static int bin_mkdir(char *nam, char **args, Options ops, UNUSED(int func)) { mode_t oumask = umask(0); mode_t mode = 0777 & ~oumask; int err = 0; umask(oumask); if(OPT_ISSET(ops,'m')) { char *str = OPT_ARG(ops,'m'), *ptr; mode = zstrtol(str, &ptr, 8); if(!*str || *ptr) { zwarnnam(nam, "invalid mode `%s'", str); return 1; } } for(; *args; args++) { char *ptr = strchr(*args, 0); while(ptr > *args + (**args == '/') && *--ptr == '/') *ptr = 0; if(OPT_ISSET(ops,'p')) { char *ptr = *args; for(;;) { while(*ptr == '/') ptr++; while(*ptr && *ptr != '/') ptr++; if(!*ptr) { err |= domkdir(nam, *args, mode, 1); break; } else { int e; *ptr = 0; e = domkdir(nam, *args, mode | 0300, 1); if(e) { err = 1; break; } *ptr = '/'; } } } else err |= domkdir(nam, *args, mode, 0); } return err; }
int mkpath(char *path) { char *slash; int done = 0; slash = path; while (!done) { slash += strspn(slash, "/"); slash += strcspn(slash, "/"); done = (*slash == '\0'); *slash = '\0'; if (domkdir(path, 0777) == -1) goto out; if (!done) *slash = '/'; } return 0; out: /* Can't create or or not a directory */ syswarn(1, errno, "Cannot create directory `%s'", path); return -1; }
int main(int argc,char *argv[]) { int i; int p=0,v=0; int mode=0777-umask(0); mode_t and,or; if (argc<2) usage(); for (i=1; i<argc; i++) { if (!argv[i]) continue; if (argv[i][0]=='-') { int j,len=strlen(argv[i]); for (j=1; j<len; j++) { switch (argv[i][j]) { case '-': if (!strcmp(argv[i],"--parent")) p=1; else if (!strcmp(argv[i],"--verbose")) v=1; else if (argv[i][2]) usage(); j=len; break; case 'p': p=1; break; case 'v': v=1; break; case 'm': parsemode(argv[i+1],&and,&or); mode=(mode&and)|or; argv[i+1]=0; break; default: usage(); } } } else { if (p) { minusp(argv[i],mode,v); } else domkdir(argv[i],mode,v,0,argv[i]); } } return res; }
static void setdir(void) { #if 0 /* let's not require subdirs */ domkdir(PATH_TESTDIR, 0775); dochdir(PATH_TESTDIR); #endif /* 0 */ }
void minusp(char *s,int m,int v) { int fd=open(".",O_RDONLY); char *t; char *full=s; if (fd<0) { panic(); return; } if (*s=='/') { chdir("/"); ++s; } while ((t=strchr(s,'/'))) { *t=0; domkdir(s,m,v,1,full); chdir(s); s=t+1; *t='/'; } if (*s) domkdir(s,m,v,1,full); fchdir(fd); close(fd); }
static void mkdir_proc(void) { char name[NAMESIZE]; int ct; for (ct=0; ct<NTRIES; ct++) { choose_name(name, sizeof(name)); say("pid %2d: mkdir %s\n", (int)getpid(), name); domkdir(name); } }
int chk_path(char *name, uid_t st_uid, gid_t st_gid) { char *spt = name; struct stat sb; int retval = -1; /* * watch out for paths with nodes stored directly in / (e.g. /bozo) */ if (*spt == '/') ++spt; for(;;) { /* * work forward from the first / and check each part of * the path */ spt = strchr(spt, '/'); if (spt == NULL) break; *spt = '\0'; /* * if it exists we assume it is a directory, it is not within * the spec (at least it seems to read that way) to alter the * file system for nodes NOT EXPLICITLY stored on the archive. * If that assumption is changed, you would test the node here * and figure out how to get rid of it (probably like some * recursive unlink()) or fix up the directory permissions if * required (do an access()). */ if (lstat(name, &sb) == 0) { *(spt++) = '/'; continue; } /* * the path fails at this point, see if we can create the * needed directory and continue on */ if (domkdir(name, S_IRWXU | S_IRWXG | S_IRWXO) == -1) { *spt = '/'; retval = -1; break; } /* * we were able to create the directory. We will tell the * caller that we found something to fix, and it is ok to try * and create the node again. */ retval = 0; if (pids) (void)set_ids(name, st_uid, st_gid); /* * make sure the user doesn't have some strange umask that * causes this newly created directory to be unusable. We fix * the modes and restore them back to the creation default at * the end of pax */ if ((access(name, R_OK | W_OK | X_OK) < 0) && (lstat(name, &sb) == 0)) { set_pmode(name, ((sb.st_mode & FILEBITS(0)) | S_IRWXU)); add_dir(name, spt - name, &sb, 1); } *(spt++) = '/'; continue; } /* * We perform one final check here, because if someone else * created the directory in parallel with us, we might return * the wrong error code, even if the directory exists now. */ if (retval == -1 && stat(name, &sb) == 0 && S_ISDIR(sb.st_mode)) retval = 0; return retval; }
int node_creat(ARCHD *arcn) { int res; int ign = 0; int oerrno; int pass = 0; mode_t file_mode; struct stat sb; char target[MAXPATHLEN]; char *nm = arcn->name; int len; /* * create node based on type, if that fails try to unlink the node and * try again. finally check the path and try again. As noted in the * file and link creation routines, this method seems to exhibit the * best performance in general use workloads. */ file_mode = arcn->sb.st_mode & FILEBITS(arcn->type == PAX_DIR); for (;;) { switch (arcn->type) { case PAX_DIR: /* * If -h (or -L) was given in tar-mode, follow the * potential symlink chain before trying to create the * directory. */ if (strcmp(NM_TAR, argv0) == 0 && Lflag) { while (lstat(nm, &sb) == 0 && S_ISLNK(sb.st_mode)) { len = readlink(nm, target, sizeof target - 1); if (len == -1) { syswarn(0, errno, "cannot follow symlink %s " "in chain for %s", nm, arcn->name); res = -1; goto badlink; } target[len] = '\0'; nm = target; } } res = domkdir(nm, file_mode); badlink: if (ign) res = 0; break; case PAX_CHR: file_mode |= S_IFCHR; res = mknod(nm, file_mode, arcn->sb.st_rdev); break; case PAX_BLK: file_mode |= S_IFBLK; res = mknod(nm, file_mode, arcn->sb.st_rdev); break; case PAX_FIF: res = mkfifo(nm, file_mode); break; case PAX_SCK: /* * Skip sockets, operation has no meaning under BSD */ tty_warn(0, "%s skipped. Sockets cannot be copied or extracted", nm); return (-1); case PAX_SLK: res = symlink(arcn->ln_name, nm); break; case PAX_CTG: case PAX_HLK: case PAX_HRG: case PAX_REG: default: /* * we should never get here */ tty_warn(0, "%s has an unknown file type, skipping", nm); return (-1); } /* * if we were able to create the node break out of the loop, * otherwise try to unlink the node and try again. if that * fails check the full path and try a final time. */ if (res == 0) break; /* * we failed to make the node */ oerrno = errno; switch (pass++) { case 0: if ((ign = unlnk_exist(nm, arcn->type)) < 0) return (-1); continue; case 1: if (nodirs || chk_path(nm, arcn->sb.st_uid, arcn->sb.st_gid) < 0) { syswarn(1, oerrno, "Cannot create %s", nm); return (-1); } continue; } /* * it must be a file that exists but we can't create or * remove, but we must avoid the infinite loop. */ break; } /* * we were able to create the node. set uid/gid, modes and times */ if (pids) res = set_ids(nm, arcn->sb.st_uid, arcn->sb.st_gid); else res = 0; /* * IMPORTANT SECURITY NOTE: * if not preserving mode or we cannot set uid/gid, then PROHIBIT any * set uid/gid bits */ if (!pmode || res) arcn->sb.st_mode &= ~SETBITS(arcn->type == PAX_DIR); if (pmode) set_pmode(arcn->name, arcn->sb.st_mode); if (arcn->type == PAX_DIR && strcmp(NM_CPIO, argv0) != 0) { /* * Dirs must be processed again at end of extract to set times * and modes to agree with those stored in the archive. However * to allow extract to continue, we may have to also set owner * rights. This allows nodes in the archive that are children * of this directory to be extracted without failure. Both time * and modes will be fixed after the entire archive is read and * before pax exits. */ if (access(nm, R_OK | W_OK | X_OK) < 0) { if (lstat(nm, &sb) < 0) { syswarn(0, errno,"Cannot access %s (stat)", arcn->name); set_pmode(nm,file_mode | S_IRWXU); } else { /* * We have to add rights to the dir, so we make * sure to restore the mode. The mode must be * restored AS CREATED and not as stored if * pmode is not set. */ set_pmode(nm, ((sb.st_mode & FILEBITS(arcn->type == PAX_DIR)) | S_IRWXU)); if (!pmode) arcn->sb.st_mode = sb.st_mode; } /* * we have to force the mode to what was set here, * since we changed it from the default as created. */ add_dir(nm, arcn->nlen, &(arcn->sb), 1); } else if (pmode || patime || pmtime) add_dir(nm, arcn->nlen, &(arcn->sb), 0); } if (patime || pmtime) set_ftime(arcn->name, arcn->sb.st_mtime, arcn->sb.st_atime, 0, (arcn->type == PAX_SLK) ? 1 : 0); #if HAVE_STRUCT_STAT_ST_FLAGS if (pfflags && arcn->type != PAX_SLK) set_chflags(arcn->name, arcn->sb.st_flags); #endif return 0; }
/*this is the main routine*/ void doshell() { char line[80]; /*run forever - the shell shouldn't end*/ while(1==1) { /*read in a line*/ printstring("SHELL>\0"); readstring(line); /*match it against each possible command*/ /*if the user presses return, ignore it*/ if (line[0]==0xd) continue; else if (iscommand(line,"CLS\0")==1) doclear(); else if (iscommand(line,"cls\0")==1) doclear(); else if (iscommand(line,"COPY\0")==1) docopy(); else if (iscommand(line,"copy\0")==1) docopy(); else if (iscommand(line,"CREATE \0")==1) docreate(line); else if (iscommand(line,"create \0")==1) docreate(line); else if (iscommand(line,"DELETE \0")==1) dodelete(line); else if (iscommand(line,"delete \0")==1) dodelete(line); else if (iscommand(line,"DIR\0")==1) dodir(); else if (iscommand(line,"dir\0")==1) dodir(); else if (iscommand(line,"EXEC \0")==1) doexecute(line,1); else if (iscommand(line,"exec \0")==1) doexecute(line,1); else if (iscommand(line,"EXECBACK \0")==1) doexecute(line,0); else if (iscommand(line,"execback \0")==1) doexecute(line,0); else if (iscommand(line,"HELP\0")==1) dohelp(); else if (iscommand(line,"help\0")==1) dohelp(); else if (line[0]=='?') dohelp(); else if (iscommand(line,"TYPE \0")==1) dotype(line); else if (iscommand(line,"type \0")==1) dotype(line); else if (iscommand(line,"KILL \0")==1) dokill(line); else if (iscommand(line,"kill \0")==1) dokill(line); else if (iscommand(line,"mkdir \0")==1) domkdir(line); else if (iscommand(line,"MKDIR\0")==1) domkdir(line); else if (iscommand(line,"FORMAT\0")==1) doFormat(); else if (iscommand(line,"format\0")==1) doFormat(); else if (iscommand(line,"remove\0")==1) doRemove(line); else if (iscommand(line,"REMOVE\0")==1) doRemove(line); else if (iscommand(line,"list\0")==1) doList(); else if (iscommand(line,"LIST\0")==1) doList(); else if (iscommand(line,"count\0")==1) doCount(line); else if (iscommand(line,"WRITE\0")==1) doCreateFile(line); else if (iscommand(line,"write\0")==1) doCreateFile(line); else if (iscommand(line,"READ\0")==1) doEcho(line); else if (iscommand(line,"read\0")==1) doEcho(line); else printstring("Command not found\r\n\0"); printstring("\r\n\0"); } }