home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume4 / unaxcess / part2 / sys.c < prev   
Encoding:
C/C++ Source or Header  |  1986-11-30  |  8.0 KB  |  409 lines

  1. /*
  2.  * %W% %E% %U% ncoast!bsa %Z%
  3.  * %Z% Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved %Z%
  4.  */
  5.  
  6. #ifndef lint
  7. static char _SccsId[] = "%W% %E% %U% ncoast!bsa %Z%";
  8. static char _CopyRt[] = "%Z% Copyright (C) 1985 by Brandon S. Allbery %Z%";
  9. #endif  lint
  10.  
  11. #include "ua.h"
  12.  
  13. static FILE *lfp;
  14.  
  15. short critical = 0;
  16.  
  17. short quitc = 0;
  18. short intr = 0;
  19. short alrm = 0;
  20.  
  21. short shhh = 0;
  22.  
  23. short warned = 0;
  24.  
  25. #ifdef SYS3
  26. #include <sys/ioctl.h>
  27. #include <termio.h>
  28. struct termio mode;
  29. #else
  30. #include <sgtty.h>
  31. #ifndef V7
  32. #include <sys/ioctl.h>
  33. #endif
  34. struct sgttyb mode;
  35. #endif
  36.  
  37. logon()
  38.     {
  39.     struct stat sb;
  40.     char *cp;
  41.     char *getenv();
  42.  
  43.         /* first set up ttymode structure */
  44. #ifdef SYS3
  45.     ioctl(0, TCGETA, &mode);
  46. #else
  47. #ifdef V7
  48.     gtty(0, &mode);
  49. #else
  50.     ioctl(0, TIOCGETP, &mode);
  51. #endif
  52. #endif
  53.  
  54.     if (parms.ua_env) {
  55.         if ((cp = getenv("SHELL")) != NULL)
  56.             strcpy(parms.ua_shell, cp);
  57.         if ((cp = getenv("EDITOR")) != NULL)
  58.             strcpy(parms.ua_edit, cp);
  59.     }
  60.     
  61.     if (!parms.ua_log || stat(LOG, &sb) < 0)        /* no logfile => no logging */
  62.     {
  63.     lfp = NULL;
  64.     return;
  65.     }
  66.     if ((lfp = fopen(LOG, "a")) == NULL)
  67.     {
  68.     perror(LOG);
  69.     puts("panic: log");
  70.     exit(2);
  71.     }
  72.     }
  73.  
  74. log(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
  75.     char *fmt, *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9;
  76.     {
  77.     char buf[1024];
  78.     static char lockfile[] = "logfile.lock";
  79.  
  80.     if (lfp == NULL)            /* logging not enabled */
  81.     return;
  82.     CRIT();
  83.     sprintf(buf, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
  84.     mklock(lockfile);
  85.     fprintf(lfp, "%s (%05d)  %s\n", date(), getpid(), visible(buf));
  86.     fflush(lfp);
  87.     rmlock(lockfile);
  88.     NOCRIT();
  89.     }
  90.  
  91. logsig(sig)
  92.     int sig;
  93.     {
  94.     log("Received signal %d.", sig);
  95.     panic("signal");
  96.     }
  97.  
  98. panic(s)
  99.     char *s;
  100.     {
  101.     log("panic: %s", s);
  102.     fprintf(stderr, "panic: %s\n", s);
  103.     unlink(RIndex(ttyname(2), '/') + 1);
  104.     exit(1);
  105.     }
  106.  
  107. quit()
  108.     {
  109.     char line[256];
  110.  
  111.     if (critical) {
  112.         quitc++;
  113.         return;
  114.     }
  115.     puts("\n\nFast logout\n");
  116.     signal(SIGQUIT, quit);
  117.     log("Signalled QUIT.");
  118.     printf("\nDo you really want to leave UNaXcess (N)? ");
  119.     gets(line);
  120.     if (ToLower(line[0]) == 'y')
  121.     {
  122.     printf("OK, %s.  See you later!\n\n\n", user.u_name);
  123.     cleanup();
  124.     }
  125.     }
  126.  
  127. intrp()
  128.     {
  129.     if (critical) {
  130.         intr++;
  131.         return;
  132.     }
  133.     puts("\n\nAborted.");
  134.     log("Command aborted.");
  135.     signal(SIGINT, intrp);
  136.     longjmp(cmdloop, 1);
  137.     }
  138.  
  139. char *visible(s)
  140.     char *s;
  141.     {
  142.     static char vs[256];
  143.     char *sp, *vp;
  144.  
  145.     vp = vs;
  146.     for (sp = s; *sp != '\0'; sp++)
  147.     if (!iscntrl(*sp))
  148.         *vp++ = *sp;
  149.     else
  150.         {
  151.         *vp++ = '^';
  152.         *vp++ = uncntrl(*sp);
  153.         }
  154.     *vp = '\0';
  155.     return vs;
  156.     }
  157.  
  158. shell()
  159.     {
  160.     short sig;
  161.     unsigned altime;
  162.  
  163.     if (user.u_access == A_GUEST || user.u_access == A_USER || parms.ua_shell[0] == '\0')
  164.     {
  165.     puts("You don't have shell access privileges.");
  166.     log("Security violation:  Unauthorized SHELL");
  167.     return 1;
  168.     }
  169.     switch (fork())
  170.     {
  171.     case -1:
  172.         log("Error %d forking shell", errno);
  173.         puts("Sorry, the system's full.  Try again later.");
  174.         return 1;
  175.     case 0:
  176.         for (sig = 2; sig < SIGUSR1; sig++)
  177.         signal(sig, SIG_DFL);
  178.         setuid(getuid());
  179.         chdir(getpwuid(getuid())->pw_dir);
  180.         run(parms.ua_shell, 0);
  181.         log("Error %d exec'ing %s", errno, parms.ua_shell);
  182.         puts("Couldn't run the shell.");
  183.         exit(1);
  184.     default:
  185.         CRIT();
  186.         for (sig = 2; sig < SIGUSR1; sig++)
  187.         signal(sig, SIG_IGN);
  188.         signal(SIGALRM, thatsall);    /* trapped by the CRIT() */
  189.         wait(NULL);
  190.         signal(SIGINT, intrp);
  191.         signal(SIGQUIT, quit);
  192.         for (sig = 4; sig < SIGUSR1; sig++)
  193.         signal(sig, logsig);
  194.         signal(SIGALRM, thatsall);
  195.         NOCRIT();
  196.     }
  197.     return 1;
  198.     }
  199.  
  200. thatsall()
  201.     {
  202.     if (critical) {
  203.         alrm++;
  204.         return;
  205.     }
  206.     if (warned) {
  207.         log("Timeout.");
  208.         puts("\nI'm sorry, but you're out of time.\n\n");
  209.         cleanup();
  210.         }
  211.     else 
  212.         {
  213.         log("5-minute warning.");
  214.         puts("\nYou have only five minutes left in this session.\n\n");
  215.         warned = 1;
  216.         alarm(5 * 60);
  217.         }
  218.     }
  219.  
  220. /*
  221.  * I've had problems with this.  If it breaks, delete the innards of the lock
  222.  * functions.  Hopefully, I got it right this time...
  223.  */
  224.  
  225. mklock(lockfile)
  226. char *lockfile; {
  227.     char lockpath[50];
  228.     int lock_fd;
  229.     struct stat statbuf;
  230.     
  231. /*  strcpy(lockpath, "lock/"); */  /* jpn - install did not create lock/ */
  232.     strcpy(lockpath, lockfile);
  233.     while (stat(lockpath, &statbuf) == 0)
  234.         if (statbuf.st_atime > 60) {
  235.             unlink(lockpath);
  236.             break;
  237.         }
  238.     if ((lock_fd = creat(lockpath, 0600)) < 0) {
  239.         fprintf(stderr, "Errno = %d creating lockfile %s\n", errno, lockpath);
  240.         exit(-1);
  241.     }
  242.     close(lock_fd);
  243. }
  244.  
  245. rmlock(lockfile)
  246. char *lockfile; {
  247.     char lockpath[50];
  248.     struct stat statbuf;
  249.     
  250. /*  strcpy(lockpath, "lock/"); */  /* jpn - install did not create lock/ */
  251.     strcpy(lockpath, lockfile);
  252.     if (stat(lockpath, &statbuf) < 0) {
  253.         log("Lockfile %s deleted???", lockpath);
  254.         printf("\n\nSomeone futzed with the lockfile.  Please tell %s IMMEDIATELY!!!\nSorry, but this means I have to log you out now.\n\n", parms.ua_sysop);
  255.         panic("LOCKFILE DELETED");
  256.     }
  257.     if (unlink(lockpath) < 0) {
  258.         log("Errno = %d, can't unlink lockfile %s", errno, lockpath);
  259.         puts("\nI've got a lockfile problem.  You won't be able to do some\nthings until it's fixed.  Sorry...\n");
  260.     }
  261. }
  262.  
  263. xedit(file)
  264.     char *file;
  265.     {
  266.     short sig;
  267.     unsigned altime;
  268.  
  269.     if (user.u_access == A_GUEST || user.u_access == A_USER || parms.ua_edit[0] == '\0')
  270.     {
  271.     puts("You don't have shell access privileges.");
  272.     log("Security violation:  Unauthorized XEDIT");
  273.     return 1;
  274.     }
  275.     if (strcmp(parms.ua_edit, "ua-edit") == 0) {
  276.         edit(file);
  277.         return 1;
  278.     }
  279.     switch (fork())
  280.     {
  281.     case -1:
  282.         log("Error %d forking shell", errno);
  283.         puts("Sorry, the system's full.  Using the line editor...");
  284.         edit(file);
  285.         return 1;
  286.     case 0:
  287.         for (sig = 2; sig < SIGUSR1; sig++)
  288.         signal(sig, SIG_DFL);
  289.         setuid(getuid());
  290.         chdir(getpwuid(getuid())->pw_dir);
  291.         run(parms.ua_edit, file);
  292.         log("Error %d exec'ing %s", errno, parms.ua_edit);
  293.         puts("Couldn't run the editor; using the line editor...");
  294.         edit(file);
  295.         exit(0);
  296.     default:
  297.         CRIT();
  298.         for (sig = 2; sig < SIGUSR1; sig++)
  299.         signal(sig, SIG_IGN);
  300.         signal(SIGALRM, thatsall);
  301.         wait(NULL);
  302.         signal(SIGINT, intrp);
  303.         signal(SIGQUIT, quit);
  304.         for (sig = 4; sig < SIGUSR1; sig++)
  305.         signal(sig, logsig);
  306.         signal(SIGALRM, thatsall);
  307.         NOCRIT();
  308.     }
  309.     return 1;
  310.     }
  311.  
  312. CRIT() {
  313.     alrm = 0;
  314.     quitc = 0;
  315.     intr = 0;
  316.     if (critical)
  317.         return;    /* clears pending signals */
  318.     critical = 1;
  319. }
  320.  
  321. NOCRIT() {
  322.     if (!critical)
  323.         return;
  324.     critical = 0;
  325.     if (alrm)
  326.         thatsall(14);
  327.     if (quitc)
  328.         quit(3);
  329.     if (intr)
  330.         intrp(2);
  331.     alrm = 0;
  332.     quitc = 0;
  333.     intr = 0;
  334. }
  335.  
  336. run(cmd, arg)
  337. char *cmd, *arg; {
  338.     char cmdbuf[5120];
  339.     
  340.     sprintf(cmdbuf, "%s %s", cmd, (arg? arg: ""));
  341.     execl("/bin/sh", "sh", "-c", cmdbuf, 0);
  342.     return -1;
  343. }
  344.  
  345. silent() {
  346.     if (shhh)
  347.         return;
  348. #ifdef SYS3
  349.     mode.c_lflag &= ~(ICANON|ISIG|ECHO|ECHOE|ECHOK);
  350.     mode.c_cc[VMIN] = 1;
  351.     mode.c_cc[VTIME] = 0;
  352.     ioctl(0, TCSETAW, &mode);
  353. #else
  354.     mode.sg_flags |= CBREAK;
  355.     mode.sg_flags &= ~ECHO;
  356. #ifdef V7
  357.     stty(0, &mode);
  358. #else
  359.     ioctl(0, TIOCSETP, &mode);
  360. #endif
  361. #endif
  362.     shhh = 1;
  363. }
  364.  
  365. talk() {
  366.     if (!shhh)
  367.         return;
  368. #ifdef SYS3
  369.     mode.c_lflag |= (ICANON|ISIG|ECHO|ECHOE|ECHOK);
  370.     mode.c_cc[VEOF] = CEOF;
  371.     mode.c_cc[VEOL] = CNUL;
  372.     ioctl(0, TCSETAW, &mode);
  373. #else
  374.     mode.sg_flags |= ECHO;
  375.     mode.sg_flags &= ~CBREAK;
  376. #ifdef V7
  377.     stty(0, &mode);
  378. #else
  379.     ioctl(0, TIOCSETP, &mode);
  380. #endif
  381. #endif
  382.     shhh = 0;
  383. }
  384.  
  385. copylink(src, dest)
  386. char *src, *dest; {
  387.     int srcp, destp, cnt;
  388.     char buf[1024];
  389.     
  390.     if (link(src, dest) == 0) {
  391.         unlink(src);
  392.         return 0;
  393.     }
  394.     if ((srcp = open(src, 0)) < 0) {
  395.         perror(src);
  396.         return -1;
  397.     }
  398.     unlink(dest);
  399.     if ((destp = creat(dest, 0600)) < 0) {
  400.         perror(dest);
  401.         return -1;
  402.     }
  403.     while ((cnt = read(srcp, buf, sizeof buf)) > 0)
  404.         write(destp, buf, cnt);
  405.     close(destp);
  406.     close(srcp);
  407.     return 0;
  408. }
  409.