int b_mkdir(int argc, char** argv, void* context) { register char* arg; register int n; register mode_t mode = DIRMODE; register mode_t mask = 0; register int mflag = 0; register int pflag = 0; register int vflag = 0; char* name; mode_t dmode; struct stat st; cmdinit(argc, argv, context, ERROR_CATALOG, 0); for (;;) { switch (optget(argv, usage)) { case 0: break; case 'm': mflag = 1; mode = strperm(arg = opt_info.arg, &opt_info.arg, mode); if (*opt_info.arg) error(ERROR_exit(0), "%s: invalid mode", arg); continue; case 'p': pflag = 1; continue; case 'v': vflag = 1; continue; case ':': error(2, "%s", opt_info.arg); continue; case '?': error(ERROR_usage(2), "%s", opt_info.arg); continue; } break; } argv += opt_info.index; if (error_info.errors || !*argv) error(ERROR_usage(2), "%s", optusage(NiL)); mask = umask(0); if (mflag || pflag) { dmode = DIRMODE & ~mask; if (!mflag) mode = dmode; dmode |= S_IWUSR | S_IXUSR; } else { mode &= ~mask; umask(mask); mask = 0; } while (arg = *argv++) { if (mkdir(arg, mode) < 0) { if (!pflag || !(errno == ENOENT || errno == EEXIST || errno == ENOTDIR)) { error(ERROR_system(0), "%s:", arg); continue; } if (errno == EEXIST) continue; /* * -p option, preserve intermediates * first eliminate trailing /'s */ n = strlen(arg); while (n > 0 && arg[--n] == '/'); arg[n + 1] = 0; for (name = arg, n = *arg; n;) { /* skip over slashes */ while (*arg == '/') arg++; /* skip to next component */ while ((n = *arg) && n != '/') arg++; *arg = 0; if (mkdir(name, n ? dmode : mode) < 0 && errno != EEXIST && access(name, F_OK) < 0) { *arg = n; error(ERROR_system(0), "%s:", name); break; } if (vflag) error(0, "%s: directory created", name); if (!(*arg = n) && (mode & (S_ISVTX|S_ISUID|S_ISGID))) { if (stat(name, &st)) { error(ERROR_system(0), "%s: cannot stat", name); break; } if ((st.st_mode & (S_ISVTX|S_ISUID|S_ISGID)) != (mode & (S_ISVTX|S_ISUID|S_ISGID)) && chmod(name, mode)) { error(ERROR_system(0), "%s: cannot change mode from %s to %s", name, fmtperm(st.st_mode & (S_ISVTX|S_ISUID|S_ISGID)), fmtperm(mode)); break; } } } } else if (vflag) error(0, "%s: directory created", arg); } if (mask) umask(mask); return error_info.errors != 0; }
int b_umask(int argc,char *argv[],Shbltin_t *context) { register char *mask; register int flag = 0; register bool sflag=false, pflag=false; NOT_USED(context); while((argc = optget(argv,sh_optumask))) switch(argc) { case 'p': pflag = true; break; case 'S': sflag = true; break; case ':': errormsg(SH_DICT,2, "%s", opt_info.arg); break; case '?': errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg); break; } if(error_info.errors) errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0)); argv += opt_info.index; if(mask = *argv) { register int c; if(isdigit(*mask)) { while(c = *mask++) { if (c>='0' && c<='7') flag = (flag<<3) + (c-'0'); else errormsg(SH_DICT,ERROR_exit(1),e_number,*argv); } } else { char *cp = mask; flag = umask(0); c = strperm(cp,&cp,~flag&0777); if(*cp) { umask(flag); errormsg(SH_DICT,ERROR_exit(1),e_format,mask); } flag = (~c&0777); } umask(flag); } else { char *prefix = pflag?"umask ":""; umask(flag=umask(0)); if(sflag) sfprintf(sfstdout,"%s%s\n",prefix,fmtperm(~flag&0777)); else sfprintf(sfstdout,"%s%0#4o\n",prefix,flag); } return(0); }
/* * mode formatting related */ static char *get_mode(Namval_t* np, Namfun_t* nfp) { mode_t mode = nv_getn(np,nfp); return(fmtperm(mode)); }