Thread View: net.bugs.v7
1 messages
1 total messages
Started by forsyth
Wed, 30 Jul 1986 05:57
correction to rmdir.c using catpath (just posted)
Author: forsyth
Date: Wed, 30 Jul 1986 05:57
Date: Wed, 30 Jul 1986 05:57
332 lines
8182 bytes
8182 bytes
Here are some changes from diffc to rmdir.c (7th edition) that use the
catpath function just posted to net.sources (862@minster.UUCP) to correct the
recently observed bug in rmdir. (I also changed the Usage message,
and stopped the code from using "" as a file name.)
Similar changes should apply to system V, but beware of the code
in that version, in rmdir(), near the call to `strrchr'.
It was changed from
if((np = rindex(name, '/')) == NULL)
np = name;
else
np++;
to
if((np = strrchr(name, '/')) == NULL)
np = name;
but unfortunately this breaks the protection (weak as it was) against
doing
(mkdir b; rmdir b/.)
It might be best to put the np++ back in. In any case, there is still
a problem that `rmdir /' results in `/ unreadable' on systems that
refuse access to "" as a file name. Given the proposed target and the
nature of the request, perhaps this is just as well.
*** o_rmdir.c Wed Jul 23 13:49:31 1986
--- rmdir.c Wed Jul 23 14:04:32 1986
***************
*** 11,16
char *rindex();
char *strcat();
char *strcpy();
main(argc,argv)
int argc;
--- 11,17 -----
char *rindex();
char *strcat();
char *strcpy();
+ char *catpath();
main(argc,argv)
int argc;
***************
*** 18,24
{
if(argc < 2) {
! fprintf(stderr, "rmdir: arg count\n");
exit(1);
}
while(--argc)
--- 19,25 -----
{
if(argc < 2) {
! fprintf(stderr, "Usage: rmdir dirname ...\n");
exit(1);
}
while(--argc)
***************
*** 30,36
char *d;
{
int fd;
! char *np, name[500];
struct stat st, cst;
struct direct dir;
--- 31,37 -----
char *d;
{
int fd;
! char *np, name[500], *comp[2];
struct stat st, cst;
struct direct dir;
***************
*** 34,40
struct stat st, cst;
struct direct dir;
! strcpy(name, d);
for (np = name+strlen(name); np != name && *--np == '/';)
*np = 0;
if((np = rindex(name, '/')) == NULL)
--- 35,52 -----
struct stat st, cst;
struct direct dir;
! if(stat(d,&st) < 0) {
! fprintf(stderr, "rmdir: %s non-existent\n", d);
! ++Errors;
! return;
! }
! comp[0] = d;
! comp[1] = NULL;
! if (catpath(name, sizeof name, comp) == NULL) {
! fprintf(stderr, "rmdir: the name %s is too long\n", d);
! ++Errors;
! return;
! }
for (np = name+strlen(name); np != name && *--np == '/';)
*np = 0;
if((np = rindex(name, '/')) == NULL)
***************
*** 41,48
np = name;
else
np++;
! if(stat(name,&st) < 0) {
! fprintf(stderr, "rmdir: %s non-existent\n", name);
++Errors;
return;
}
--- 53,60 -----
np = name;
else
np++;
! if (stat(".", &cst) < 0) {
! fprintf(stderr, "rmdir: cannot stat \".\"");
++Errors;
return;
}
***************
*** 46,56
++Errors;
return;
}
- if (stat("", &cst) < 0) {
- fprintf(stderr, "rmdir: cannot stat \"\"");
- ++Errors;
- exit(1);
- }
if((st.st_mode & S_IFMT) != S_IFDIR) {
fprintf(stderr, "rmdir: %s not a directory\n", name);
++Errors;
--- 58,63 -----
++Errors;
return;
}
if((st.st_mode & S_IFMT) != S_IFDIR) {
fprintf(stderr, "rmdir: %s not a directory\n", name);
return(1);
***************
*** 53,60
}
if((st.st_mode & S_IFMT) != S_IFDIR) {
fprintf(stderr, "rmdir: %s not a directory\n", name);
! ++Errors;
! return;
}
if(st.st_ino==cst.st_ino &&st.st_dev==cst.st_dev) {
fprintf(stderr, "rmdir: cannot remove current directory\n");
--- 60,66 -----
}
if((st.st_mode & S_IFMT) != S_IFDIR) {
fprintf(stderr, "rmdir: %s not a directory\n", name);
! return(1);
}
if(st.st_ino==cst.st_ino &&st.st_dev==cst.st_dev) {
fprintf(stderr, "rmdir: cannot remove current directory\n");
***************
*** 58,63
}
if(st.st_ino==cst.st_ino &&st.st_dev==cst.st_dev) {
fprintf(stderr, "rmdir: cannot remove current directory\n");
++Errors;
return;
}
--- 64,73 -----
}
if(st.st_ino==cst.st_ino &&st.st_dev==cst.st_dev) {
fprintf(stderr, "rmdir: cannot remove current directory\n");
+ return(1);
+ }
+ if(!strcmp(np, ".") || !strcmp(np, "..")) {
+ fprintf(stderr, "rmdir: cannot remove . or ..\n");
++Errors;
return;
}
***************
*** 62,68
return;
}
if((fd = open(name,0)) < 0) {
! fprintf(stderr, "rmdir: %s unreadable\n", name);
++Errors;
return;
}
--- 72,78 -----
return;
}
if((fd = open(name,0)) < 0) {
! fprintf(stderr, "rmdir: %s unreadable\n", d);
++Errors;
return;
}
***************
*** 66,80
++Errors;
return;
}
! while(read(fd, (char *)&dir, sizeof dir) == sizeof dir) {
! if(dir.d_ino == 0) continue;
! if(!strcmp(dir.d_name, ".") || !strcmp(dir.d_name, ".."))
! continue;
! fprintf(stderr, "rmdir: %s not empty\n", name);
! ++Errors;
! close(fd);
! return;
! }
close(fd);
if(!strcmp(np, ".") || !strcmp(np, "..")) {
fprintf(stderr, "rmdir: cannot remove . or ..\n");
--- 76,90 -----
++Errors;
return;
}
! while(read(fd, (char *)&dir, sizeof dir) == sizeof dir)
! if (dir.d_ino != 0 &&
! strcmp(dir.d_name, ".") != 0 &&
! strcmp(dir.d_name, "..") != 0) {
! fprintf(stderr, "rmdir: %s not empty\n", d);
! ++Errors;
! close(fd);
! return;
! }
close(fd);
strcat(name, "/.");
if(access(name, 0) < 0) { /* name/. non-existent */
***************
*** 76,86
return;
}
close(fd);
- if(!strcmp(np, ".") || !strcmp(np, "..")) {
- fprintf(stderr, "rmdir: cannot remove . or ..\n");
- ++Errors;
- return;
- }
strcat(name, "/.");
if((access(name, 0)) < 0) { /* name/. non-existent */
strcat(name, ".");
--- 86,91 -----
return;
}
close(fd);
strcat(name, "/.");
if(access(name, 0) < 0) { /* name/. non-existent */
strcat(name, ".");
***************
*** 82,88
return;
}
strcat(name, "/.");
! if((access(name, 0)) < 0) { /* name/. non-existent */
strcat(name, ".");
goto unl;
}
--- 87,93 -----
}
close(fd);
strcat(name, "/.");
! if(access(name, 0) < 0) { /* name/. non-existent */
strcat(name, ".");
goto unl;
}
***************
*** 87,93
goto unl;
}
strcat(name, ".");
! if((access(name, 0)) < 0) /* name/.. non-existent */
goto unl2;
if(access(name, 02)) {
name[strlen(name)-3] = '\0';
--- 92,98 -----
goto unl;
}
strcat(name, ".");
! if(access(name, 0) < 0) /* name/.. non-existent */
goto unl2;
if(access(name, 02)) {
fprintf(stderr, "rmdir: %s: no permission\n", d);
***************
*** 90,97
if((access(name, 0)) < 0) /* name/.. non-existent */
goto unl2;
if(access(name, 02)) {
! name[strlen(name)-3] = '\0';
! fprintf(stderr, "rmdir: %s: no permission\n", name);
++Errors;
return;
}
--- 95,101 -----
if(access(name, 0) < 0) /* name/.. non-existent */
goto unl2;
if(access(name, 02)) {
! fprintf(stderr, "rmdir: %s: no permission\n", d);
++Errors;
return;
}
***************
*** 102,108
unlink(name); /* unlink name/. */
name[strlen(name)-2] = '\0';
if (unlink(name) < 0) {
! fprintf(stderr, "rmdir: %s not removed\n", name);
++Errors;
}
}
--- 106,112 -----
unlink(name); /* unlink name/. */
name[strlen(name)-2] = '\0';
if (unlink(name) < 0) {
! fprintf(stderr, "rmdir: %s not removed\n", d);
++Errors;
}
}
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads