int b_date(int argc, register char** argv, void* context) { register int n; register char* s; register Fmt_t* f; char* t; unsigned long u; Time_t now; Time_t ts; Time_t te; Time_t e; char buf[1024]; Fmt_t* fmts; Fmt_t fmt; struct stat st; char* cmd = argv[0]; /* original command path */ char* format = 0; /* tmxfmt() format */ char* string = 0; /* date string */ int elapsed = 0; /* args are start/stop pairs */ int filetime = 0; /* use this st_ time field */ int increment = 0; /* incrementally adjust time */ int last = 0; /* display the last time arg */ Tm_zone_t* listzones = 0; /* known time zone table */ int network = 0; /* don't set network time */ int show = 0; /* show date and don't set */ int unelapsed = 0; /* fmtelapsed() => strelapsed */ cmdinit(argc, argv, context, ERROR_CATALOG, 0); tm_info.flags = TM_DATESTYLE; fmts = &fmt; fmt.format = ""; fmt.next = 0; for (;;) { switch (optget(argv, usage)) { case 'a': case 'c': case 'm': filetime = opt_info.option[1]; continue; case 'd': string = opt_info.arg; show = 1; continue; case 'e': format = "%#"; continue; case 'E': elapsed = 1; continue; case 'f': format = opt_info.arg; continue; case 'i': increment = 1; continue; case 'l': tm_info.flags |= TM_LEAP; continue; case 'L': last = 1; continue; case 'n': network = 1; continue; case 'p': if (!(f = newof(0, Fmt_t, 1, 0))) error(ERROR_SYSTEM|3, "out of space [format]"); f->next = fmts; f->format = opt_info.arg; fmts = f; continue; case 's': show = 1; continue; case 'u': tm_info.flags |= TM_UTC; continue; case 'U': unelapsed = (int)opt_info.num; continue; case 'z': listzones = tm_data.zone; continue; case '?': error(ERROR_USAGE|4, "%s", opt_info.arg); continue; case ':': error(2, "%s", opt_info.arg); continue; } break; } argv += opt_info.index; if (error_info.errors) error(ERROR_USAGE|4, "%s", optusage(NiL)); now = tmxgettime(); if (listzones) { s = "-"; while (listzones->standard) { if (listzones->type) s = listzones->type; sfprintf(sfstdout, "%3s %4s %4s %4d %4d\n", s, *listzones->standard ? listzones->standard : "-", listzones->daylight ? listzones->daylight : "-", listzones->west, listzones->dst); listzones++; show = 1; } } else if (elapsed) { e = 0; while (s = *argv++) { if (!(t = *argv++)) { argv--; t = "now"; } ts = convert(fmts, s, now); te = convert(fmts, t, now); if (te > ts) e += te - ts; else e += ts - te; } sfputr(sfstdout, fmtelapsed((unsigned long)tmxsec(e), 1), '\n'); show = 1; } else if (unelapsed) { while (s = *argv++) { u = strelapsed(s, &t, unelapsed); if (*t) error(3, "%s: invalid elapsed time", s); sfprintf(sfstdout, "%lu\n", u); } show = 1; } else if (filetime) { if (!*argv) error(ERROR_USAGE|4, "%s", optusage(NiL)); n = argv[1] != 0; while (s = *argv++) { if (stat(s, &st)) error(2, "%s: not found", s); else { switch (filetime) { case 'a': now = tmxgetatime(&st); break; case 'c': now = tmxgetctime(&st); break; default: now = tmxgetmtime(&st); break; } tmxfmt(buf, sizeof(buf), format, now); if (n) sfprintf(sfstdout, "%s: %s\n", s, buf); else sfprintf(sfstdout, "%s\n", buf); show = 1; } } } else { if ((s = *argv) && !format && *s == '+') { format = s + 1; argv++; s = *argv; } if (s || (s = string)) { if (*argv && string) error(ERROR_USAGE|4, "%s", optusage(NiL)); now = convert(fmts, s, now); if (*argv && (s = *++argv)) { show = 1; do { if (!last) { tmxfmt(buf, sizeof(buf), format, now); sfprintf(sfstdout, "%s\n", buf); } now = convert(fmts, s, now); } while (s = *++argv); } } else show = 1; if (format || show) { tmxfmt(buf, sizeof(buf), format, now); sfprintf(sfstdout, "%s\n", buf); } else if (settime(context, cmd, now, increment, network)) error(ERROR_SYSTEM|3, "cannot set system time"); } while (fmts != &fmt) { f = fmts; fmts = fmts->next; free(f); } tm_info.flags = 0; if (show && sfsync(sfstdout)) error(ERROR_system(0), "write error"); return error_info.errors != 0; }
int test_unop(Shell_t *shp,register int op,register const char *arg) { struct stat statb; int f; switch(op) { case 'r': return(permission(arg, R_OK)); case 'w': return(permission(arg, W_OK)); case 'x': return(permission(arg, X_OK)); case 'V': #if SHOPT_FS_3D { register int offset = staktell(); if(stat(arg,&statb)<0 || !S_ISREG(statb.st_mode)) return(0); /* add trailing / */ stakputs(arg); stakputc('/'); stakputc(0); arg = (const char*)stakptr(offset); stakseek(offset); /* FALL THRU */ } #else return(0); #endif /* SHOPT_FS_3D */ case 'd': return(test_stat(arg,&statb)>=0 && S_ISDIR(statb.st_mode)); case 'c': return(test_stat(arg,&statb)>=0 && S_ISCHR(statb.st_mode)); case 'b': return(test_stat(arg,&statb)>=0 && S_ISBLK(statb.st_mode)); case 'f': return(test_stat(arg,&statb)>=0 && S_ISREG(statb.st_mode)); case 'u': return(test_mode(arg)&S_ISUID); case 'g': return(test_mode(arg)&S_ISGID); case 'k': #ifdef S_ISVTX return(test_mode(arg)&S_ISVTX); #else return(0); #endif /* S_ISVTX */ #if SHOPT_TEST_L case 'l': #endif case 'L': case 'h': /* undocumented, and hopefully will disappear */ if(*arg==0 || arg[strlen(arg)-1]=='/' || lstat(arg,&statb)<0) return(0); return(S_ISLNK(statb.st_mode)); case 'C': #ifdef S_ISCTG return(test_stat(arg,&statb)>=0 && S_ISCTG(statb.st_mode)); #else return(0); #endif /* S_ISCTG */ case 'H': #ifdef S_ISCDF { register int offset = staktell(); if(test_stat(arg,&statb)>=0 && S_ISCDF(statb.st_mode)) return(1); stakputs(arg); stakputc('+'); stakputc(0); arg = (const char*)stakptr(offset); stakseek(offset); return(test_stat(arg,&statb)>=0 && S_ISCDF(statb.st_mode)); } #else return(0); #endif /* S_ISCDF */ case 'S': return(isasock(arg,&statb)); case 'N': return(test_stat(arg,&statb)>=0 && tmxgetmtime(&statb) > tmxgetatime(&statb)); case 'p': return(isapipe(arg,&statb)); case 'n': return(*arg != 0); case 'z': return(*arg == 0); case 's': sfsync(sfstdout); case 'O': case 'G': if(*arg==0 || test_stat(arg,&statb)<0) return(0); if(op=='s') return(statb.st_size>0); else if(op=='O') return(statb.st_uid==shp->gd->userid); return(statb.st_gid==shp->gd->groupid); case 'a': case 'e': if(memcmp(arg,"/dev/",5)==0 && sh_open(arg,O_NONBLOCK)) return(1); return(permission(arg, F_OK)); case 'o': f=1; if(*arg=='?') return(sh_lookopt(arg+1,&f)>0); op = sh_lookopt(arg,&f); return(op && (f==(sh_isoption(op)!=0))); case 't': { char *last; op = strtol(arg,&last, 10); return(*last?0:tty_check(op)); } case 'v': case 'R': { Namval_t *np; Namarr_t *ap; int isref; if(!(np = nv_open(arg,shp->var_tree,NV_VARNAME|NV_NOFAIL|NV_NOADD|NV_NOREF))) return(0); isref = nv_isref(np); if(op=='R') return(isref); if(isref) { if(np->nvalue.cp) np = nv_refnode(np); else return(0); } if(ap = nv_arrayptr(np)) return(nv_arrayisset(np,ap)); return(!nv_isnull(np) || nv_isattr(np,NV_INTEGER)); } default: { static char a[3] = "-?"; a[1]= op; errormsg(SH_DICT,ERROR_exit(2),e_badop,a); /* NOTREACHED */ return(0); } } }