correction to rmdir.c using catpath (just posted)
forsyth
forsyth at minster.UUCP
Wed Jul 30 15:57:12 AEST 1986
Here are some changes from diffc to rmdir.c (7th edition) that use the
catpath function just posted to net.sources (862 at 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;
}
}
More information about the Net.bugs.v7
mailing list