00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <sys/types.h>
00015 #include <signal.h>
00016 #include <time.h>
00017 #include <utmp.h>
00018 #include <stdlib.h>
00019 #include <string.h>
00020 #include <unistd.h>
00021 #include <stdio.h>
00022
00023
00024 #define Min(a,b) ((a<b) ? a : b)
00025
00026 #define STRING 80
00027 #define MIN 60L
00028 #define HOUR (60L*60L)
00029
00030
00031
00032
00033 #define INTERVALS 13
00034 #define WARNINGS 4
00035
00036
00037 static char *Version = "@(#) LEAVE 1.4 (01/09/90)";
00038 static int intervals[INTERVALS] = {
00039 -5 * MIN,
00040 -1 * MIN,
00041 0,
00042 MIN,
00043 2 * MIN,
00044 3 * MIN,
00045 4 * MIN,
00046 5 * MIN,
00047 6 * MIN,
00048 7 * MIN,
00049 8 * MIN,
00050 9 * MIN,
00051 10 * MIN
00052 };
00053 static char *warnings[WARNINGS] = {
00054 "You have to leave within 5 minutes",
00055 "Just one more minute!",
00056 "Time to leave!",
00057 "You're going to be late!"
00058 };
00059
00060
00061 _PROTOTYPE(int main, (int argc, char **argv));
00062 _PROTOTYPE(void Usage, (void));
00063 _PROTOTYPE(void Get_Hour_Min, (char *when, int *hour, int *min));
00064 _PROTOTYPE(int Still_Logged_On, (char *user, char *tty));
00065
00066 void Usage()
00067 {
00068 fprintf(stderr, "Usage: leave [[+]hh[:]mm]\n");
00069 exit(1);
00070 }
00071
00072
00073 void Get_Hour_Min(when, hour, min)
00074 char *when;
00075 int *hour;
00076 int *min;
00077 {
00078 int hour_min;
00079 int just_min = 0;
00080
00081 switch (sscanf(when, "%d:%d", &hour_min, &just_min)) {
00082 case 1:
00083 *hour = hour_min / 100;
00084 *min = hour_min % 100;
00085 break;
00086 case 2:
00087 *hour = hour_min;
00088 *min = just_min;
00089 break;
00090 default:
00091 Usage();
00092 }
00093
00094 if (hour_min < 0 || just_min < 0 || *min > 59) Usage();
00095 }
00096
00097
00098 int Still_Logged_On(user, tty)
00099 char *user;
00100 char *tty;
00101 {
00102 FILE *f;
00103 struct utmp login;
00104
00105 if ((f = fopen(UTMP, "r")) == NULL)
00106
00107 return(1);
00108
00109 while (fread(&login, sizeof(struct utmp), (size_t)1, f) == 1) {
00110 if (!strncmp(login.ut_line, tty, (size_t)8))
00111 if (!strncmp(login.ut_name, user, (size_t)8)) {
00112 fclose(f);
00113 return(1);
00114 } else {
00115 fclose(f);
00116 return(0);
00117 }
00118 }
00119 fclose(f);
00120 return(0);
00121 }
00122
00123
00124 int main(argc, argv)
00125 int argc;
00126 char *argv[];
00127 {
00128 char when[STRING];
00129 time_t now = time((time_t *)0);
00130 time_t leave, delta;
00131 struct tm *tm;
00132 int hour, min;
00133 int pid, i;
00134 char *user = cuserid( (char *)NULL);
00135 char *tty = ttyname(0) + 5;
00136
00137
00138 if (argc <= 1) {
00139 printf("When do you have to leave? ");
00140 fflush(stdout);
00141 if (fgets(when, STRING, stdin) == NULL || when[0] == '\n') exit(0);
00142 } else {
00143 strcpy(when, argv[1]);
00144 if (argc > 2) strcat(when, argv[2]);
00145 }
00146
00147
00148 tm = localtime(&now);
00149 if (when[0] == '+') {
00150 Get_Hour_Min(&when[1], &hour, &min);
00151 tm->tm_hour += hour;
00152 tm->tm_min += min;
00153 leave = mktime(tm);
00154 } else {
00155
00156 Get_Hour_Min(&when[0], &hour, &min);
00157 tm->tm_hour = hour;
00158 tm->tm_min = min;
00159 leave = mktime(tm);
00160 if (leave < now) {
00161 printf("That time has already passed!\n");
00162 exit(1);
00163 }
00164 }
00165
00166 printf("Alarm set for %s", ctime(&leave));
00167
00168 if ((pid = fork()) == -1) {
00169 fprintf(stderr, "leave: can not fork\n");
00170 exit(1);
00171 }
00172 if (pid != 0) exit(0);
00173
00174
00175 if (user == NULL || tty == NULL) {
00176 fprintf(stderr, "leave: Can not determine user and terminal name\n");
00177 exit(1);
00178 }
00179 signal(SIGINT, SIG_IGN);
00180 signal(SIGQUIT, SIG_IGN);
00181 signal(SIGTERM, SIG_IGN);
00182
00183 for (;;) {
00184 if (!Still_Logged_On(user, tty)) exit(0);
00185
00186
00187
00188 delta = leave - time((time_t *)0);
00189
00190
00191 for (i = 0; i < INTERVALS; ++i)
00192 if (delta + intervals[i] > 0) break;
00193
00194
00195
00196
00197 if (i > 0)
00198 printf("\007\r%s\r\n",
00199 warnings[i > WARNINGS ? WARNINGS - 1 : i - 1]);
00200
00201 if (i == INTERVALS) {
00202 printf("That was the last time I'll tell you. Bye.\r\n");
00203 exit(0);
00204 }
00205
00206
00207
00208 sleep((unsigned) Min(delta + intervals[i], HOUR));
00209 }
00210 }