📄 find.c
字号:
*/int isnumber(str, base, sign)register char *str;int base;int sign;{ if (sign && ((*str == '-') || ((base == 8) && (*str == '+')))) str++; while ((*str >= '0') && (*str < ('0' + base))) str++; return(*str == '\0' ? 1 : 0);}/* Convert a string to an integer, storing sign info in *ps. */void number(str, base, pl, ps)char *str;int base;long *pl;int *ps;{ int up = '0' + base - 1; long val = 0; *ps = ((*str == '-' || *str == '+') ? ((*str++ == '-') ? -1 : 1) : 0); while (*str >= '0' && *str <= up) val = base * val + *str++ - '0'; if (*str) fatal("syntax error: illegal numeric value", ""); *pl = val;}void domode(op, mode, bits)int op;int *mode;int bits;{ switch (op) { case '-': *mode &= ~bits; break; /* clear bits */ case '=': *mode |= bits; break; /* set bits */ case '+': *mode |= (bits & ~um); /* set, but take umask in account */ }}void fmode(str, pl, ps)char *str;long *pl;int *ps;{ int m = 0, w, op; char *p = str; if (*p == '-') { *ps = -1; p++; } else *ps = 0; while (*p) { w = 0; if (ISOPER(*p)) w = MUSER | MGROUP | MOTHERS; else if (!ISWHO(*p)) fatal("u, g, o, or a expected: ", p); else { while (ISWHO(*p)) { switch (*p) { case 'u': w |= MUSER; break; case 'g': w |= MGROUP; break; case 'o': w |= MOTHERS; break; case 'a': w = MUSER | MGROUP | MOTHERS; } p++; } if (!ISOPER(*p)) fatal("-, + or = expected: ", p); } op = *p++; while (ISMODE(*p)) { switch (*p) { case 'r': if (w & MUSER) domode(op, &m, S_IRUSR); if (w & MGROUP) domode(op, &m, S_IRGRP); if (w & MOTHERS) domode(op, &m, S_IROTH); break; case 'w': if (w & MUSER) domode(op, &m, S_IWUSR); if (w & MGROUP) domode(op, &m, S_IWGRP); if (w & MOTHERS) domode(op, &m, S_IWOTH); break; case 'x': if (w & MUSER) domode(op, &m, S_IXUSR); if (w & MGROUP) domode(op, &m, S_IXGRP); if (w & MOTHERS) domode(op, &m, S_IXOTH); break; case 's': if (w & MUSER) domode(op, &m, S_ISUID); if (w & MGROUP) domode(op, &m, S_ISGID); break; case 't': domode(op, &m, S_ISVTX); } p++; } if (*p) { if (*p == ',') p++; else fatal("garbage at end of mode string: ", p); } } *pl = m;}struct node * expr(t)int t;{ struct node *nd, *p, *nd2; nd = primary(t); if ((t = lex(*++ipp)) == OP_OR) { nd2 = expr(lex(*++ipp)); p = newnode(OP_OR); p->n_info.n_opnd.n_left = nd; p->n_info.n_opnd.n_right = nd2; return p; } ipp--; return nd;}struct node * primary(t)int t;{ struct node *nd, *p, *nd2; nd = secondary(t); if ((t = lex(*++ipp)) != OP_AND) { ipp--; if (t == EOI || t == RPAR || t == OP_OR) return nd; } nd2 = primary(lex(*++ipp)); p = newnode(OP_AND); p->n_info.n_opnd.n_left = nd; p->n_info.n_opnd.n_right = nd2; return p;}struct node * secondary(t)int t;{ struct node *n, *p; if (t == LPAR) { n = expr(lex(*++ipp)); if (lex(*++ipp) != RPAR) fatal("syntax error, ) expected", ""); return n; } if (t == NOT) { n = secondary(lex(*++ipp)); p = newnode(NOT); p->n_info.n_opnd.n_left = n; return p; } return simple(t);}void checkarg(arg)char *arg;{ if (arg == 0) fatal("syntax error, argument expected", "");}struct node * simple(t)int t;{ struct node *p = newnode(t); struct exec *e; struct stat est; struct passwd *pw; struct group *gr; long l; int i; switch (t) { case OP_TYPE: checkarg(*++ipp); switch (**ipp) { case 'b': p->n_info.n_int.n_val = S_IFBLK; break; case 'c': p->n_info.n_int.n_val = S_IFCHR; break; case 'd': p->n_info.n_int.n_val = S_IFDIR; break; case 'f': p->n_info.n_int.n_val = S_IFREG; break; case 'l':#ifdef S_IFLNK p->n_info.n_int.n_val = S_IFLNK;#else p->n_info.n_int.n_val = ~0; /* Always unequal. */#endif break; default: fatal("-type needs b, c, d, f or l", ""); } break; case OP_USER: checkarg(*++ipp); if (((pw = getpwnam(*ipp)) == NULL) && isnumber(*ipp, 10, 0)) number(*ipp, 10, &(p->n_info.n_int.n_val), &(p->n_info.n_int.n_sign)); else { if (pw == NULL) fatal("unknown user: ", *ipp); p->n_info.n_int.n_val = pw->pw_uid; p->n_info.n_int.n_sign = 0; } break; case OP_GROUP: checkarg(*++ipp); if (((gr = getgrnam(*ipp)) == NULL) && isnumber(*ipp, 10, 0)) number(*ipp, 10, &(p->n_info.n_int.n_val), &(p->n_info.n_int.n_sign)); else { if (gr == NULL) fatal("unknown group: ", *ipp); p->n_info.n_int.n_val = gr->gr_gid; p->n_info.n_int.n_sign = 0; } break; case OP_SIZE: checkarg(*++ipp); i = strlen(*ipp) - 1; if ((*ipp)[i] == 'c') { p->n_type = OP_SIZEC; /* Count in bytes i.s.o. blocks */ (*ipp)[i] = '\0'; } number(*ipp, 10, &(p->n_info.n_int.n_val), &(p->n_info.n_int.n_sign)); break; case OP_LINKS: case OP_INUM: checkarg(*++ipp); number(*ipp, 10, &(p->n_info.n_int.n_val), &(p->n_info.n_int.n_sign)); break; case OP_PERM: checkarg(*++ipp); if (isnumber(*ipp, 8, 1)) number(*ipp, 8, &(p->n_info.n_int.n_val), &(p->n_info.n_int.n_sign)); else fmode(*ipp, &(p->n_info.n_int.n_val), &(p->n_info.n_int.n_sign)); break; case OP_ATIME: case OP_CTIME: case OP_MTIME: checkarg(*++ipp); number(*ipp, 10, &l, &(p->n_info.n_int.n_sign)); p->n_info.n_int.n_val = current_time - l * SECS_PER_DAY; /* More than n days old means less than the absolute time */ p->n_info.n_int.n_sign *= -1; break; case OP_EXEC: case OP_OK: checkarg(*++ipp); e = (struct exec *) Malloc(sizeof(struct exec)); e->e_cnt = 2; e->e_vec[0] = SHELL; p->n_info.n_exec = e; while (*ipp) { if (**ipp == ';' && (*ipp)[1] == '\0') { e->e_vec[e->e_cnt] = 0; break; } e->e_vec[(e->e_cnt)++] = (**ipp == '{' && (*ipp)[1] == '}' && (*ipp)[2] == '\0') ? (char *) (-1) : *ipp; ipp++; } if (*ipp == 0) fatal("-exec/-ok: ; missing", ""); if ((e->e_vec[1] = find_bin(e->e_vec[2])) == 0) fatal("can't find program ", e->e_vec[2]); if (t == OP_OK) if ((tty = open("/dev/tty", O_RDWR)) < 0) fatal("can't open /dev/tty", ""); break; case OP_NEWER: checkarg(*++ipp); if (LSTAT(*ipp, &est) == -1) fatal("-newer: can't get status of ", *ipp); p->n_info.n_int.n_val = est.st_mtime; break; case OP_NAME: checkarg(*++ipp); p->n_info.n_str = *ipp; break; case OP_XDEV: xdev_flag = 1; break; case OP_DEPTH: depth_flag = 1; break; case OP_PRUNE: case OP_PRINT: case OP_PRINT0: case OP_NOUSER: case OP_NOGROUP: break; default: fatal("syntax error, operator expected", ""); } if ((t == OP_PRINT) || (t == OP_PRINT0) || (t == OP_EXEC) || (t == OP_OK)) needprint = 0; return p;}/*######################## DIAGNOSTICS ##############################*/void nonfatal(s1, s2)char *s1, *s2;{ fprintf(stderr, "%s: %s%s\n", prog, s1, s2);}void fatal(s1, s2)char *s1, *s2;{ nonfatal(s1, s2); exit(1);}/*################### SMATCH #########################*//* Don't try to understand the following one... */int smatch(s, t) /* shell-like matching */char *s, *t;{ register n; if (*t == '\0') return *s == '\0'; if (*t == '*') { ++t; do if (smatch(s, t)) return 1; while (*s++ != '\0'); return 0; } if (*s == '\0') return 0; if (*t == '\\') return (*s == *++t) ? smatch(++s, ++t) : 0; if (*t == '?') return smatch(++s, ++t); if (*t == '[') { while (*++t != ']') { if (*t == '\\') ++t; if (*(t + 1) != '-') if (*t == *s) { while (*++t != ']') if (*t == '\\') ++t; return smatch(++s, ++t); } else continue; if (*(t + 2) == ']') return(*s == *t || *s == '-'); n = (*(t + 2) == '\\') ? 3 : 2; if (*s >= *t && *s <= *(t + n)) { while (*++t != ']') if (*t == '\\') ++t; return smatch(++s, ++t); } t += n; } return 0; } return(*s == *t) ? smatch(++s, ++t) : 0;}/*####################### EXECUTE ###########################*//* Do -exec or -ok */char * find_bin(s)char *s;{ char *f, *l, buf[PATH_MAX]; if (*s == '/') /* absolute path name */ return(access(s, 1) == 0) ? s : 0; l = f = epath; for (;;) { if (*l == ':' || *l == 0) { if (l == f) { if (access(s, 1) == 0) return Salloc(s); f++; } else { register char *p = buf, *q = s; while (f != l) *p++ = *f++; f++; *p++ = '/'; while (*p++ = *q++) { } if (access(buf, 1) == 0) return Salloc(buf); } if (*l == 0) break; } l++; } return 0;}int execute(op, e, path)int op;struct exec *e;char *path;{ int s, pid; char *argv[MAXARG]; register char **p, **q; for (p = e->e_vec, q = argv; *p;) /* replace the {}s */ if ((*q++ = *p++) == (char *) -1) q[-1] = path; *q = '\0'; if (op == OP_OK) { char answer[10]; for (p = &argv[2]; *p; p++) { write(tty, *p, strlen(*p)); write(tty, " ", 1); } write(tty, "? ", 2); if (read(tty, answer, 10) < 2 || *answer != 'y') return 0; } if ((pid = fork()) == -1) fatal("can't fork", ""); if (pid == 0) { register i = 3; while (close(i++) == 0) { } /* wow!!! */ execv(argv[1], &argv[2]); /* binary itself? */ execv(argv[0], &argv[1]); /* shell command? */ fatal("exec failure: ", argv[1]); /* none of them! */ exit(127); } return wait(&s) == pid && s == 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -