Esempio n. 1
0
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;
}
Esempio n. 2
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);
}
Esempio n. 3
0
/*
 * mode formatting related 
*/ 
static char *get_mode(Namval_t* np, Namfun_t* nfp)
{
	mode_t mode = nv_getn(np,nfp);
	return(fmtperm(mode));
}