📄 sh.c
字号:
*/chredir(argc, argv)int argc;char *argv[];{ int c, rmarg, a; chfiles = 0; for(c = 0; c < argc; c++){ rmarg = 0; switch(argv[c][0]){ case '<': if((fin = open(argv[c + 1], 0)) == -1){ printk("Unable to open input file %s\n",argv[c]); fin = 0; return -1; } else{ dup2(fin, 0); close(fin); rmarg = 1; chfiles++; } break; case '>': if(argv[c][1] == '&'){ if((ferr = creat(argv[c + 1], 0666)) == -1){ printk("Unable to create output file %s\n",argv[c]); ferr = 2; return -1; } else{ dup2(ferr, 2); close(ferr); rmarg = 1; chfiles++; } } else{ if((fout = creat(argv[c + 1], 0666)) == -1){ printk("Unable to create output file %s\n",argv[c]); fout = 1; } else{ dup2(fout, 1); close(fout); rmarg = 1; chfiles++; } break; } default: break; } /* If required remove args from argument list */ if(rmarg){ /* Set c to first arg to be removed and shift up * Args above to take its place */ for(a = c; 1; a++){ argv[a] = argv[a + 2]; if(!argv[a]) break; } argc -= 2; c--; } } return argc;}/* * Retenv() Returns enviroment string whose name is given. */retenv(env, name, str)char *env[];char *name, *str;{ int c; for(c = 0; c < (NENVS -1); c++){ if(env[c] && !strncmp(env[c], name, strlen(name))){ name = env[c]; while(*name++ != '='); strcpy(str, name); } } return 0;}shexit(n)int n;{ sync();#if defined(STANDALONE)#else /* Calls machine shut for things like floppy off etc */ mach_shut();#endif exit(n);}/* * Cd - built-in change-directory command. */cd(argc, argv)char *argv[];{ if (argc == 1) argv[1] = "/"; else if (argc != 2){ printk("cd: too many args\n"); return -1; } if (chdir(argv[1])) printk("cd: invalid directory\n"); return 0;}/* * Setid() Sets userid and gid of shell */setid(argc,argv)char *argv[];int argc;{ if(argc != 3){ printk("Usage: setid <uid> <gid>\n"); return -1; } if(setgid(atoi(argv[2])) == -1) return -1; if(setuid(atoi(argv[1])) == -1) return -1; return 0;}/* * Set enviroment varibles */setenv(argc, argv, env)int argc;char *argv[], *env[];{ int c; /* Check arguments */ if(argc != 3){ printk("usage: set <Varible> <setting>\n"); return -1; } /* Check if room for this entry */ if((strlen(argv[1]) + strlen(argv[2]) + 2) >= ENVLEN){ printk("Enviroment varible to long\n"); return -1; } for(c = 0; c < (NENVS -1); c++){ if(env[c] == 0){ env[c] = shenv[c]; env[c+1] = 0; strcpy(env[c], argv[1]); strcat(env[c], "="); strcat(env[c], argv[2]); return 0; } else { if(!strncmp(env[c], argv[1], strlen(argv[1]))){ strcpy(env[c], argv[1]); strcat(env[c], "="); strcat(env[c], argv[2]); return 0; } } } printk("To many enviroment strings\n"); return -1;}/* * Echo() Echos is arguments to tty */echo(argc, argv)int argc;char *argv[];{ int c; for(c = 1; c < argc; c++) printk("%s ",argv[c]); printk("\n"); return 0;}#if defined(STANDALONE)#else/* * Kstate() Sets the state of the kernal */kstate(argc, argv)int argc;char *argv[];{ int c; if(argc == 1){ printk("Usage: kstate <0, 1> (warnings off, on)\n"); return 1; } state.warning = atoi(argv[1]); return 0;}#endif/****************************************************************************** * Routines special to internal shell ****************************************************************************** *//****************************************************************************** * Shexec() Shell execute new process and wait till finished * returns -1 if not found, or exit status if found. ****************************************************************************** */# define XEQ 75 /* Program execute syscall no */shexec(name, argv, env, eflag)char *name;char *argv[], *env[];int eflag;{ int pid, cpid, error;#if defined(MSDOS) /* Execute new process and get pid */ if ((error = spawnve(P_WAIT, name, argv, env)) == -1) return NOTFOUND; else return error;#else /* Execute new process and get pid */ if ((cpid = syscall(XEQ, name, argv, env)) != -1){ /* If process is in background continue */ if(eflag & EBACKGRD) return 0; /* Else check for all child processes until this one dies * This will also collect any system zombies etc */ do{ pid = wait(&error); } while((pid != cpid) && (pid != -1)); return error; } else return NOTFOUND;#endif}#ifdef WILDCARDS/* * Clearargs() Clears the arguments in the arg structure given. */clearargs(args)struct Args *args;{ args->nargs = 0; args->argp[0] = 0; args->endarg = args->area; return 0;}/* * Addarg() Adds an argument to the given structure * Returns 1 if possible 0 if not. */addarg(str, args)char *str;struct Args *args;{ /* Checks if there is room for arguments */ if(args->nargs >= MAXNARGS) return 0; if((args->endarg + strlen(str) + 1) >= &args->area[MAXAAREA]) return 0; /* Adds new arg to the area */ strcpy(args->endarg, str); args->argp[args->nargs++] = args->endarg; args->argp[args->nargs] = 0; args->endarg += (strlen(str) + 1); return 1;}/* * Wiswild() Checks if the given string has wild chars in it */wiswild(name)char *name;{ while(*name) if((*name == '*') || (*name++ == '?')) return 1; return 0;}/* * Wildexp() Expands the given name using the given directory * Puting all arguments found into the args array. * Returns number of args found, -1 if error. */#if defined(MSDOS)wildexp(name, dirname, args)char *name, *dirname;struct Args *args;{ struct direct *dir; DIR *dirp; char nextdir[MAXPATH]; char *nextname, *arg; int df, ar, ars; /* If no directory name given and not full path name then set * to current dir "." */ if(!(*dirname)){ if(*name == '/') dirname = "/"; else dirname = "."; } /* Check if directory accesable */ if((dirp = opendir(dirname)) == 0) return 0; ar = 0; /* Get rid of any leading slashes's */ while(*name == '/') name++; /* Find out if further sub dirs need to be searched */ nextname = name; while(*nextname && (*nextname != '/')) nextname++; if(*nextname){ /* If so set name to point to required dir * Set nextname to point to name of file or further sub-dirs. */ *nextname++ = 0; } /* Read each directory entry and check for match ignore .'s */ while(dir = readdir(dirp)){ if(dir->d_ino && strcmp(dir->d_name, ".") && strcmp(dir->d_name, "..")){ if(wildstr(name, dir->d_name)){ if((strlen(nextdir) + strlen(dir->d_name) + 2) > MAXPATH) return -1; strcpy(nextdir, dirname); if(nextdir[0] && (nextdir[strlen(nextdir) - 1] != '/')) strcat(nextdir,"/"); strcat(nextdir,dir->d_name); if(!(*nextname)){ /* Remove unecessary first bits */ arg = nextdir; if((*arg == '.') && (*(arg+1) != '.')){ arg += 2; if(*arg == '/') arg++; } if(!addarg(arg, args)) return -1; ar++; } else{ if(wisdir(nextdir)){ if((ars = wildexp(nextname, nextdir, args)) == -1) return -1; ar += ars; } } } } } /* Recover origanal name */ if(*nextname--) *nextname = '/'; closedir(dirp); return ar;}#elsewildexp(name, dirname, args)char *name, *dirname;struct Args *args;{ struct direct dir; char nextdir[MAXPATH]; char *nextname, *arg; int df, ar, ars; /* If no directory name given and not full path name then set * to current dir "." */ if(!(*dirname)){ if(*name == '/') dirname = "/"; else dirname = "."; } /* Check if directory accesable */ if((df = open(dirname, 0)) == -1) return 0; ar = 0; /* Get rid of any leading slashes's */ while(*name == '/') name++; /* Find out if further sub dirs need to be searched */ nextname = name; while(*nextname && (*nextname != '/')) nextname++; if(*nextname){ /* If so set name to point to required dir * Set nextname to point to name of file or further sub-dirs. */ *nextname++ = 0; } /* Read each directory entry and check for match ignore .'s */ while(read(df, &dir, sizeof(struct direct))){ if(dir.d_ino && strcmp(dir.d_name, ".") && strcmp(dir.d_name, "..")){ if(wildstr(name, dir.d_name)){ if((strlen(nextdir) + strlen(dir.d_name) + 2) > MAXPATH) return -1; strcpy(nextdir, dirname); if(nextdir[0] && (nextdir[strlen(nextdir) - 1] != '/')) strcat(nextdir,"/"); strcat(nextdir,dir.d_name); if(!(*nextname)){ /* Remove unecessary first bits */ arg = nextdir; if((*arg == '.') && (*(arg+1) != '.')) arg += 2; if(*arg == '/') arg++; if(!addarg(arg, args)) return -1; ar++; } else{ if(wisdir(nextdir)){ if((ars = wildexp(nextname, nextdir, args)) == -1) return -1; ar += ars; } } } } } /* Recover origanal name */ if(*nextname--) *nextname = '/'; close(df); return ar;}#endif/* * Wisdir() Returns S_IFDIR if the file given is a directory */wisdir(name)char *name;{ struct stat status; stat(name, &status); return (status.st_mode & S_IFDIR);}/* * Wildstr() Checks to see if the wild-carded string is equal * to the given string. Returns 1 is equal. */wildstr(estr, name)char *estr, *name;{ while(*estr){ if(*estr == '*'){ estr++; if(!(*estr)) return 1; while(*name && (*name != *estr)) name++; if(!(*name)) return 0; } if(*estr != '?'){ if(*name != *estr) return 0; } estr++; name++; } if(*name || *estr) return 0; else return 1;}#endif WILDCARDS#if defined(STANDALONE)pmem(){ printk("No pmem in standalone\n"); return (1);}smem(){ printk("No smem in standalone\n"); return (1);}kstate(){ printk("No kstatein standalone\n"); return (1);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -