1: #if !defined(lint) && defined(DOSCCS)
   2: static  char *sccsid = "@(#)dumpoptr.c	1.6 (2.11BSD GTE) 1996/11/16";
   3: #endif
   4: 
   5: #include "dump.h"
   6: 
   7: struct  group *getgrnam();
   8: /*
   9:  *	Query the operator; This fascist piece of code requires
  10:  *	an exact response.
  11:  *	It is intended to protect dump aborting by inquisitive
  12:  *	people banging on the console terminal to see what is
  13:  *	happening which might cause dump to croak, destroying
  14:  *	a large number of hours of work.
  15:  *
  16:  *	Every 2 minutes we reprint the message, alerting others
  17:  *	that dump needs attention.
  18:  */
  19: int timeout;
  20: char    *attnmessage;       /* attemtion message */
  21: 
  22: query(question)
  23:     char    *question;
  24: {
  25:     char    replybuffer[64];
  26:     int back;
  27:     FILE    *mytty;
  28: 
  29:     if ( (mytty = fopen("/dev/tty", "r")) == NULL){
  30:         msg("fopen on /dev/tty fails\n");
  31:         abort();
  32:     }
  33:     attnmessage = question;
  34:     timeout = 0;
  35:     alarmcatch();
  36:     for(;;){
  37:         if ( fgets(replybuffer, 63, mytty) == NULL){
  38:             if (ferror(mytty)){
  39:                 clearerr(mytty);
  40:                 continue;
  41:             }
  42:         } else if ( (strcmp(replybuffer, "yes\n") == 0) ||
  43:                 (strcmp(replybuffer, "Yes\n") == 0)){
  44:                 back = 1;
  45:                 goto done;
  46:         } else if ( (strcmp(replybuffer, "no\n") == 0) ||
  47:                 (strcmp(replybuffer, "No\n") == 0)){
  48:                 back = 0;
  49:                 goto done;
  50:         } else {
  51:             msg("\"Yes\" or \"No\"?\n");
  52:             alarmcatch();
  53:         }
  54:     }
  55:     done:
  56:     /*
  57: 	 *	Turn off the alarm, and reset the signal to trap out..
  58: 	 */
  59:     alarm(0);
  60:     if (signal(SIGALRM, sigalrm) == SIG_IGN)
  61:         signal(SIGALRM, SIG_IGN);
  62:     fclose(mytty);
  63:     return(back);
  64: }
  65: /*
  66:  *	Alert the console operator, and enable the alarm clock to
  67:  *	sleep for 2 minutes in case nobody comes to satisfy dump
  68:  */
  69: alarmcatch()
  70: {
  71:     if (timeout)
  72:         msgtail("\n");
  73:     msg("NEEDS ATTENTION: %s: (\"yes\" or \"no\") ",
  74:         attnmessage);
  75:     signal(SIGALRM, alarmcatch);
  76:     alarm(120);
  77:     timeout = 1;
  78: }
  79: /*
  80:  *	Here if an inquisitive operator interrupts the dump program
  81:  */
  82: interrupt()
  83: {
  84:     msg("Interrupt received.\n");
  85:     if (query("Do you want to abort dump?"))
  86:         dumpabort();
  87:     signal(SIGINT, interrupt);
  88: }
  89: 
  90: /*
  91:  *	The following variables and routines manage alerting
  92:  *	operators to the status of dump.
  93:  *	This works much like wall(1) does.
  94:  */
  95: struct  group *gp;
  96: 
  97: /*
  98:  *	Get the names from the group entry "operator" to notify.
  99:  */
 100: set_operators()
 101: {
 102:     if (!notify)        /*not going to notify*/
 103:         return;
 104:     gp = getgrnam(OPGRENT);
 105:     endgrent();
 106:     if (gp == (struct group *)0){
 107:         msg("No entry in /etc/group for %s.\n",
 108:             OPGRENT);
 109:         notify = 0;
 110:         return;
 111:     }
 112: }
 113: 
 114: struct tm *localtime();
 115: struct tm *localclock;
 116: 
 117: /*
 118:  *	We fork a child to do the actual broadcasting, so
 119:  *	that the process control groups are not messed up
 120:  */
 121: broadcast(message)
 122:     char    *message;
 123: {
 124:     time_t      clock;
 125:     FILE    *f_utmp;
 126:     struct  utmp    utmp;
 127:     char    **np;
 128:     int pid, s;
 129: 
 130:     switch (pid = fork()) {
 131:     case -1:
 132:         return;
 133:     case 0:
 134:         break;
 135:     default:
 136:         while (wait(&s) != pid)
 137:             continue;
 138:         return;
 139:     }
 140: 
 141:     if (!notify || gp == 0)
 142:         exit(0);
 143:     clock = time((time_t *)0);
 144:     localclock = localtime(&clock);
 145: 
 146:     if((f_utmp = fopen(_PATH_UTMP, "r")) == NULL) {
 147:         msg("Cannot open 'utmp'\n");
 148:         return;
 149:     }
 150: 
 151:     while (!feof(f_utmp)){
 152:         if (fread((char *)&utmp, sizeof (struct utmp), 1, f_utmp) != 1)
 153:             break;
 154:         if (utmp.ut_name[0] == 0)
 155:             continue;
 156:         for (np = gp->gr_mem; *np; np++){
 157:             if (strncmp(*np, utmp.ut_name, sizeof(utmp.ut_name)) != 0)
 158:                 continue;
 159:             /*
 160: 			 *	Do not send messages to operators on dialups
 161: 			 */
 162:             if (strncmp(utmp.ut_line, DIALUP, strlen(DIALUP)) == 0)
 163:                 continue;
 164: #ifdef DEBUG
 165:             msg("Message to %s at %s\n",
 166:                 utmp.ut_name, utmp.ut_line);
 167: #endif DEBUG
 168:             sendmes(utmp.ut_line, message);
 169:         }
 170:     }
 171:     fclose(f_utmp);
 172:     Exit(0);    /* the wait in this same routine will catch this */
 173:     /* NOTREACHED */
 174: }
 175: 
 176: sendmes(tty, message)
 177: char *tty, *message;
 178: {
 179:     char t[50], buf[BUFSIZ];
 180:     register char *cp;
 181:     register int c;
 182:     int ch, msize;
 183:     register FILE *f_tty;
 184: 
 185:     msize = strlen(message);
 186:     strcpy(t, "/dev/");
 187:     strcat(t, tty);
 188: 
 189:     if((f_tty = fopen(t, "w")) != NULL) {
 190:         setbuf(f_tty, buf);
 191:         fprintf(f_tty, "\n\007\007\007Message from the dump program to all operators at %d:%02d ...\r\n\n"
 192:                ,localclock->tm_hour
 193:                ,localclock->tm_min);
 194:         for (cp = message, c = msize; c-- > 0; cp++) {
 195:             ch = *cp;
 196:             if (ch == '\n')
 197:                 putc('\r', f_tty);
 198:             putc(ch, f_tty);
 199:         }
 200:         fclose(f_tty);
 201:     }
 202: }
 203: 
 204: /*
 205:  *	print out an estimate of the amount of time left to do the dump
 206:  */
 207: 
 208: time_t  tschedule = 0;
 209: 
 210: timeest()
 211: {
 212:     time_t  tnow, deltat;
 213:     long    pleft;
 214:     char buf[BUFSIZ];
 215: 
 216:     time (&tnow);
 217:     if (tnow >= tschedule){
 218:         tschedule = tnow + 300;
 219:         if (blockswritten < 500L)
 220:             return;
 221: /*
 222: 			/				    \
 223: 			|/ estimated blocks \		    |
 224: 	delta time =	||----------------  | X time so far |  - time so far
 225: 			|\ blocks thus far  /		    |
 226: 			\				    /
 227: */
 228:         pleft  = ((100 * esize)/blockswritten) - 100;
 229:         deltat = (time_t) (tnow - tstart_writing) * pleft;
 230:         deltat = deltat/100;    /* scale back down */
 231:         sprintf(buf,"%3.2f%%%% done, finished in %d:%02d\n",
 232:             (float) (blockswritten*100.0)/esize,
 233:             (int)(deltat/3600L), (int)((deltat%3600L)/60L));
 234:         msg(buf);
 235:     }
 236: }
 237: 
 238: /* VARARGS1 */
 239: /* ARGSUSED */
 240: msg(fmt, a1, a2, a3, a4, a5)
 241:     char    *fmt;
 242: {
 243:     fprintf(stderr,"  DUMP: ");
 244: #ifdef TDEBUG
 245:     fprintf(stderr,"pid=%d ", getpid());
 246: #endif
 247:     fprintf(stderr, fmt, a1, a2, a3, a4, a5);
 248:     fflush(stdout);
 249:     fflush(stderr);
 250: }
 251: 
 252: /* VARARGS1 */
 253: /* ARGSUSED */
 254: msgtail(fmt, a1, a2, a3, a4, a5)
 255:     char    *fmt;
 256: {
 257:     fprintf(stderr, fmt, a1, a2, a3, a4, a5);
 258: }
 259: 
 260: /*
 261:  *	Tell the operator what has to be done.
 262:  */
 263: lastdump(arg)
 264:     char    arg;    /* w ==> just what to do; W ==> most recent dumps */
 265: {
 266:             char    *lastname;
 267:             char    *date;
 268:     register    int i;
 269:             time_t  tnow;
 270:     register    struct  fstab   *dt;
 271:             int dumpme;
 272:     register    struct  idates  *itwalk;
 273: 
 274:     int idatesort();
 275: 
 276:     time(&tnow);
 277:     inititimes();       /* /etc/dumpdates input */
 278:     qsort(idatev, nidates, sizeof(struct idates *), idatesort);
 279: 
 280:     if (arg == 'w')
 281:         fprintf(stdout, "Dump these file systems:\n");
 282:     else
 283:         fprintf(stdout, "Last dump(s) done (Dump '>' file systems):\n");
 284:     lastname = "??";
 285:     ITITERATE(i, itwalk){
 286:         if (strncmp(lastname, itwalk->id_name, sizeof(itwalk->id_name)) == 0)
 287:             continue;
 288:         date = (char *)ctime(&itwalk->id_ddate);
 289:         date[16] = '\0';    /* blast away seconds and year */
 290:         lastname = itwalk->id_name;
 291:         dt = getfsspec(deraw(itwalk->id_name));
 292:         dumpme = (  (dt != 0)
 293:              && (dt->fs_freq != 0)
 294:              && (itwalk->id_ddate < tnow - (dt->fs_freq*DAY)));
 295:         if ( (arg != 'w') || dumpme)
 296:           fprintf(stdout,"%c %8s\t(%6s) Last dump: Level %c, Date %s\n",
 297:             dumpme && (arg != 'w') ? '>' : ' ',
 298:             itwalk->id_name,
 299:             dt ? dt->fs_file : 0,
 300:             itwalk->id_incno,
 301:             date
 302:             );
 303:     }
 304: }
 305: 
 306: int idatesort(p1, p2)
 307:     struct  idates  **p1, **p2;
 308: {
 309:     int diff;
 310: 
 311:     diff = strncmp((*p1)->id_name, (*p2)->id_name, sizeof((*p1)->id_name));
 312:     if (diff == 0)
 313:         if ((*p2)->id_ddate > (*p1)->id_ddate)
 314:             return (1);
 315:         else
 316:             if ((*p2)->id_ddate == (*p1)->id_ddate)
 317:                 return (0);
 318:             else
 319:                 return (-1);
 320:     else
 321:         return (diff);
 322: }

Defined functions

alarmcatch defined in line 69; used 3 times
idatesort defined in line 306; used 2 times
interrupt defined in line 82; used 2 times
lastdump defined in line 263; used 2 times
msg defined in line 240; used 70 times
msgtail defined in line 254; used 4 times
query defined in line 22; used 6 times
sendmes defined in line 176; used 1 times
set_operators defined in line 100; used 1 times
timeest defined in line 210; used 1 times

Defined variables

attnmessage defined in line 20; used 2 times
gp defined in line 95; used 4 times
localclock defined in line 115; used 3 times
sccsid defined in line 2; never used
timeout defined in line 19; used 3 times
tschedule defined in line 208; used 2 times
Last modified: 1996-11-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3484
Valid CSS Valid XHTML 1.0 Strict