static int GetStatFromARC(char *arc_line, char *name, struct stat *stat) { char *t, *old; int i, id; struct tm tm_struct; static char *month[] = { "Jan", "Feb", "Mar", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; (void) memset( stat, 0, sizeof( struct stat ) ); stat->st_nlink = 1; t = Strtok_r( arc_line, " \t", &old ); if( t == NULL ) return( -1 ); /* Dateiname */ /*-----------*/ (void) strcpy( name, t ); t = Strtok_r( NULL, " \t", &old ); if( t == NULL ) return( -1 ); /* Dateilaenge */ /*-------------*/ if( !isdigit( *t ) ) return( -1 ); stat->st_size = AtoLL( t ); t = Strtok_r( NULL, " \t", &old ); if( t == NULL ) return( -1 ); /* Stowage */ /*---------*/ t = Strtok_r( NULL, " \t", &old ); if( t == NULL ) return( -1 ); /* SF */ /*----*/ t = Strtok_r( NULL, " \t", &old ); if( t == NULL ) return( -1 ); /* Size Now */ /*----------*/ if( !isdigit( *t ) ) return( -1 ); t = Strtok_r( NULL, " \t", &old ); if( t == NULL ) return( -1 ); /* M-Datum */ /*---------*/ tm_struct.tm_mday = atoi( t ); t = Strtok_r( NULL, " \t", &old ); if( t == NULL ) return( -1 ); for( i=0; i < 12; i++ ) { if( !strcmp( t, month[i] ) ) break; } if( i >= 12 ) i = 0; tm_struct.tm_mon = i; t = Strtok_r( NULL, " \t", &old ); if( t == NULL ) return( -1 ); tm_struct.tm_year = atoi( t ); if(tm_struct.tm_year < 70) tm_struct.tm_year += 100; t = Strtok_r( NULL, " \t:", &old ); if( t == NULL ) return( -1 ); tm_struct.tm_hour = atoi( t ); t = Strtok_r( NULL, " \t", &old ); if( t == NULL ) return( -1 ); if( t[strlen(t)-1] == 'p' ) tm_struct.tm_hour += 12; t[strlen(t)-1] ='\0'; tm_struct.tm_min = atoi( t ); t = Strtok_r( NULL, " \t", &old ); if( t == NULL ) return( -1 ); tm_struct.tm_sec = 0; tm_struct.tm_isdst = -1; stat->st_atime = 0; stat->st_ctime = 0; stat->st_mtime = Mktime( &tm_struct ); /* Attributes */ /*------------*/ stat->st_mode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; /* Owner */ /*-------*/ id = getuid(); if( id == -1 ) id = atoi( t ); stat->st_uid = (unsigned) id; /* Group */ /*-------*/ id = getgid(); stat->st_gid = (unsigned) id; return( 0 ); }
static int GetStatFromRAR(char *rar_line, char *name, struct stat *stat) { char *t, *old; int id; struct tm tm_struct; (void) memset( stat, 0, sizeof( struct stat ) ); stat->st_nlink = 1; t = Strtok_r( rar_line, " \t", &old ); if( t == NULL ) return( -1 ); /* Dateiname */ /*-----------*/ (void) strcpy( name, t ); t = Strtok_r( NULL, " \t", &old ); if( t == NULL ) return( -1 ); /* Dateilaenge */ /*-------------*/ if( !isdigit( *t ) ) return( -1 ); stat->st_size = AtoLL( t ); t = Strtok_r( NULL, " \t", &old ); if( t == NULL ) return( -1 ); /* Packed */ /*--------*/ t = Strtok_r( NULL, " \t", &old ); if( t == NULL ) return( -1 ); /* Ratio */ /*-------*/ t = Strtok_r( NULL, " \t", &old ); if( t == NULL ) return( -1 ); /* M-Datum */ /*---------*/ if(strlen(t) == 8) { t[2] = t[5] = '\0'; tm_struct.tm_mday = atoi( &t[0] ); tm_struct.tm_mon = atoi( &t[3] ); tm_struct.tm_year = atoi( &t[6] ); if(tm_struct.tm_year < 70) tm_struct.tm_year += 100; } t = Strtok_r( NULL, " \t", &old ); if( t == NULL ) return( -1 ); /* M-time */ /*--------*/ if(strlen(t) == 5) { t[2] = '\0'; tm_struct.tm_hour = atoi( &t[0] ); tm_struct.tm_min = atoi( &t[2] ); } tm_struct.tm_sec = 0; tm_struct.tm_isdst = -1; stat->st_atime = 0; stat->st_ctime = 0; stat->st_mtime = Mktime( &tm_struct ); t = Strtok_r( NULL, " \t", &old ); if( t == NULL ) return( -1 ); /* Attributes */ /*------------*/ stat->st_mode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; /* Owner */ /*-------*/ id = getuid(); if( id == -1 ) id = atoi( t ); stat->st_uid = (unsigned) id; /* Group */ /*-------*/ id = getgid(); stat->st_gid = (unsigned) id; return( 0 ); }
int main(int argc, char *argv[]) { int f_dayAfter = 0; /* days after current date */ int f_dayBefore = 0; /* days before current date */ int Friday = 5; /* day before weekend */ int ch; struct tm tp1, tp2; (void)setlocale(LC_ALL, ""); while ((ch = getopt(argc, argv, "-A:aB:D:dF:f:l:t:U:W:?")) != -1) switch (ch) { case '-': /* backward contemptible */ case 'a': if (getuid()) { errno = EPERM; err(1, NULL); } doall = 1; break; case 'W': /* we don't need no steenking Fridays */ Friday = -1; /* FALLTHROUGH */ case 'A': /* days after current date */ f_dayAfter = atoi(optarg); break; case 'B': /* days before current date */ f_dayBefore = atoi(optarg); break; case 'D': /* debug output of sun and moon info */ DEBUG = optarg; break; case 'd': /* debug output of current date */ debug = 1; break; case 'F': /* Change the time: When does weekend start? */ Friday = atoi(optarg); break; case 'f': /* other calendar file */ calendarFile = optarg; break; case 'l': /* Change longitudal position */ EastLongitude = strtol(optarg, NULL, 10); break; case 't': /* other date, for tests */ f_time = Mktime(optarg); break; case 'U': /* Change UTC offset */ UTCOffset = strtod(optarg, NULL); break; case '?': default: usage(); } argc -= optind; argv += optind; if (argc) usage(); /* use current time */ if (f_time <= 0) (void)time(&f_time); /* if not set, determine where I could be */ { if (UTCOffset == UTCOFFSET_NOTSET && EastLongitude == LONGITUDE_NOTSET) { /* Calculate on difference between here and UTC */ time_t t; struct tm tm; long utcoffset, hh, mm, ss; double uo; time(&t); localtime_r(&t, &tm); utcoffset = tm.tm_gmtoff; /* seconds -> hh:mm:ss */ hh = utcoffset / SECSPERHOUR; utcoffset %= SECSPERHOUR; mm = utcoffset / SECSPERMINUTE; utcoffset %= SECSPERMINUTE; ss = utcoffset; /* hh:mm:ss -> hh.mmss */ uo = mm + (100.0 * (ss / 60.0)); uo /= 60.0 / 100.0; uo = hh + uo / 100; UTCOffset = uo; EastLongitude = UTCOffset * 15; } else if (UTCOffset == UTCOFFSET_NOTSET) { /* Base on information given */ UTCOffset = EastLongitude / 15; } else if (EastLongitude == LONGITUDE_NOTSET) { /* Base on information given */ EastLongitude = UTCOffset * 15; } } settimes(f_time, f_dayBefore, f_dayAfter, Friday, &tp1, &tp2); generatedates(&tp1, &tp2); /* * FROM now on, we are working in UTC. * This will only affect moon and sun related events anyway. */ if (setenv("TZ", "UTC", 1) != 0) errx(1, "setenv: %s", strerror(errno)); tzset(); if (debug) dumpdates(); if (DEBUG != NULL) { dodebug(DEBUG); exit(0); } if (doall) while ((pw = getpwent()) != NULL) { (void)setegid(pw->pw_gid); (void)initgroups(pw->pw_name, pw->pw_gid); (void)seteuid(pw->pw_uid); if (!chdir(pw->pw_dir)) cal(); (void)seteuid(0); } else cal(); exit(0); }
int main(int argc, char *argv[]) { int ch; char *caldir; (void)setlocale(LC_ALL, ""); while ((ch = getopt(argc, argv, "abf:t:A:B:-")) != -1) switch (ch) { case '-': /* backward contemptible */ case 'a': if (getuid()) errx(1, "%s", strerror(EPERM)); doall = 1; break; case 'b': bodun_always++; break; case 'f': /* other calendar file */ calendarFile = optarg; break; case 't': /* other date, undocumented, for tests */ if ((f_time = Mktime(optarg)) <= 0) errx(1, "specified date is outside allowed range"); break; case 'A': /* days after current date */ f_dayAfter = atoi(optarg); f_SetdayAfter = 1; break; case 'B': /* days before current date */ f_dayBefore = atoi(optarg); break; default: usage(); } argc -= optind; argv += optind; if (argc) usage(); /* use current time */ if (f_time <= 0) (void)time(&f_time); if (f_dayBefore) { /* Move back in time and only look forwards */ f_dayAfter += f_dayBefore; f_time -= SECSPERDAY * f_dayBefore; f_dayBefore = 0; } settime(&f_time); if (doall) { pid_t kid, deadkid; int kidstat, kidreaped, runningkids; int acstat; struct stat sbuf; time_t t; unsigned int sleeptime; signal(SIGCHLD, childsig); runningkids = 0; t = time(NULL); while ((pw = getpwent()) != NULL) { acstat = 0; /* Avoid unnecessary forks. The calendar file is only * opened as the user later; if it can't be opened, * it's no big deal. Also, get to correct directory. * Note that in an NFS environment root may get EACCES * on a chdir(), in which case we have to fork. As long as * we can chdir() we can stat(), unless the user is * modifying permissions while this is running. */ if (chdir(pw->pw_dir)) { if (errno == EACCES) acstat = 1; else continue; } if (stat(calendarFile, &sbuf) != 0) { if (chdir(calendarHome)) { if (errno == EACCES) acstat = 1; else continue; } if (stat(calendarNoMail, &sbuf) == 0 || stat(calendarFile, &sbuf) != 0) continue; } sleeptime = USERTIMEOUT; switch ((kid = fork())) { case -1: /* error */ warn("fork"); continue; case 0: /* child */ (void)setpgid(getpid(), getpid()); (void)setlocale(LC_ALL, ""); if (setusercontext(NULL, pw, pw->pw_uid, LOGIN_SETALL ^ LOGIN_SETLOGIN)) err(1, "unable to set user context (uid %u)", pw->pw_uid); if (acstat) { if (chdir(pw->pw_dir) || stat(calendarFile, &sbuf) != 0 || chdir(calendarHome) || stat(calendarNoMail, &sbuf) == 0 || stat(calendarFile, &sbuf) != 0) exit(0); } cal(); exit(0); } /* parent: wait a reasonable time, then kill child if * necessary. */ runningkids++; kidreaped = 0; do { sleeptime = sleep(sleeptime); /* Note that there is the possibility, if the sleep * stops early due to some other signal, of the child * terminating and not getting detected during the next * sleep. In that unlikely worst case, we just sleep * too long for that user. */ for (;;) { deadkid = waitpid(-1, &kidstat, WNOHANG); if (deadkid <= 0) break; runningkids--; if (deadkid == kid) { kidreaped = 1; sleeptime = 0; } } } while (sleeptime); if (!kidreaped) { /* It doesn't _really_ matter if the kill fails, e.g. * if there's only a zombie now. */ if (getpgid(kid) != getpgrp()) (void)killpg(getpgid(kid), SIGTERM); else (void)kill(kid, SIGTERM); warnx("uid %u did not finish in time", pw->pw_uid); } if (time(NULL) - t >= SECSPERDAY) errx(2, "'calendar -a' took more than a day; " "stopped at uid %u", pw->pw_uid); } for (;;) { deadkid = waitpid(-1, &kidstat, WNOHANG); if (deadkid <= 0) break; runningkids--; } if (runningkids) warnx("%d child processes still running when " "'calendar -a' finished", runningkids); } else if ((caldir = getenv("CALENDAR_DIR")) != NULL) { if(!chdir(caldir)) cal(); } else cal(); exit(0); }