⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mkdir.c

📁 操作系统源代码
💻 C
字号:
/* mkdir - Make directories		Author: V. Archer *//* Copyright 1991 by Vincent Archer *	You may freely redistribute this software, in source or binary *	form, provided that you do not alter this copyright mention in any *	way. */#include <sys/types.h>#include <sys/stat.h>#include <minix/minlib.h>#include <limits.h>#include <errno.h>#include <string.h>#include <stdlib.h>#include <stdio.h>extern int optind, opterr;extern char *optarg;#define USR_MODES (S_ISUID|S_IRWXU)#define GRP_MODES (S_ISGID|S_IRWXG)#define EXE_MODES (S_IXUSR|S_IXGRP|S_IXOTH)#ifdef S_ISVTX#define ALL_MODES (USR_MODES|GRP_MODES|S_IRWXO|S_ISVTX)#else#define ALL_MODES (USR_MODES|GRP_MODES|S_IRWXO)#endif#define DEFAULT_MODE (S_IRWXU|S_IRWXG|S_IRWXO)#define USER_WX (S_IWUSR|S_IXUSR)/* Global variables */int pflag;char *symbolic;mode_t u_mask;struct stat st;_PROTOTYPE(int main, (int argc, char **argv));_PROTOTYPE(mode_t parsemode, (char *symbolic, Mode_t oldmode));_PROTOTYPE(int makepath, (char *fordir));_PROTOTYPE(int makedir, (char *dirname));_PROTOTYPE(void usage, (void));/* Parse a P1003.2 4.7.7-conformant symbolic mode. */mode_t parsemode(symbolic, oldmode)char *symbolic;mode_t oldmode;{  mode_t who, mask, newmode, tmpmask;  char action;  newmode = oldmode & ALL_MODES;  while (*symbolic) {	who = 0;	for (; *symbolic; symbolic++) {		if (*symbolic == 'a') {			who |= ALL_MODES;			continue;		}		if (*symbolic == 'u') {			who |= USR_MODES;			continue;		}		if (*symbolic == 'g') {			who |= GRP_MODES;			continue;		}		if (*symbolic == 'o') {			who |= S_IRWXO;			continue;		}		break;	}	if (!*symbolic || *symbolic == ',') usage();	while (*symbolic) {		if (*symbolic == ',') break;		switch (*symbolic) {		    default:			usage();		    case '+':		    case '-':		    case '=':	action = *symbolic++;		}		mask = 0;		for (; *symbolic; symbolic++) {			if (*symbolic == 'u') {				tmpmask = newmode & S_IRWXU;				mask |= tmpmask | (tmpmask << 3) | (tmpmask << 6);				symbolic++;				break;			}			if (*symbolic == 'g') {				tmpmask = newmode & S_IRWXG;				mask |= tmpmask | (tmpmask >> 3) | (tmpmask << 3);				symbolic++;				break;			}			if (*symbolic == 'o') {				tmpmask = newmode & S_IRWXO;				mask |= tmpmask | (tmpmask >> 3) | (tmpmask >> 6);				symbolic++;				break;			}			if (*symbolic == 'r') {				mask |= S_IRUSR | S_IRGRP | S_IROTH;				continue;			}			if (*symbolic == 'w') {				mask |= S_IWUSR | S_IWGRP | S_IWOTH;				continue;			}			if (*symbolic == 'x') {				mask |= EXE_MODES;				continue;			}			if (*symbolic == 's') {				mask |= S_ISUID | S_ISGID;				continue;			}			if (*symbolic == 'X') {				if (S_ISDIR(oldmode) || (oldmode & EXE_MODES))					mask |= EXE_MODES;				continue;			}#ifdef S_ISVTX			if (*symbolic == 't') {				mask |= S_ISVTX;				who |= S_ISVTX;				continue;			}#endif			break;		}		switch (action) {		    case '=':			if (who)				newmode &= ~who;			else				newmode = 0;		    case '+':			if (who)				newmode |= who & mask;			else				newmode |= mask & (~u_mask);			break;		    case '-':			if (who)				newmode &= ~(who & mask);			else				newmode &= ~mask | u_mask;		}	}	if (*symbolic) symbolic++;  }  return(newmode);}/* Main module. */int main(argc, argv)int argc;char **argv;{  int error, c;  opterr = 0;  pflag = 0;  symbolic = (char *) 0;  u_mask = umask(0);  umask(u_mask);  while ((c = getopt(argc, argv, "m:p")) != EOF) switch (c) {	    case 'm':	symbolic = optarg;	break;	    case 'p':	pflag = 1;	break;	    default:	usage();	}  if (optind >= argc) usage();  error = 0;  while (optind < argc) error |= makedir(argv[optind++]);  return(error);}/* P1003.2 requires that missing intermediate pathname components should be *	created if the -p option is specified (4.40.3). */int makepath(fordir)char *fordir;{  char parent[PATH_MAX + 1], *end;  strcpy(parent, fordir);  if (!(end = strrchr(parent, '/'))) return(0);  *end = '\0';  if (!parent[0]) return(0);  if (!stat(parent, &st)) {	if (S_ISDIR(st.st_mode)) return(0);	errno = ENOTDIR;	perror(parent);	return(1);  }  if (mkdir(parent, DEFAULT_MODE)) {	if (makepath(parent)) return(1);	if (mkdir(parent, DEFAULT_MODE)) {		perror(parent);		return(1);	}  }/* P1003.2 states that, regardless of umask() value, intermediate paths *	should have at least write and search (x) permissions (4.40.10). */  if ((u_mask & USER_WX) &&      chmod(parent, ((~u_mask) | USER_WX)) & DEFAULT_MODE) {	perror(parent);	return(1);  }  return(0);}/* Actual directory creation, using a mkdir() system call. */int makedir(dirname)char *dirname;{  if (mkdir(dirname, DEFAULT_MODE)) {	if (!pflag) {		perror(dirname);		return(1);	}	if (!stat(dirname, &st)) {		if (S_ISDIR(st.st_mode)) return(0);		errno = ENOTDIR;		perror(dirname);		return(1);	}	if (makepath(dirname)) return(1);	if (mkdir(dirname, DEFAULT_MODE)) {		perror(dirname);		return(1);	}  }  if (symbolic && (stat(dirname, &st) ||		 chmod(dirname, parsemode(symbolic, st.st_mode)))) {	perror(dirname);	return(1);  }  return(0);}/* Posix command prototype. */void usage(){  std_err("Usage: mkdir [-p] [-m mode] dir...\n");  exit(1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -