static char *sccsid = "%W%"; extern errno; #include "parms.h" #include "structs.h" #include /* signal processing */ #define LOCKTRY 10 /* number of shots at grabbing */ /* * dounix(charstring, flag) will execute that character string as a shell * command stolen from shell, though this one catches more signals. * * R. Kolstad -- 11/2/80 * modified: R. Essick January 1982, to clean up some signal processing * */ dounix (uid, ttymode, arg0, arg1, arg2, arg3, arg4) char *arg0, *arg1, *arg2, *arg3, *arg4; { register pid, rpid; int (*p) (), (*q) (), (*r) (); #ifdef SIGTSTP int (*s) (); #endif char *cmd; int retcode; extern char *myshell; if (ttymode) ttystop(); /* give back to normal mode */ if ((pid = fork()) == 0) { uncatchem(); /* reset this process signals */ /* if user can get his hands on it */ if (uid) { /* only set uid if giving shell */ setuid(globuid); /* give him his uid */ umask(msk); /* restore umask */ } else { setuid(NOTESUID); } if (arg0 == 0) { execlp(myshell, myshell, 0); cmd = myshell; } else { execlp(arg0, arg0, arg1, arg2, arg3, arg4); cmd = arg0; } fprintf(stderr, "dounix: execlp failed\n"); perror(cmd); _exit(1); } p = signal(SIGHUP, SIG_IGN); q = signal(SIGINT, SIG_IGN); r = signal(SIGQUIT, SIG_IGN); #ifdef SIGTSTP s = signal(SIGTSTP, SIG_DFL); #endif while ((rpid = wait(&retcode)) != pid && rpid != -1); signal(SIGHUP, p); signal(SIGINT, q); signal(SIGQUIT, r); #ifdef SIGTSTP signal(SIGTSTP, s); #endif if (ttymode) ttystrt(); /* set terminal mode back */ return(rpid!=-1 ? retcode>>8 : 1); } /* * print out an error message and die. * call includes a number and nam of routine where it * died. * * Ray Essick 10/23/80 */ x (cond, p) char *p; { if (cond == 0) { return; /* didnt fail */ } perror("notes"); printf("%s <---- abort (%d)\n", p, errno); printf("See a notes guru\n"); ttystop(); /* back to normal */ #ifdef DUMPCORE abort(); #else exit(BAD); /* for production */ #endif } int ignsigs; /* * lock creates a lock file, or waits until it can create the lock. * lock files are of the form lock# where # is a character passed * to the routine. * * Rob Kolstad 10/20/80 * modified: rbe December 1981 to add full path name for lock file */ lock (io, c) struct io_f *io; char c; { int i, trys; char p[WDLEN]; ignsigs++; sprintf (p, "%s/%s/%c%s", MSTDIR, LOCKS, c, io->nf); /* generate file name */ trys = LOCKTRY; /* set him up */ while ((i = creat (p, 0)) < 0) { if (trys-- == 0) { fprintf (stderr, "lock%c combo lost - see notes guru\n", c); ttystop (); exit (BAD); } sleep (2); /* guarantee at least 1 */ } close (i); } /* * unlock takes the same arguements as the lock routine, and it * will remove the corresponding lock file * * Rob Kolstad 10/20/80 * modified: rbe December 1981 to add full path name for lock name */ unlock (io, c) struct io_f *io; char c; { char p[WDLEN]; sprintf (p, "%s/%s/%c%s", MSTDIR, LOCKS, c, io->nf); /* generate file name */ x (unlink (p) < 0, "unlock: unlink lock"); ignsigs--; } /* * glock creates a lock file, or waits until it can create the lock. * lock files are of the form lock# where # is a character passed * to the routine. * This lock file is a GLOBAL lock - across all notefiles * * taken from lock routine above by R. Essick December 1981 */ glock (io, c) struct io_f *io; /* unused in this routine */ char c; { int i, trys; char p[WDLEN]; ignsigs++; sprintf (p, "%s/%s/%c", MSTDIR, LOCKS, c); /* generate file name */ trys = LOCKTRY; while ((i = creat (p, 0)) < 0) { if (trys-- == 0) { fprintf (stderr, "lock%c combo lost\n", c); ttystop (); exit (BAD); } sleep (2); /* is there a smaller time interval */ } close (i); } /* * gunlock takes the same arguements as the lock routine, and it * will remove the corresponding lock file * This is GLOBAL locking - across all notefiles * * copy of code from unlock, with minor changes * Ray Essick December 1981 */ gunlock (io, c) struct io_f *io; /* not used by this routine */ char c; { char p[WDLEN]; sprintf (p, "%s/%s/%c", MSTDIR, LOCKS, c); /* make the file name */ x (unlink (p) < 0, "gunlock: unlink lock"); ignsigs--; } /* * length tells us max(length of string, 1) */ len (p, n) char *p; { int i; i = n; p += n; while (*--p == ' ' && --i) { if (i == 0) { i = 1; } } return(i); } /* * shell - give the user a shell * this includes: * 1) changing to the directory where he came in from * 2) giving him a shell * 3) return to the notefile directory * * original author: Ray Essick may 29, 1981 * */ gshell() { int ret; printf ("\n"); ret = dounix (1, 1, 0, 0, 0, 0, 0); if (ret != 0) wfchar(); return(ret); } /* copydate merely moves a when_f structure from 'from' to 'to' */ /* ray essick - 20-nov-1981 */ copydate (from, to) struct when_f *from, *to; { to->w_year = from->w_year; to->w_month = from->w_month; to->w_day = from->w_day; to->w_hours = from->w_hours; to->w_mins = from->w_mins; } /* strcmp - tell whether two null terminated strings are equal */ /* returns < if a < b, 0 if a == b, > if a > b */ /* r. essick 20-nov-81 */ strcmp (p, q) char *p, *q; { register char *pp, *qq; /* make it FAST */ pp = p; qq = q; /* must initialize them */ for (; *pp == *qq; pp++, qq++) { if (*pp == '\0') { return(0); } } return(*pp - *qq); } /* strmove - copy a null terminated string to another */ /* returns the count of characters moved, this count includes the */ /* null terminator.. */ /* r. essick 20-nov-81 */ strmove (p, q) char *p, *q; /* from p to q */ { int count; register char *pp, *qq; count = 0; /* start with no characters moved */ pp = p; qq = q; /* use registers for speed */ while (*qq++ = *pp++) { count++; } return(count); /* return count of characters moved */ /* don't include the terminator */ } /* copyauth(from, to) struct auth_f *from,*auth * copys author from from to to * Ray Essick December 1981 */ copyauth (from, to) struct auth_f *from, *to; { strmove (from->aname, to->aname); /* copy the author name */ to->aid = from->aid; /* and user id */ } /* listget, listconv - parse a list of numbers. * this is all taken ( sort of ) from Rob Kolstad's getpg * program */ listget (buf, ptr, start, finish) char buf[]; int *ptr, *start, *finish; { if ((buf[*ptr] < '0' || buf[*ptr] > '9') && buf[*ptr] != ' ') { return(0); /* end of this list */ } *start = listconv (buf, ptr); /* get the first */ *finish = *start; /* default to single */ if (buf[*ptr] == '-') { ++(*ptr); /* trash that separator */ *finish = listconv (buf, ptr); /* grab second */ ++(*ptr); /* bump past delimiter */ return(2); /* parsed 2 arguements */ } else { if (buf[*ptr] != '\0') { ++(*ptr); /* dump delimiter */ } return(1); } } listconv (buf, ptr) char buf[]; int *ptr; { int i; i = 0; while (buf[*ptr] == ' ') { ++(*ptr); } while (buf[*ptr] >= '0' && buf[*ptr] <= '9') { i = 10 * i + buf[*ptr] - '0'; ++(*ptr); /* bump him */ } return(i); } /* tolcase - check to see if upper case, and convert to lcase */ /* R. Essick Feb 1982 */ tolcase (c) char c; { if (c < 'A' || c > 'Z') { return c; } else { return(c - 'A' + 'a'); /* ascii only !!!!! */ } } /* * miscellaneous output routines for the terminal * * center(p,len,row,col) takes a character string pointed at by p and * centers it within a field of length n. it is printed on screen at row,col * (centered). It is also assumed that p's string is BLANK TERMINATED * * prdate(w) struct when_f *w; prints the date. Assumes 'at' is already done * * sprdate(w,str) struct when_f *w; char str[]; formats the date and returns * the result in the string pointed to by str. * */ center(p, len, row, col) char *p; { int i; char *r; r = p + len; i = len; while (*--r == ' ' && --i) continue; /* scan backwards to first nonblank */ if (i != 0) { at(row, col + (len - i) / 2); /* text on stdout */ fwrite(p, sizeof *r, i, stdout); } } char *mnames[13] = /* so indexes work right */ { "???", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; sprdate(w, str) struct when_f *w; char *str; { char *m; int h, i, j; /* temps to print 0's or funny strings */ m = "am"; h = w->w_hours; if (h >= 12) m = "pm"; if (h == 0) h = 12; if (h > 12) h -= 12; i = w->w_mins / 10; j = w->w_mins % 10; /* get those leading zeroes */ sprintf(str, "%2d:%d%d %2s %3s %2d, %4d", h, i, j, m, mnames[w->w_month], w->w_day, w->w_year); } prdate(zdate) struct when_f *zdate; { char line[DATELEN]; sprdate(zdate, line); /* have the formatter do stuff to it */ printf("%s", line); /* and print the thing */ }