home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume13 / conf / part01 / conf.c next >
C/C++ Source or Header  |  1988-03-13  |  11KB  |  487 lines

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