home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume16 / conf2 / part01 / conf.c next >
Encoding:
C/C++ Source or Header  |  1988-09-14  |  11.4 KB  |  559 lines

  1. #include "conf.h"
  2.         /* Talk, talk ... it's all talk! */
  3.  
  4. char *progname;                    /* program name (argv[0]) */
  5. char *logname, *homedir;
  6.  
  7. int lfd, log_rfd, log_wfd, usr_fd;
  8. long ourplace;
  9. FILE *rec_fp;
  10. int confing = FALSE;
  11.  
  12. char replyname[MAXNAMELEN] = "";
  13. char replytty[MAXTTYLEN+1] = "";    /* there is a reason for the + 1
  14.                         although I have forgotten it
  15.                         right now, I'm sure it should
  16.                         be there.
  17.                      */
  18.  
  19. char *wrdata;
  20. unsigned wdlen=0;
  21.  
  22. struct cusrfil cuser, tuser;
  23. struct clogfil clog, tlog;
  24.  
  25. #ifdef    SYSV
  26. struct termio term, saveterm;
  27. #endif    SYSV
  28.  
  29. #ifdef    BSD
  30. struct tchars chrstr;
  31. struct sgttyb ktty;
  32. int ttyflags;
  33. #endif    BSD
  34.  
  35. char ichar = CTRL('C');                /* interrupt character */
  36. char qchar = CTRL('\\');            /* quit character */
  37.  
  38. jmp_buf env;
  39.  
  40. int columns = 80, lines = 24, banner = TRUE, seeme = TRUE, informe = FALSE,
  41.     lineinput = FALSE, beep = FALSE, expand8bit = TRUE, expandctrl = TRUE;
  42.  
  43. char *cls = NULL, *pager, *shell, *normform, *lineform, *shoutform, *sendform,
  44.     *informform, *recfile;
  45.  
  46. my_int()
  47. {
  48.     longjmp(env, 1);
  49. }
  50.  
  51. #ifdef BSD
  52. stopit()
  53. {
  54.     ktty.sg_flags = ttyflags;
  55.     stty(0, &ktty);
  56.     (void) signal(SIGTSTP, SIG_DFL);
  57.     (void) kill(0, SIGTSTP);
  58.     gtty(0, &ktty);
  59.     ttyflags = ktty.sg_flags;
  60.  
  61.     if (!(ttyflags&ECHO))
  62.     lineinput = TRUE;
  63.  
  64.     ktty.sg_flags |= CBREAK;
  65.     ktty.sg_flags &= ~ECHO;
  66.     stty(0, &ktty);
  67.  
  68.     (void) ioctl(0, TIOCGETC, &chrstr);
  69.     
  70.     ichar = chrstr.t_intrc;
  71.     qchar = chrstr.t_quitc;
  72.     (void) signal(SIGTSTP, stopit);
  73. }
  74. #endif BSD
  75.  
  76. main(argc, argv)
  77. int argc;
  78. char *argv[];
  79. {
  80.     char *ptr, *word, *line, answer;
  81.     int num, x, c, old_umask, rotten_egg;
  82.     struct passwd *pt;
  83.  
  84.     progname = *argv++; --argc; 
  85.  
  86.     /* Open all support files */
  87.  
  88.     old_umask = umask(0);
  89.  
  90.     x = 0;
  91.     while ((lfd = open(CONFLOCK, O_CREAT|O_EXCL, 0666)) < 0)
  92.     {
  93.     if (++x > 60)        /* looks like the lock file may be hosed */
  94.     {
  95.         printf("The lock file %s looks like it is wedged.\n", CONFLOCK);
  96.         printf("What should I do; (A)bort, (C)ontinue, or (R)emove? ");
  97.  
  98.         answer = 'a';
  99.  
  100.         while (((c = getchar()) != '\n') && (c != CR))
  101.         {
  102.         switch(c)
  103.         {
  104.         case 'a':
  105.         case 'A':
  106.         case 'C':
  107.         case 'c':
  108.         case 'R':
  109.         case 'r':
  110.             answer = c;
  111.             break;
  112.  
  113.         default:
  114.             printf("\n(A)bort, (C)ontinue, or (R)emove? ");
  115.             break;
  116.         }
  117.         }
  118.         
  119.         switch(answer)
  120.         {
  121.         case 'a':
  122.         case 'A':
  123.         (void) umask(old_umask);
  124.         exit(-1);
  125.  
  126.         case 'c':
  127.         case 'C':
  128.         x = 0;
  129.         continue;
  130.  
  131.         case 'r':
  132.         case 'R':
  133.         (void) unlink(CONFLOCK);
  134.         continue;
  135.         }
  136.  
  137.         sleep(1);
  138.     }
  139.     }
  140.  
  141.     close(lfd);
  142.  
  143.     if ((usr_fd = open(CONFUSERS, O_RDWR|O_CREAT, FILEMASK)) < 0)
  144.     {
  145.     (void) fprintf(stderr, "%s: couldn't open %s (%s)\n", progname,
  146.                CONFUSERS, puterr(errno));
  147.     (void) exit(-1);
  148.     }
  149.  
  150.     (void) lseek(usr_fd, 0L, 0);
  151.  
  152.     if ((argc == 1) && (!strcmp(*argv, "-T")))
  153.     {
  154.     (void) lseek(usr_fd, 0L, 0);
  155.  
  156. #ifdef    SYSV
  157.     lockf(usr_fd, F_LOCK, 0L);    /* lock user file */
  158. #endif    SYSV
  159.  
  160. #ifdef    BSD
  161.     flock(usr_fd, LOCK_EX);
  162. #endif    BSD
  163.  
  164.     rotten_egg = TRUE;
  165.     while (read(usr_fd, (char *)&tuser, sizeof(struct cusrfil)) ==
  166.            sizeof(struct cusrfil))
  167.         if (tuser.cu_flags != USER_OFF)
  168.         {
  169.         c = kill(tuser.cu_procid, 0);
  170.         if ((!c) || ((c < 0) && (errno != ESRCH)))
  171.             rotten_egg = FALSE;
  172.         }
  173.  
  174. #ifdef    SYSV
  175.     (void) lseek(usr_fd, 0L, 0);
  176.     lockf(usr_fd, F_ULOCK, 0L);
  177. #endif    SYSV
  178.  
  179. #ifdef    BSD
  180.     flock(usr_fd, LOCK_UN);
  181. #endif    BSD
  182.  
  183.     if (rotten_egg)
  184.     {
  185.         close(usr_fd);
  186.         open(CONFLOG, O_TRUNC);
  187.         open(CONFUSERS, O_TRUNC);
  188.     }
  189.  
  190.     unlink(CONFLOCK);
  191.     exit(0);
  192.     }
  193.  
  194.     if ((log_wfd = open(CONFLOG, O_WRONLY|O_CREAT|O_APPEND, FILEMASK)) < 0)
  195.     {
  196.     (void) fprintf(stderr,"%s: couldn't create/open %s for writing(%s)\n",
  197.                progname, CONFLOG, puterr(errno));
  198.     (void) exit(-1);
  199.     }
  200.  
  201.     (void) umask(old_umask);
  202.  
  203.     if ((log_rfd = open(CONFLOG, O_RDONLY)) < 0)
  204.     {
  205.     (void) fprintf(stderr,"%s: couldn't open %s for reading (%s)\n",
  206.                progname, CONFLOG, puterr(errno));
  207.     (void) exit(-1);
  208.     }
  209.  
  210.     unlink(CONFLOCK);
  211.  
  212.     setuid(getuid());
  213.  
  214.     (void) lseek(log_rfd, 0L, 2);
  215.  
  216.     /* set up some pointers to interesting stuff */
  217.  
  218.     wrdata = mymalloc(wdlen = PAGESIZ);
  219.  
  220.     cuser.cu_line = 1;
  221.     cuser.cu_flags = USER_ON;
  222.     cuser.cu_procid = getpid();
  223.  
  224.     pt = getpwuid(getuid());
  225.  
  226.     if ((ptr = getlogin()) == NULL)
  227.     if ((ptr = pt->pw_name) == NULL)
  228.         ptr = "somebody";        /* can't figure this guy out */
  229.  
  230.     logname = mymalloc((unsigned)(strlen(ptr)+1));
  231.     (void) strcpy(logname, ptr);
  232.  
  233.     (void) strcpy(cuser.cu_cname, ptr);
  234.  
  235.     if ((ptr = ttyname(0)) == NULL)
  236.     strcpy(cuser.cu_tty, "tty??");
  237.     else
  238.     strcpy(cuser.cu_tty, ((ptr= strrchr(ptr, '/')) ? ptr+1 : "tty??"));
  239.  
  240.     homedir = mymalloc((unsigned)(strlen(pt->pw_dir)+1));
  241.     (void) strcpy(homedir, pt->pw_dir);
  242.  
  243.     cls = mymalloc((unsigned)1);
  244.     *cls = '\0';
  245.  
  246.     normform = mymalloc((unsigned)(sizeof(DEF_FORM_NORM)));
  247.     (void) strcpy(normform, DEF_FORM_NORM);
  248.  
  249.     sendform = mymalloc((unsigned)(sizeof(DEF_FORM_SEND)));
  250.     (void) strcpy(sendform, DEF_FORM_SEND);
  251.  
  252.     shoutform = mymalloc((unsigned)(sizeof(DEF_FORM_SHOUT)));
  253.     (void) strcpy(shoutform, DEF_FORM_SHOUT);
  254.  
  255.     informform = mymalloc((unsigned)(sizeof(DEF_FORM_INFORM)));
  256.     (void) strcpy(informform, DEF_FORM_INFORM);
  257.  
  258.     lineform = mymalloc((unsigned)(sizeof(DEF_FORM_LINE)));
  259.     (void) strcpy(lineform, DEF_FORM_LINE);
  260.  
  261.     pager = mymalloc((unsigned)(sizeof(DEF_PAGER)));
  262.     (void) strcpy(pager, DEF_PAGER);
  263.  
  264.     shell = mymalloc((unsigned)(sizeof(DEF_SHELL)));
  265.     (void) strcpy(shell, DEF_SHELL);
  266.  
  267.     recfile = mymalloc((unsigned)(sizeof(DEF_RECFILE)));
  268.     (void) strcpy(recfile, DEF_RECFILE);
  269.  
  270.     gettcap();            /* get termcap stuff */
  271.     getrc();            /* get some defaults from rc file */
  272.     getopts();            /* get some defaults from environment */
  273.  
  274.     while (word = *argv++, argc--)
  275.     {
  276.     if (*word == '-')
  277.     {
  278.        word++;
  279.  
  280.        while (*word != '\0')
  281.        {
  282.            switch(*word++)
  283.            {
  284.            case 'T':
  285.            printf("%s: -T wasn't specified by itself.  Ignoring...\n",
  286.               progname);
  287.  
  288.            case 'l':
  289.            if (*word == '\0')
  290.            {
  291.                if (!argc)
  292.                {
  293.                (void) printf("%s: -l switch specified without a conference line number\n",
  294.                      progname);
  295.                usage();
  296.                }
  297.                word = *argv++; --argc;
  298.            }
  299.  
  300.            num = atoi(word);
  301.            if ((num < 1) || (num > MAXCONFLINES))
  302.            {
  303.               (void) printf("%s: invalid conference line number: %d\n",
  304.                     progname, num);
  305.               usage();
  306.           }
  307.            cuser.cu_line = num;
  308.            *word = '\0';
  309.            break;
  310.  
  311.            case 's':
  312.            if (*word == '\0')
  313.            {
  314.                if (!argc)
  315.                {
  316.                (void) fprintf(stderr,
  317.                       "%s: -s specified without a parameter\n",
  318.                       progname);
  319.                usage();
  320.                }
  321.                word = *argv++; --argc;
  322.            }
  323.  
  324.            if ((x = setopts(parsestr(word, strlen(word), NEXTWORD)))
  325.                != FOUNDOPT)
  326.            {
  327.                char *errmess;
  328.  
  329.                if (x == AMBIGUOUS)
  330.                errmess = "Ambiguous";
  331.                else
  332.                errmess = "Invalid";
  333.                 
  334.                (void) fprintf(stderr, "%s: %s -s parameter: %s\n",
  335.                       progname, errmess, word);
  336.                usage();
  337.            }
  338.            *word = '\0';
  339.            break;
  340.  
  341.            case 'w':
  342.            (void) do_who(0);
  343.            (void) exit(0);
  344.  
  345.            default:
  346.            (void)fprintf(stderr, "%s: invalid parameter '%c'\n",
  347.                  progname, *(word-1));
  348.            usage();
  349.            }
  350.        }
  351.        }
  352.     else
  353.         (void) do_ring(word);
  354.     }
  355.  
  356.     /* by this point, all parameters/options have been parsed */
  357.  
  358.     confing = TRUE;
  359.  
  360.     clog.f_line = cuser.cu_line;
  361.     clog.f_usrlen = strlen(cuser.cu_cname) + 1;
  362.     clog.f_ttylen = strlen(cuser.cu_tty) + 1;
  363.  
  364.     (void) lseek(usr_fd, 0L, 0);
  365.  
  366. #ifdef    SYSV
  367.     lockf(usr_fd, F_LOCK, 0L);    /* lock user file */
  368. #endif    SYSV
  369.  
  370. #ifdef    BSD
  371.     flock(usr_fd, LOCK_EX);
  372. #endif    BSD
  373.  
  374.     ourplace = lseek(usr_fd, 0L, 1);
  375.     while (read(usr_fd, (char *)&tuser, sizeof(struct cusrfil)) ==
  376.     sizeof(struct cusrfil))
  377.     if (tuser.cu_flags == USER_OFF)
  378.         break;
  379.     else
  380.         ourplace = lseek(usr_fd, 0L, 1);
  381.  
  382.     (void) lseek(usr_fd, ourplace, 0);
  383.  
  384.     write(usr_fd, (char *)&cuser, sizeof(struct cusrfil));
  385.  
  386. #ifdef    SYSV
  387.     (void) lseek(usr_fd, 0L, 0);
  388.     lockf(usr_fd, F_ULOCK, 0L);
  389. #endif    SYSV
  390.  
  391. #ifdef    BSD
  392.     flock(usr_fd, LOCK_UN);
  393. #endif    BSD
  394.  
  395.     /* any fatal errors pass this point must do a nice_exit(status) */
  396.  
  397.     write_log(INFORM, "Login", (char *)NULL, 0, (unsigned)strlen("Login"));
  398.  
  399. #ifdef    SYSV
  400.     (void) ioctl(0, TCGETA, &term);
  401.     saveterm=term;
  402.  
  403.     if (!(term.c_lflag&ECHO))
  404.     lineinput = TRUE;
  405.  
  406.     ichar = term.c_cc[VINTR];
  407.     qchar = term.c_cc[VQUIT];
  408.  
  409.     term.c_iflag &= ~(ICRNL);
  410.     term.c_lflag &= ~(ICANON|ECHO);
  411.     term.c_cc[VEOF] = 1;
  412.     term.c_cc[VEOL] = 0;
  413.     (void) ioctl(0, TCSETAW, &term);
  414.     
  415. #endif    SYSV
  416.  
  417. #ifdef    BSD
  418.     gtty(0, &ktty);
  419.     ttyflags = ktty.sg_flags;
  420.  
  421.     if (!(ttyflags&ECHO))
  422.     lineinput = TRUE;
  423.  
  424.     ktty.sg_flags |= CBREAK;
  425.     ktty.sg_flags &= ~ECHO;
  426.     stty(0, &ktty);
  427.  
  428.     (void) ioctl(0, TIOCGETC, &chrstr);
  429.     
  430.     ichar = chrstr.t_intrc;
  431.     qchar = chrstr.t_quitc;
  432. #endif    BSD
  433.  
  434.     (void) signal(SIGINT, SIG_IGN);
  435.     (void) signal(SIGQUIT, fatal);
  436.     (void) signal(SIGHUP, nice_exit);
  437.     (void) signal(SIGTERM, nice_exit);
  438.     (void) signal(SIGILL, fatal);
  439.     (void) signal(SIGTRAP, fatal);
  440.     (void) signal(SIGIOT, fatal);
  441.     (void) signal(SIGEMT, fatal);
  442.     (void) signal(SIGFPE, fatal);
  443.     (void) signal(SIGBUS, fatal);
  444.     (void) signal(SIGSEGV, fatal);
  445.     (void) signal(SIGSYS, fatal);
  446.     (void) signal(SIGPIPE, fatal);
  447.  
  448. #ifdef SIGTSTP
  449.     (void) signal(SIGTSTP, stopit);
  450. #endif SIGTSTP
  451.  
  452.     if (banner)
  453.     (void) version(FALSE);
  454.  
  455.     (void) printf("login user %s (%s) on conference line %d\n",
  456.           cuser.cu_cname, cuser.cu_tty, cuser.cu_line);
  457.  
  458.     if (setjmp(env))
  459.     {
  460.     (void) signal(SIGINT, my_int);
  461.     dispchar(ichar, stdout, NOVIS);
  462.     (void) putchar('\n');
  463.     (void) lseek(log_rfd, 0L, 2);
  464.     }
  465.     else
  466.     (void) signal(SIGINT, my_int);
  467.  
  468.     forever
  469.     {
  470.     read_log();
  471.  
  472.     fflush(stdout);        /* damnit */
  473.     line = getline();
  474.     (void) signal(SIGINT, my_int);
  475.     if (line != NULL)
  476.     {
  477.         if ((*line == ':') && (*(line+1) != ':'))
  478.         {
  479.             if (*(line+1) == '!')
  480.             keep_shell(line+2);
  481.         else
  482.         {
  483.             --linelen;
  484.             (void) intpret(line+1);
  485.         }
  486.         }
  487.         else
  488.         {
  489.         if (*line == ':')
  490.             write_log(NORMAL, line+1, (char *)NULL, 0, linelen-1);
  491.         else
  492.             write_log(NORMAL, line, (char *)NULL, 0, linelen);
  493.         }
  494.         free(line);
  495.     }
  496.     }
  497. }
  498.  
  499. nice_exit(status)
  500. int status;
  501. {
  502.     make_nice(TRUE);
  503.  
  504.     (void) signal(SIGALRM, SIG_DFL);
  505.     (void) signal(SIGINT, SIG_DFL);
  506.     (void) signal(SIGQUIT, SIG_DFL);
  507.     (void) signal(SIGHUP, SIG_DFL);
  508.     (void) signal(SIGTERM, SIG_DFL);
  509.     (void) signal(SIGILL, SIG_DFL);
  510.     (void) signal(SIGTRAP, SIG_DFL);
  511.     (void) signal(SIGIOT, SIG_DFL);
  512.     (void) signal(SIGEMT, SIG_DFL);
  513.     (void) signal(SIGFPE, SIG_DFL);
  514.     (void) signal(SIGBUS, SIG_DFL);
  515.     (void) signal(SIGSEGV, SIG_DFL);
  516.     (void) signal(SIGSYS, SIG_DFL);
  517.     (void) signal(SIGPIPE, SIG_DFL);
  518.  
  519.     (void) exit(status);
  520. }
  521.  
  522. make_nice(status)
  523. int status;
  524. {
  525.     (void) alarm(0);
  526.  
  527.     if (status)
  528.     write_log(INFORM,"Logout",(char *)NULL,0, (unsigned)strlen("Logout"));
  529.  
  530.     if (cuser.cu_flags&USER_RECORD)
  531.     (void)fclose(rec_fp);
  532.  
  533.     cuser.cu_flags = USER_OFF;
  534.     write_usr();
  535.  
  536.     (void) close(usr_fd);
  537.     (void) close(log_rfd);
  538.     (void) close(log_wfd);
  539.  
  540. #ifdef    SYSV
  541.     (void) ioctl(0, TCSETAW, &saveterm);
  542. #endif    SYSV
  543.  
  544. #ifdef    BSD
  545.     ktty.sg_flags = ttyflags;
  546.     stty(0, &ktty);
  547. #endif    BSD
  548.  
  549.     execlp(progname, progname, "-T", (char *)0);
  550. }
  551.  
  552. usage()
  553. {
  554.     (void) fprintf(stderr,
  555.            "usage: %s [-T][-w][-s switchname][-l line-number]\n",
  556.            progname);
  557.     (void) exit(-1);
  558. }
  559.