Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

correction to rmdir.c using catpath (just posted)

0 views
Skip to first unread message

forsyth

unread,
Jul 30, 1986, 1:57:12 AM7/30/86
to
Here are some changes from diffc to rmdir.c (7th edition) that use the
catpath function just posted to net.sources (8...@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;
}
}

0 new messages