home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume10 / multitalk / multitalk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-13  |  36.5 KB  |  1,362 lines

  1. /***********************************************
  2.  * 
  3.  * MultiTalk - Talk Parlour
  4.  * Multi-user Conferencing Program.
  5.  *
  6.  * Written and Developed by Albert Viall
  7.  * WARNING: Do not remove this header or alter it
  8.  *  in anyway. By releasing this source code into
  9.  *  public domain, the author allows minor changes
  10.  *  to the source code to suit the needs of the
  11.  *  user.
  12.  * 
  13.  * (C)1989
  14.  * All Rights Reserved
  15.  **********************************************/
  16.  
  17.  
  18. #include <stdio.h>
  19. #include <ctype.h>
  20. #include <errno.h>
  21. #include <signal.h>
  22. #include <sgtty.h>
  23. #include <assert.h>
  24. #include <sys/file.h> 
  25. #include <sys/time.h> 
  26. #include "multitalk.h"
  27.  
  28. #define BELL '\007'
  29. #define WRITELOCAL "m_local"
  30. #define WRITEALL   "m_all"
  31. #define SENDLOCAL  "s_local"
  32. #define SENDALL    "s_all"
  33. #define WHISPER    "m_whisper"
  34. #define SENDTO       "s_to"
  35.  
  36. char name[40],*myroom,myfile[35];
  37. char prompt[8];
  38. int yellcnt,mypid,echo,master;
  39.  
  40. /* Global structure used for loginfile
  41.  * If you add or delete any login parameters, it must be
  42.  * done here first
  43.  */
  44. struct logon {
  45.     char thetty[12]; /* tty filename, i.e. /dev/ttyi34  */
  46.     char uid_name[8]; /* the system login name */
  47.     char logon_name[40]; /* Mtalk login name */
  48.     char room[11]; /* current room */
  49.     int thepid; /* this structures pidnumber */
  50.     } logon_info[MAXUSERS]; /* MAXUSERS is defined in multitalk.h */
  51. int    cleanup();
  52.  
  53. main()
  54. {
  55.     int x,z,y;
  56.     char str[256],junk[9],*myname,*getlogin(),*mytty,*ttyname();  
  57.  
  58.     /* Perform a tidy cleanup upon signal.
  59.      * Thank you for keeping your area clean.
  60.      */ 
  61.     signal(SIGHUP,cleanup);
  62.     signal(SIGINT,cleanup);
  63.     security("compare",junk);  /* Am I in the purgefile? */
  64.     master=0;
  65.     mypid=getpid();
  66.     myname=getlogin();
  67.     mytty=ttyname(fileno(stdin));
  68.     /* set global 'myfile' to search for my commfile */
  69.     sprintf(myfile,"%s%d\0",PATH,mypid);  
  70.     fopen(myfile,"a");  /* Open my commfile just to make sure its there */
  71.     do_login();  
  72.         sprintf(str,"### %s was just escorted into the Talk Parlour on %s.",&name,mytty);
  73.     mwrite(SENDALL,"",str);
  74.     get_comfile(); 
  75.     do_message(myname,"read");
  76.     yellcnt=0;
  77.     echo=1;
  78.     sprintf(prompt,"Say? \0"); /* set default input prompt */
  79.     
  80.  
  81.     /* main processing - things branch from here */
  82.     for(;;) {
  83.                 str[0]='\0';
  84.         printf("%s",prompt);
  85.         gets(str);
  86.         
  87.         get_room();
  88.         /* is str a command? */
  89.         if (str[0]=='/') {
  90.             parse_cmd(str);
  91.             get_comfile();
  92.             continue;
  93.                 }
  94.  
  95.         /* did I input regular text? */
  96.         if (strlen(str) != 0) {
  97.             mwrite(WRITELOCAL,"",str);
  98.             get_comfile();
  99.             continue;  
  100.                 }  
  101.         /* or did I hit a c/r */
  102.         if (strlen(str) == 0) {
  103.             get_comfile();
  104.             continue;
  105.             }
  106.  
  107.  
  108.         } /* end of main processing */
  109. } /* NOTREACHED */
  110.  
  111. char     *
  112. date()  /* returns date and time in the 26 character format */
  113. {
  114.     long t;
  115.     register char *s;
  116.     char *ctime();
  117.  
  118.     time(&t);
  119.     s=ctime(&t);
  120.     return s;
  121. }
  122.  
  123. void init_flds()
  124. {  
  125.     int t;
  126.     
  127.     /* This should be the first function to be called whenever a new
  128.      * set of fields are incorporated into the array. It will
  129.      * Initialize the entire array.
  130.      */
  131.     for (t=0; t<MAXUSERS; t++) {
  132.         logon_info[t].thetty[0]='\0';
  133.         logon_info[t].uid_name[0]='\0';
  134.         logon_info[t].logon_name[0]='\0';
  135.         logon_info[t].room[0]='\0';
  136.         } 
  137. }
  138.  
  139.  
  140. do_login()
  141. {
  142.     /* This function performs all entry duties into the parlour
  143.      * such as name input, status_display, and adding this entry
  144.      * to the loginfile.
  145.      */ 
  146.     int z;
  147.     FILE *lgnfd;
  148.     char *ttyname(), *getlogin(), *mytty, *myname,*room;
  149.     char byname[40],text[230];
  150.     int accessible; 
  151.  
  152.     mytty=ttyname(fileno(stdin));
  153.     myname=getlogin();
  154.     check_max(); /* check on how many slots are being used */ 
  155.     /* Test access of lockfile and exit if found after user notify */
  156.     if ((strcmp(myname,HEADMOO)==0)) goto bypass; /* Icck! I hate goto's */
  157.     if ((accessible=access(LOCKFIL, 0))== 0) {
  158.                      putchar(BELL);
  159.             printf("\n\nThe Task has been locked from further entry by the Caretaker.");
  160.             printf("\nFor further information, contact the Caretaker(%s)\n\n",HEADMOO);
  161.             exit(0);
  162.             }
  163. bypass: /* like I said above, I hate goto's, but there was no choice here
  164.      * this is written here to allow noone into Mtalk when it has been
  165.      * LOCKED except for the Caretaker.
  166.      */
  167.     printf("\n___________________________________________________________");
  168.     printf("\n Multi*Talk           Talk Parlour                 Ver1.2 ");
  169.     printf("\n      Multi-user Conferencing Program  by  Albert Viall");
  170.     printf("\n-----------------------------------------------------------\n");
  171.     printf("\n'Please sign-in at the Register' (%s): ", myname);
  172.     gets(byname);
  173.  
  174.     if (strlen(byname) ==0) {
  175.                 strcpy(byname,myname);
  176.         strcpy(name,myname);
  177.         } else {
  178.             strcpy(name,byname);
  179.             }
  180.     room="Reception"; 
  181.     myroom="Reception";
  182.     check_users(); /* Check the uniqueness of your name. */
  183.  
  184.     if ((lgnfd=fopen(LGNFILE,"a")) == NULL) {
  185.         perror("do_login/lgnfd open error");
  186.         exit(-1); 
  187.                 }
  188.  
  189.     fprintf(lgnfd,"%s %s %s %s %d\n",mytty,myname,&byname,room,mypid);
  190.     fflush(lgnfd); fclose(lgnfd);
  191.         status_display(); 
  192.  
  193.      printf("\nAll commands must be preceded by '/'. Type '/q' to Quit.\n");
  194.     printf("Type '/?' for commands. Type '/news' for current news.\n");
  195.     printf("\n'Greeves, the butler, escorts you into the Reception Hall.'\n");
  196.     /* show a login entry in the dayfile for this person. */
  197.     security("dayfile","Login ");
  198.             return;  
  199. }
  200.  
  201. parse_cmd(str)
  202. char *str;  
  203. {
  204.     /* This function parses an Mtalk commandline which is always
  205.      * preceded by a '/'.
  206.      */ 
  207.         FILE *lckfd,*pgfd;
  208.     int i;
  209.     int j=0;
  210.     int b,y,accessible;
  211.     char cmd[15],tty[8],ch;
  212.         char arg[15],ttybuf[13];
  213.         char obj[230],yell[230];
  214.     char bro[230],t_lock[35],m_togl[35];   
  215.     char *myname,*getlogin(),*mytty,*ttyname();
  216.  
  217.     myname=getlogin();
  218.     mytty=ttyname(fileno(stdin)); 
  219.     obj[0]='\0';
  220.     /* This FOR loop spans the string looking for how many spaces it can
  221.      * find. We are only worried about the first two which would incorporate
  222.      * a complete command I.e. CMD ARG OBJ
  223.      */    
  224.         y=0;
  225.     for(i=0;i<strlen(str);i++) {
  226.         if (isspace(str[i])) y++;
  227.     /* If there is only one command argument. Null out ARG and OBJ */
  228.         }
  229.     if (y==0) {
  230.         sscanf(str,"%s",cmd);
  231.         arg[0]='\0';
  232.         obj[0]='\0';
  233.         }
  234.     /* If there are two arguments ONLY. Null out the OBJ  */
  235.     if (y==1) {
  236.         sscanf(str,"%s %s",cmd,arg);
  237.         obj[0]='\0';
  238.         }
  239.           /* More than than 2 args? Scan for CMD and ARG, then construct
  240.      * OBJ character by character ending with a NULL.
  241.      */
  242.     if (y > 1) {
  243.         y=0;
  244.         sscanf(str,"%s %s",cmd,arg);
  245.             for(i=0;!isspace(str[i]);i++) { continue; } 
  246.         for(i++;!isspace(str[i]);i++) { continue; }
  247.         for(i++;i<strlen(str);i++) {  
  248.             obj[y]=str[i];
  249.             y++;
  250.             }
  251.                 obj[y]='\0';
  252.         y=0;
  253.         }
  254.     /*    printf("\nCMD:%s\nARG:%s\nOBJ:%s\n",cmd,arg,obj);  */ 
  255.         /* These string compares do the matching of the 'cmd' to whatever
  256.      * command you are defining. All new commands MUST be defined in this
  257.      * area.
  258.     */  
  259.     if (b=strcmp(cmd, "/q") == 0) {
  260.                         do_logout(); 
  261.             exit(0);
  262.             }
  263.     if (b=strcmp(cmd, "/?") == 0) {
  264.                         read_text(CMDS,"pause"); 
  265.             return;
  266.             }
  267.     if (b=strcmp(cmd, "/auto") == 0) {
  268.             auto_mode(); 
  269.             return;
  270.             }
  271.     if (b=strcmp(cmd, "/echo") == 0) {
  272.             if (echo==1) {
  273.                 echo=0;
  274.                 printf("Echo Mode is OFF.\n");
  275.                 return;
  276.                 }
  277.             if (echo==0) {
  278.                 echo=1;
  279.                 printf("Echo Mode is ON.\n");
  280.                 return;
  281.                 }
  282.             return;
  283.             }
  284.     if (b=strcmp(cmd, "/news") == 0) {
  285.                         read_text(NEWS,"pause"); 
  286.             return;
  287.             }
  288.     if (b=strcmp(cmd, "/prompt") == 0) {
  289.             if (strlen(arg)==0) {
  290.                 sprintf(prompt,"Say? \0");
  291.                 return;
  292.                 }
  293.             sprintf(prompt,"%s \0",arg);
  294.             return;
  295.             }
  296.     if (b=strcmp(cmd, "/whisper") == 0) {
  297.             if (strlen(arg)==0) {
  298.                 printf("Usage is: /whisper [logon name] [mesg]\n");
  299.                 return;
  300.                 }
  301.             mwrite(WHISPER,arg,obj);
  302.             return;
  303.             }
  304.     /* by some of the following undocumented commands, you can see that
  305.      * I intended for Mtalk to be somewhat humorous
  306.      */ 
  307.     if (b=strcmp(cmd, "/wear") == 0) {
  308.             if (strlen(arg)==0) {
  309.                 sprintf(bro,"`%s just put on a lampshade.'",&name);
  310.                 mwrite(SENDLOCAL,"",bro);
  311.                 return;
  312.                 }
  313.             sprintf(bro,"`%s just put on %s %s'",&name,arg,obj);
  314.             mwrite(SENDLOCAL,"",bro);
  315.             return;
  316.             }
  317.     if (b=strcmp(cmd, "/drink") == 0) {
  318.             if (strlen(arg)==0) {
  319.                 sprintf(bro,"`%s just drank some Coke.'",&name);
  320.                 mwrite(SENDLOCAL,"",bro);
  321.                 return;
  322.                 }
  323.             sprintf(bro,"`%s just drank %s %s'",&name,arg,obj);
  324.             mwrite(SENDLOCAL,"",bro);
  325.             return;
  326.             }
  327.     if (b=strcmp(cmd, "/eat") == 0) {
  328.             if (strlen(arg)==0) {
  329.                 sprintf(bro,"`%s just ate some potato chips.'",&name);
  330.                 mwrite(SENDLOCAL,"",bro);
  331.                 return;
  332.                 }
  333.             sprintf(bro,"`%s just ate %s %s.'",&name,arg,obj);
  334.             mwrite(SENDLOCAL,"",bro);
  335.             return;
  336.             }
  337.     if (b=strcmp(cmd, "/throwup") == 0) {
  338.             if (strlen(arg)==0) {
  339.                 sprintf(bro,"`%s just threw up.'",&name);
  340.                 mwrite(SENDLOCAL,"",bro);
  341.                 return;
  342.                 }
  343.             sprintf(bro,"`%s just threw up %s %s.'",&name,arg,obj);
  344.             mwrite(SENDLOCAL,"",bro);
  345.             return;
  346.             }
  347.     if (b=strcmp(cmd, "/fart") == 0) {
  348.             sprintf(bro,"`%s just broke wind.'",&name);
  349.             mwrite(SENDLOCAL,"",bro);
  350.             return;
  351.             }
  352.     /* OKAY, Let's get back to serious */
  353.     if (b=strcmp(cmd, "/time") == 0) {
  354.                         printf("The Time is: %s",date()); 
  355.             return;
  356.             }
  357.     if (b=strcmp(cmd, "/status") == 0) {
  358.                         status_display(); 
  359.             return;
  360.             }
  361.     if (b=strcmp(cmd, "/moderator") == 0) {
  362.         if (strcmp(myroom,"Reception")!=0) {
  363.             if (master==1) {
  364.                 moderator("unmaster","moo");
  365.                 return;
  366.                 } else {
  367.                 moderator("master","moo");
  368.                 return;
  369.                 }
  370.             } else {
  371.             printf("You may not Moderate the Reception Hall.\n");
  372.             return;
  373.             }
  374.         }
  375.     if (b=strcmp(cmd, "/remove") == 0) {
  376.         if (strcmp(myroom,"Reception")!=0) {
  377.             if (master==1) {
  378.                 moderator("remove",arg);
  379.                 return;
  380.                 }
  381.             printf("You are not the Moderator of this table.\n");
  382.             return;
  383.             } else {
  384.             printf("You may not Remove anyone from the Reception Hall.\n");
  385.             return;
  386.             }
  387.         }
  388.     if (b=strcmp(cmd, "/open") == 0) {
  389.         if (strcmp(myroom,"Reception")!=0) {
  390.             if (master==1) {
  391.                 moderator("open","moo");
  392.                 return;
  393.                 }
  394.             printf("You are not the Moderator of this table.\n");
  395.             return;
  396.             } else {
  397.             printf("You may not Open/Close the Reception Hall.\n");
  398.             return;
  399.             }
  400.         }
  401.     if (b=strcmp(cmd, "/close") == 0) {
  402.         if (strcmp(myroom,"Reception")!=0) {
  403.             if (master==1) {
  404.                 moderator("close","moo");
  405.                 return;
  406.                 }
  407.             printf("You are not the Moderator of this table.\n");
  408.             return;
  409.             } else {
  410.             printf("You may not Open/Close the Reception Hall.\n");
  411.             return;
  412.             }
  413.         }
  414.     if (b=strcmp(cmd, "/message") == 0) {
  415.             if (strlen(arg)==0) {
  416.                 printf("You must specify someone to send it to.\n");
  417.                 return;
  418.                 }
  419.             do_message(arg,"write");
  420.             return;
  421.             }
  422.     if (b=strcmp(cmd, "/lock") == 0) {
  423.         if (y=strcmp(myname,HEADMOO)!=0) {
  424.             putchar(BELL); 
  425.             printf("This Command reserved for Caretaker.\n");
  426.                         return;  
  427.             }   
  428.                 if ((accessible=access(LOCKFIL,0)) ==0) {
  429.             unlink(LOCKFIL);
  430.             security("dayfile","UNLOCK");
  431.             mwrite(SENDALL,"","`Greeves just opened the doors to the Parlour.'");
  432.             return;
  433.             } else { 
  434.             fopen(LOCKFIL,"a"); 
  435.                 }     
  436.             mwrite(SENDALL,"","`Greeves has just bolted the doors shut. No further entry is permitted.'");
  437.             security("dayfile","LOCK  ");
  438.             return;
  439.             }
  440.     if (b=strcmp(cmd, "/logoff") == 0) {
  441.         if (y=strcmp(myname,HEADMOO)!=0) {
  442.             putchar(BELL); 
  443.             printf("\nThis Command reserved for Caretaker.\n");
  444.                         return;  
  445.             }   
  446.         if (strlen(arg)==0) {
  447.             printf("You must specify someone to 'logoff'.\n");
  448.             return;
  449.             }
  450.         sprintf(bro,"### %s was just forcibly logged off by a Caretaker.",arg);
  451.         logoff(arg);
  452.         mwrite(SENDALL,"",bro);    
  453.         return;
  454.         }
  455.     if (b=strcmp(cmd, "/dayfile") == 0) {
  456.         if (y=strcmp(myname,HEADMOO)!=0) {
  457.             putchar(BELL); 
  458.             printf("\nThis Command reserved for Caretaker.\n");
  459.                         return;  
  460.             }   
  461.         printf("\nSTATUS - UID - LOGINAME - TIME DESCRIPTION\n");
  462.         printf("=============================================\n\n"); 
  463.         read_text(DAYFILE,"pause"); /* show dayfile and pause */
  464.         return;
  465.         }
  466.     if (b=strcmp(cmd, "/broadcast") == 0) {
  467.         if (y=strcmp(myname,HEADMOO)!=0) {
  468.             putchar(BELL); 
  469.             printf("This Command reserved for Caretaker.\n");
  470.                         return;  
  471.             }   
  472.         sprintf(bro,"### BROADCAST(%s): %s %s",&name,arg,obj);
  473.         mwrite(SENDALL,"",bro);
  474.         return;
  475.         }
  476.     if (b=strcmp(cmd, "/purge") == 0) {
  477.         if (y=strcmp(myname,HEADMOO)!=0) {
  478.             putchar(BELL); 
  479.             printf("This Command reserved for Caretaker.\n");
  480.                         return;  
  481.             }   
  482.         security("purge",arg); 
  483.         return;
  484.         }
  485.     if (b=strcmp(cmd, "/page") == 0) {
  486.             system("who | more");
  487.             printf("\nPage which TTY(i.e. ttyi19)?");
  488.             gets(tty);
  489.             sprintf(ttybuf,"/dev/%s",tty);
  490.             if ((pgfd=fopen(ttybuf,"w"))==NULL) {
  491.                 perror("PAGE Device not found");
  492.                 return;
  493.                 }
  494.             fputc(BELL,pgfd);
  495.             fprintf(pgfd,"\n** %s(%s) Paged you to the Talk Parlour **\n respond with 'mtalk' , %s",myname,mytty,date());
  496.             fflush(pgfd); fclose(pgfd);
  497.             return;
  498.             }
  499.     if (b=strcmp(cmd, "/yell") == 0) {
  500.             sprintf(yell,"%s %s",arg,obj);
  501.             mwrite(WRITEALL,"",yell);
  502.             return;
  503.             }  
  504.     if (b=strcmp(cmd, "/sit") == 0) {
  505.             if (strlen(arg)==0) {
  506.                 moderator("cleanup","moo");
  507.                 moderator("unmaster","moo");    
  508.                 sit("Reception");
  509.                 printf("You get up and walk back to the Reception Hall.\n");
  510.                 return;
  511.                 }
  512.             sprintf(t_lock,"%s%s.LCK\0",PATH,arg);
  513.             if ((accessible=access(t_lock,0))==0) {
  514.                 printf("The `%s' table has been closed from further entry.\n",arg);
  515.                 return;
  516.                 }
  517.             sit(arg);
  518.             printf("You sit down at the `%s' table.\n",arg);
  519.             return;
  520.             }  
  521.     if (b=strcmp(cmd, "/look") == 0) {
  522.                   if (strcmp(myroom,"Reception")==0) {
  523.                 printf("You are in the Reception Hall.\n");
  524.                 return;
  525.                 }
  526.             printf("You are sitting at the `%s' table.\n",myroom);
  527.             sprintf(t_lock,"%s%s.LCK\0",PATH,myroom);
  528.             sprintf(m_togl,"%s%s.MAS\0",PATH,myroom);
  529.             if ((accessible=access(m_togl,0))==0) {
  530.                 printf("This table is Moderated.\n");
  531.                 }
  532.             if (master==1) {
  533.                 printf("You are the Moderator.\n");
  534.                 }
  535.             if ((accessible=access(t_lock,0))==0) {
  536.                 printf("The table is Closed from further entry.\n");
  537.                 }
  538.             return;
  539.             }  
  540.     /* Stupid? or what?? */             
  541.     printf("Huh? I don't understand.\nType '/?' for commands.\n");            
  542.     return;
  543. }
  544. void status_display()
  545. {
  546.     /* This will display the user status of Mtalk. It also tests
  547.      * to see if you are HEADMOO, and displays usefull information
  548.      * for Caretakers eye's only.
  549.      */
  550.     int z,y,i,max_i,accessible;
  551.     FILE *lgofd;
  552.     char shmoo[80],*myname,*getlogin();
  553.  
  554.     if ((lgofd=fopen(LGNFILE,"r")) == NULL) { /* Open the loginfile */ 
  555.         perror("Open Error reading LGNFILE");
  556.         exit(-1);
  557.             }
  558.     myname=getlogin(); 
  559.     init_flds();
  560.         /* Read a line from LGOFD until EOF. Each line in loginfile consists
  561.      * of info regarding each user logged into MTALK.
  562.      */
  563.     max_i=0;
  564.     for (i=0; i<MAXUSERS; i++) {
  565.         if (feof(lgofd)) break;
  566.         fscanf(lgofd,"%s %s %s %s %d",logon_info[i].thetty,logon_info[i].uid_name,logon_info[i].logon_name,logon_info[i].room,&logon_info[i].thepid); 
  567.         } 
  568.         max_i=i-1;  
  569.     fclose(lgofd);
  570.  
  571.     /* Okay, now format the header */
  572.         printf("\nThe following are currently in the Talk Parlour:");
  573.     printf("\n==================================================================");
  574.     printf("\n Name                           Terminal        Uid       Room    ");
  575.     printf("\n------------------------------------------------------------------");
  576.  
  577.     /* Now print out status, all fields are left justified  */
  578.     for (i=0; i<max_i; i++) { 
  579.             if ((strcmp(logon_info[i].room,"Reception")==0)) {
  580.               printf("\n%-17.17s             %-11.11s       %-8.8s %-10.10s",logon_info[i].logon_name,logon_info[i].thetty,logon_info[i].uid_name,logon_info[i].room);
  581.                   continue;
  582.                                 }  
  583.             if ((strcmp(logon_info[i].room,"Casino")==0)) {
  584.               printf("\n%-17.17s             %-11.11s       %-8.8s %-10.10s",logon_info[i].logon_name,logon_info[i].thetty,logon_info[i].uid_name,logon_info[i].room);
  585.                   continue;
  586.                                 }  
  587.  
  588.               printf("\n%-17.17s             %-11.11s       %-8.8s *********",logon_info[i].logon_name,logon_info[i].thetty,logon_info[i].uid_name);
  589.                                  }
  590.         /* Print the trailer */ 
  591.     printf("\n==================================================================\n");
  592.     /* If I am HEADMOO, tell me if the task is locked */
  593.     if (y=strcmp(myname,HEADMOO)==0) {
  594.         if ((accessible=access(LOCKFIL,0))==0){
  595.             printf("\t\t\tThe Task is LOCKED.\n");
  596.             }
  597.         }  
  598. }  
  599. void do_logout()
  600. {
  601.     /* This function performs a gracefull logout. What is done, is that
  602.      * the loginfile is loaded into the logon_info array. Then, the
  603.      * program matches you with your corresponding login entry and
  604.      * NULLS it out. Lastly, the loginfile is unlinked and the remaining
  605.      * entries are written to a new loginfile minus your's.
  606.      */
  607.     int z,y,i,max_i;
  608.     FILE *lgofd; 
  609.     char *ttyname(), *getlogin(), *mytty, *myname,junk[230];
  610.  
  611.     /* Initialize the array fields */
  612.     init_flds();
  613.     mytty=ttyname(fileno(stdin));
  614.     myname=getlogin();
  615.     sprintf(junk,"### %s just left the Talk Parlour on %s.",&name,mytty);
  616.     mwrite(SENDALL,"",junk);
  617.  
  618.     /* Open this blasted file */
  619.     if ((lgofd=fopen(LGNFILE,"r+"))==NULL) {
  620.         perror("Open error on do_logout()");
  621.         exit(-1);
  622.         }
  623.     /* Read in the loginfile */
  624.     for (i=0; i<MAXUSERS; i++) {
  625.         if (feof(lgofd)) break;
  626.         fscanf(lgofd,"%s %s %s %s %d",logon_info[i].thetty,logon_info[i].uid_name,logon_info[i].logon_name,logon_info[i].room,&logon_info[i].thepid); 
  627.         } 
  628.         max_i=i-1; 
  629.     fclose(lgofd);
  630.  
  631.     /* Compare Array 'thetty' to mine to get a match */
  632.     for (i=0; i<max_i; i++) {
  633.         if (strcmp(mytty,logon_info[i].thetty)==0) {
  634.             /* A match to my tty is found */
  635.             logon_info[i].thetty[0]='\0'; /* NULL it out */
  636.             break;
  637.             }
  638.         }
  639.     unlink(LGNFILE); /* We don't need it now, erase it */
  640.         /* Open the new loginfile */
  641.     if ((lgofd=fopen(LGNFILE,"a"))==NULL) {
  642.         perror("Open error on do_logout()2");
  643.         exit(-1);
  644.         }
  645.  
  646.     /* Put the array into the new file except for mine */
  647.     for (i=0; i<max_i; i++) {
  648.         if (strlen(logon_info[i].thetty)!=0) {
  649.             fprintf(lgofd,"%s %s %s %s %d\n",logon_info[i].thetty,logon_info[i].uid_name,logon_info[i].logon_name,logon_info[i].room,logon_info[i].thepid);
  650.             }
  651.         continue;
  652.         }
  653.     fclose(lgofd);
  654.     get_comfile();
  655.     moderator("cleanup","moo");  /* Do this on the possibility that someone
  656.                 * logs out while at a table.
  657.                 */
  658.     /* put entry into dayfile that I logged out */
  659.     security("dayfile","Logout");
  660.         printf("\nThanks for using M*Talk...\n");
  661. }
  662.  
  663. read_text(news,pause) 
  664. char *news;
  665. char *pause; 
  666. {
  667.     /* This function will read a text file in one of two ways depending
  668.      * upon the parameters it has been given. If "pause" is passed
  669.      * it will display the file and pause every 23 lines and wait for
  670.      * a c/r. Otherwise, "nopause" should be passed.
  671.      */
  672.     FILE *rn;
  673.     int c,y,cnt;
  674.     char ch;
  675.  
  676.     if ((rn=fopen(news,"r"))==NULL) {
  677.         return;
  678.         }
  679.     
  680.     if (y=strcmp(pause,"nopause") == 0) {
  681.         while ((c=getc(rn))!=EOF)
  682.             putc(c,stdout);
  683.  
  684.         fclose(rn);  
  685.         return;
  686.         }
  687.  
  688.     if (y=strcmp(pause,"pause") == 0) {
  689.         while ((c=getc(rn))!=EOF) {
  690.             if (c=='\n') cnt++;
  691.             if (cnt==23) {
  692.                  printf("\n- 'Return' for more or 'q' to Quit -");
  693.                  ch=getchar();
  694.                 if (strcmp(ch,'q')==0) {
  695.                     break;
  696.                     } else {
  697.                 printf("\013\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
  698.                     cnt=0;
  699.                     continue;
  700.                     }
  701.                 }
  702.             putc(c,stdout);
  703.             }
  704.         fclose(rn);
  705.         return;
  706.         }
  707.  
  708. }      
  709.  
  710. sit(where)
  711. char *where;
  712. {
  713.     /* function is self-explanatory. It corresponds to the /SIT
  714.      * command.
  715.      */
  716.  
  717.     FILE *lgnfd,*outfd;
  718.     int max_i,i,y,accessible;
  719.     char *ttyname(),*getlogin(),*mytty,*myname,stuff[230],pid[5],t_lock[35];
  720.  
  721.     sprintf(t_lock,"%s%s.LCK\0",PATH,where);
  722.  
  723.     if ((lgnfd=fopen(LGNFILE,"r"))== NULL) {
  724.         perror("Open error on sit()/LGNFD");
  725.         return;
  726.         }
  727.         strcpy(myroom,where);
  728.     mytty=ttyname(fileno(stdin));
  729.     myname=getlogin();
  730.     init_flds(); /* Initialize the array */
  731.     max_i=0;
  732.     
  733.     /* Get the info */
  734.     for(i=0;i<MAXUSERS;i++) {
  735.         if (feof(lgnfd)) break;
  736.         fscanf(lgnfd,"%s %s %s %s %d",logon_info[i].thetty,logon_info[i].uid_name,logon_info[i].logon_name,logon_info[i].room,&logon_info[i].thepid); 
  737.         }
  738.     max_i=i-1;
  739.  
  740.     /* Set my array table equal to my physical table */
  741.     for(i=0; i<max_i; i++) {
  742.         if (strcmp(mytty,logon_info[i].thetty)==0) {
  743.             strcpy(logon_info[i].room, myroom);
  744.             break;
  745.             }
  746.         continue;
  747.         }
  748.     /* Now tell everyone but me, that I sat down at their table */
  749.     for(i=0; i<max_i; i++) {
  750.         if (strlen(where)==0) break;  
  751.         if (strcmp(mytty,logon_info[i].thetty)==0) {
  752.             continue;
  753.             }
  754.         sprintf(pid,"%s%d",PATH,logon_info[i].thepid);
  755.         if (strcmp(logon_info[i].room,myroom) ==0) {
  756.             if ((outfd=fopen(pid,"a"))==NULL) {
  757.                 perror("open error commfile/sit");
  758.                 continue;
  759.                 }
  760.             sprintf(stuff,"`%s' just sat down at your table.\n\0",&name);
  761.             fwrite(stuff,sizeof(char),strlen(stuff),outfd);
  762.             fflush(outfd); fclose(outfd);
  763.             continue;
  764.             }
  765.         continue;
  766.         }
  767.  
  768.                 
  769.     unlink(LGNFILE);
  770.     if ((outfd=fopen(LGNFILE,"a")) ==NULL) {
  771.         perror("sit()/outfd");
  772.         exit(-1);
  773.         }
  774.     for(i=0; i<max_i; i++) {
  775.             fprintf(outfd,"%s %s %s %s %d\n",logon_info[i].thetty,logon_info[i].uid_name,logon_info[i].logon_name,logon_info[i].room,logon_info[i].thepid);
  776.              }
  777.     fclose(outfd);
  778. }
  779.  
  780. security(which,who)
  781. char *which;
  782. char *who;
  783. {
  784.     /* This function deals with security specific operations.
  785.      * Most notably, the /PURGE command. But also, handles the
  786.      * dayfile entry.
  787.      */
  788.     FILE *prgfd;
  789.     char *getlogin(),*myname,junk[9];
  790.  
  791.     myname=getlogin();
  792.  
  793.     if (strcmp(which,"purge")==0) {
  794.         if ((prgfd=fopen(PRGFILE,"a"))==NULL) {
  795.             perror("security/purge open error");
  796.             return;
  797.             }
  798.         fprintf(prgfd,"%s\n",who);
  799.         fflush(prgfd); fclose(prgfd);
  800.         printf("\n`%s' has now been purged from Mtalk.\n",who);
  801.         return;
  802.         }
  803.     if (strcmp(which,"dayfile")==0) {
  804.         if ((prgfd=fopen(DAYFILE,"a"))==NULL) {
  805.             perror("security/dayfile open error");
  806.             return;
  807.             }
  808.         fprintf(prgfd,"%s-%s-%s-%s",who,myname,&name,date());
  809.         fflush(prgfd); fclose(prgfd);
  810.         return;
  811.         }
  812.     if (strcmp(which,"compare")==0) {
  813.         if ((prgfd=fopen(PRGFILE,"r"))==NULL) {
  814.             return;
  815.             }   
  816.         for(;;) {
  817.             if (feof(prgfd)) break;
  818.             fscanf(prgfd,"%s",junk);
  819.             if (strcmp(myname,junk)==0) {
  820.                 putchar(BELL); 
  821.                 printf("\n**** Your access to M*talk has been removed indefinately.\n**** Please see the Caretaker for further info.\n");
  822.                 exit(1);
  823.                 }
  824.             continue;
  825.             }
  826.         return;
  827.         }
  828. } /* NOTREACHED End of Security function */
  829.  
  830. get_comfile()
  831. {
  832.     /* This function will read your corresponding commfile and then
  833.      * unlink it to ready it for further appendages. 
  834.      */
  835.     read_text(myfile,"nopause");
  836.     unlink(myfile);
  837. }
  838.  
  839. void check_max()
  840. {
  841.     /* This function checks to make sure there arent MAXUSERS on Mtalk
  842.      * and is called before anything else.
  843.      */
  844.     int z,y,i,max_i;
  845.     FILE *lgofd; 
  846.     char *ttyname(), *getlogin(), *mytty, *myname;
  847.  
  848.     /* Initialize the array fields */
  849.     init_flds();
  850.     mytty=ttyname(fileno(stdin));
  851.     myname=getlogin();
  852.  
  853.     /* Open this blasted file */
  854.     if ((lgofd=fopen(LGNFILE,"r+"))==NULL) {
  855.         perror("Warning: Open error on loginfile, no big deal.");
  856.         return;
  857.         }
  858.     for (i=0; i<MAXUSERS; i++) {
  859.         if (feof(lgofd)) break;
  860.         fscanf(lgofd,"%s %s %s %s %d",logon_info[i].thetty,logon_info[i].uid_name,logon_info[i].logon_name,logon_info[i].room,&logon_info[i].thepid); 
  861.         } 
  862.         max_i=i-1; 
  863.     fclose(lgofd);
  864.     if (max_i < MAXUSERS) {
  865.         return;
  866.         }
  867.     putchar(BELL);
  868.     printf("\n\n*** Sorry, M*Talk is full right Now. Try again later. ***\n\n");
  869.     exit(0);
  870. }
  871. auto_mode()
  872. {
  873.     /* The function for /AUTO. Here, we must change the term. 
  874.      * characteristics, and then build a bitmap of the file descriptors
  875.      * we are interested in looking at. In this case, stdin does just fine.
  876.      * Then, we delay one second, so as not to tie anything up, and 
  877.      * constantly check for our commfile. If it's there, display it.
  878.      */
  879.     int accessible, mypid, template[2], mask[2], st;
  880.     struct sgttyb ttysettings;
  881.     struct timeval delay;
  882.  
  883.     /* set the terminal characteristics */
  884.     assert(ioctl(fileno(stdin), TIOCGETP, &ttysettings) ==0);
  885.     ttysettings.sg_flags &= (~ECHO); /* no echo */
  886.     ttysettings.sg_flags |= CBREAK; /* half raw, still allows signals */
  887.     template[fileno(stdin)/32] = 1 << (fileno(stdin)%32);
  888.  
  889.     delay.tv_sec=1;
  890.     delay.tv_usec=0;
  891.  
  892.     printf("\nAuto Mode - Press `ENTER' to abort.\n");
  893.     for(;;) {
  894.         int n;
  895.         /* We must do this copy because select smashes the mask all
  896.          * to hell each time it is called.
  897.          */
  898.         (void) bcopy(template,mask,2 * sizeof(int));
  899.         assert(n=select(1,mask,0L,0L,&delay) >= 0);
  900.  
  901.     /* If input pending, store it and read it. Mask is now hosed */
  902.     if (n && (mask[fileno(stdin)/32] & (1 << (fileno(stdin)%32)))) {
  903.         char c;
  904.         assert(read(fileno(stdin),&c,sizeof(char)) > 0);
  905.         if (c=='\n') break;
  906.         }
  907.     /* if Myfile is there, read the thing */
  908.     if ((accessible=access(myfile,0))==0) {
  909.         get_comfile();
  910.         continue;
  911.         }
  912.     }
  913.     /* Reset the terminal. This should really be a signal call, in case
  914.      * someone hits control-C, but most people use TCSH, and the shell
  915.      * does all that for us.
  916.      */    
  917.     ttysettings.sg_flags |= ECHO;
  918.     ttysettings.sg_flags &= (~CBREAK);
  919.     assert(ioctl(fileno(stdin), TIOCSETP, &ttysettings)==0);
  920.     return;
  921. }
  922. cleanup(sig)
  923. {
  924.     /* This routine provides a tidy exit from the program upon
  925.      * an ungracefull exit by the user. This routine is used only
  926.      * with the signal calls shown at the beginning of this
  927.       * source code.
  928.      */
  929.     kill(mypid,SIGHUP); 
  930.     do_logout();
  931.     exit(0);
  932. }
  933. void check_users() 
  934. {
  935.     /* This function compares your name that you inputted with the
  936.      * logonnames which are in the parlour at your login. If we get
  937.      * a match, then we can't let you in. Must not have more than one
  938.      * person of the same name online.
  939.      */
  940.     int z,y,i,max_i,accessible;
  941.     FILE *lgofd;
  942.     char shmoo[80],*myname,*getlogin();
  943.  
  944.     if ((lgofd=fopen(LGNFILE,"r")) == NULL) { /* Open the loginfile */ 
  945.         perror("Warning: Open Error reading loginfile, no big deal.");
  946.         return;
  947.             }
  948.     myname=getlogin(); 
  949.     init_flds();
  950.         /* Read a line from LGOFD until EOF. Each line in loginfile consists
  951.      * of info regarding each user logged into MTALK.
  952.      */
  953.     max_i=0;
  954.     for (i=0; i<MAXUSERS; i++) {
  955.         if (feof(lgofd)) break;
  956.         fscanf(lgofd,"%s %s %s %s %d",logon_info[i].thetty,logon_info[i].uid_name,logon_info[i].logon_name,logon_info[i].room,&logon_info[i].thepid); 
  957.         } 
  958.         max_i=i-1;  
  959.     fclose(lgofd);
  960.  
  961.     /* Now compare all the logonnames. */
  962.     for (i=0; i<max_i; i++) {
  963.         if (strcmp(&name,logon_info[i].logon_name)==0) {
  964.             putchar(BELL);
  965.             printf("\n\nThat Name is already in use. Try another name.\n\n");
  966.             exit(-1);
  967.             }
  968.         continue;
  969.         }
  970. }
  971. do_message(who,what)
  972. char *who;
  973. char *what;
  974. {
  975.     FILE *msgfd;
  976.     int y,accessible,i,lineno;
  977.     char *myname, *getlogin(), stuff[20], msg[80], file[35],ch;
  978.     struct message {
  979.         char line[80];
  980.         } text[20];
  981.  
  982.     myname=getlogin();
  983.     sprintf(file,"%s%s\0",PATH,who);
  984.  
  985.     if (strcmp(what,"write")==0) {
  986.         printf("\nGreeves says,`You wish to write a small message to (%s)?'\n`First, make sure that is the correct logon for this person.'\n",who);
  987.         printf("\nContinue(yes or no)?");
  988.         gets(stuff);
  989.         if (strcmp(stuff,"no")==0) { return; }
  990.         if (strlen(stuff)==0) return;
  991.  
  992.         sprintf(msg,"********* A message from (%s), sent on %s\n",myname,date());
  993.         lineno=1;
  994.         printf("\nMessage to (%s) on %sYou may write up to 20 lines. End the message with a 'blank' line.\n\n",who,date());
  995.         for (i=0; i<20; i++) {
  996.             printf("%d> ",lineno);
  997.             gets(text[i].line);
  998.             if (strlen(text[i].line)==0) break;
  999.             lineno++;
  1000.             }
  1001.         printf("Do you want to (s)end it, or (f)orget it? ");
  1002.         ch=getchar();
  1003.         
  1004.         switch(ch) {
  1005.             case 's':
  1006.                 break;
  1007.             case 'f':
  1008.                 printf("\n`Nothing sent..'");
  1009.                 return;
  1010.             default:
  1011.                 printf("\n`Nothing sent..'");
  1012.                 return;
  1013.             }
  1014.  
  1015.                 
  1016.         if ((msgfd=fopen(file,"a"))==NULL) {
  1017.             perror("error on msgfd");
  1018.             return;
  1019.             }
  1020.         fprintf(msgfd,"-------------------------------------------------------------------\n");
  1021.         fprintf(msgfd,"%s\0",msg);
  1022.         for (i=0; i<lineno; i++) {
  1023.             fprintf(msgfd,"%s\n\0",text[i].line);
  1024.             }
  1025.         fprintf(msgfd,"-------------------------------------------------------------------\n");
  1026.         fflush(msgfd); fclose(msgfd);
  1027.         printf("\nGreeves says,`Allright %s, when I see %s, I shall givehim/her the message.'\n",&name,who);
  1028.         sprintf(file,"Wmsg (%s)\0",who);
  1029.         security("dayfile",file);    
  1030.         return;
  1031.         }
  1032.  
  1033.     if (strcmp(what,"read")==0) {
  1034.         if ((accessible=access(file,0))==0) {
  1035.             putchar(BELL);
  1036.             printf("\nGreeves says,`Excuse me, I believe you have a message.'\n Would you like it now(yes or no)?");
  1037.             gets(stuff);
  1038.             if (strlen(stuff)==0) return;
  1039.             if (strcmp(stuff,"no")==0) {
  1040.                 printf("\nGreeves says,`Allright %s, I shall save it for you until later.'\n\n",&name);
  1041.                 return;
  1042.                 }
  1043.  
  1044.             printf("\n`Greeves hands you a piece of paper and then leaves.'\n");
  1045.             read_text(file,"pause");
  1046.             unlink(file);
  1047.             return;
  1048.             }
  1049.         return;
  1050.         }
  1051. }
  1052.  
  1053. moderator(what,who)
  1054. char *what;
  1055. char *who;
  1056. {
  1057.     FILE *lgnfd,*outfd;
  1058.     int max_i,i,accessible;
  1059.     char stuff[80],*myname,*getlogin(),m_togl[35],t_lock[35];
  1060.  
  1061.     sprintf(t_lock,"%s%s.LCK\0",PATH,myroom);
  1062.     sprintf(m_togl,"%s%s.MAS\0",PATH,myroom);
  1063.  
  1064.     myname=getlogin();
  1065.  
  1066.     if (strcmp(what,"master")==0) {
  1067.         if (((accessible=access(m_togl,0))==0)&&(master==1)) {
  1068.             printf("You are already Moderator of this table.\n");
  1069.             return;
  1070.             }
  1071.         if (((accessible=access(m_togl,0))==0)&&(master==0)) {
  1072.             printf("Someone is already Moderator of this table.\n");
  1073.             return;
  1074.             }
  1075.         master=1;
  1076.         sprintf(stuff,"`%s' is now Moderator of this table.",&name);
  1077.         mwrite(SENDLOCAL,"",stuff);
  1078.         fopen(m_togl,"a");
  1079.         return;
  1080.         }
  1081.     if (strcmp(what,"unmaster")==0) {
  1082.         if (((accessible=access(m_togl,0))==0)&&(master==1)) {
  1083.             unlink(m_togl);
  1084.             master=0;
  1085.             return;
  1086.             }
  1087.         return;
  1088.         }
  1089.  
  1090.     if (strcmp(what,"close")==0) {
  1091.         if (((accessible=access(t_lock,0))==0)&&(master==1)) {
  1092.             printf("This table is already Closed.\n");
  1093.             return;
  1094.             }
  1095.         fopen(t_lock,"a");
  1096.         sprintf(stuff,"`%s' has just Closed this table from further entry.",&name);
  1097.         mwrite(SENDLOCAL,"",stuff);
  1098.         return;
  1099.         }
  1100.     if (strcmp(what,"open")==0) {
  1101.         if (((accessible=access(t_lock,0))!=0)&&(master==1)) {
  1102.             printf("This table is already Open.\n");
  1103.             return;
  1104.             }
  1105.         unlink(t_lock);
  1106.         sprintf(stuff,"`%s' has just Opened this table.",&name);
  1107.         mwrite(SENDLOCAL,"",stuff);
  1108.         return;
  1109.         }
  1110.     if (strcmp(what,"cleanup")==0) {
  1111.         if (((accessible=access(m_togl,0))==0)&&(master==1)) {
  1112.             unlink(m_togl);
  1113.             }
  1114.         if (((accessible=access(t_lock,0))==0)&&(master==1)) {
  1115.             unlink(t_lock);
  1116.             }
  1117.         return;
  1118.         }
  1119.     if (strcmp(what,"remove")==0) {
  1120.       if (strcmp(who,&name)==0) {
  1121.         printf("You can't 'remove' yourself from a table.\n");
  1122.         return;
  1123.         }
  1124.       if ((lgnfd=fopen(LGNFILE,"r"))== NULL) {
  1125.         perror("Open error on sit()/LGNFD");
  1126.         return;
  1127.         }
  1128.       init_flds(); /* Initialize the array */
  1129.       max_i=0;
  1130.     
  1131.       /* Get the info */
  1132.       for(i=0;i<MAXUSERS;i++) {
  1133.         if (feof(lgnfd)) break;
  1134.         fscanf(lgnfd,"%s %s %s %s %d",logon_info[i].thetty,logon_info[i].uid_name,logon_info[i].logon_name,logon_info[i].room,&logon_info[i].thepid); 
  1135.         }
  1136.         fclose(lgnfd);
  1137.       max_i=i-1;
  1138.     for(i=0;i<max_i;i++) {
  1139.         if ((strcmp(logon_info[i].logon_name,who)==0)&&(strcmp(logon_info[i].room,myroom)==0)) {
  1140.             sprintf(stuff,"*** `%s' was just removed from the table by the Moderator.",who);
  1141.             mwrite(SENDLOCAL,"",stuff);
  1142.             strcpy(logon_info[i].room,"Reception");
  1143.             break;
  1144.             }
  1145.         continue;
  1146.         }
  1147.     unlink(LGNFILE);
  1148.     if ((outfd=fopen(LGNFILE,"a"))==NULL) {
  1149.         perror("/master - remove");
  1150.         return;
  1151.         }
  1152.     for(i=0; i<max_i; i++) {
  1153.             fprintf(outfd,"%s %s %s %s %d\n",logon_info[i].thetty,logon_info[i].uid_name,logon_info[i].logon_name,logon_info[i].room,logon_info[i].thepid);
  1154.              }
  1155.     fclose(outfd);
  1156.     }
  1157.  
  1158. }
  1159. get_room()
  1160. {
  1161.     FILE *lgnfd;
  1162.     int i,y,max_i;
  1163.     char *mytty,*ttyname();
  1164.     
  1165.       if ((lgnfd=fopen(LGNFILE,"r"))== NULL) {
  1166.         perror("Open error on sit()/LGNFD");
  1167.         return;
  1168.         }
  1169.       init_flds(); /* Initialize the array */
  1170.       max_i=0;
  1171.     mytty=ttyname(fileno(stdin));
  1172.     
  1173.       /* Get the info */
  1174.       for(i=0;i<MAXUSERS;i++) {
  1175.         if (feof(lgnfd)) break;
  1176.         fscanf(lgnfd,"%s %s %s %s %d",logon_info[i].thetty,logon_info[i].uid_name,logon_info[i].logon_name,logon_info[i].room,&logon_info[i].thepid); 
  1177.         }
  1178.         fclose(lgnfd);
  1179.       max_i=i-1;
  1180.     for(i=0;i<max_i;i++) {
  1181.         if (strcmp(mytty,logon_info[i].thetty)==0) {
  1182.             strcpy(myroom,logon_info[i].room);
  1183.             break;
  1184.             }
  1185.         continue;
  1186.         }
  1187.     return;
  1188. }
  1189.  
  1190. mwrite(attr,who,msg)
  1191. char *attr;
  1192. char *who;
  1193. char *msg;
  1194. {
  1195.     /* Mwrite() is the core of the whole Mtalk program. Given the
  1196.      * different attributes as parameters, this function controls all
  1197.      * of the input/output to the other users in Mtalk.
  1198.      */    
  1199.     FILE *lgnfd,*outfd;
  1200.     int max_i,i,accessible,y;
  1201.     char *ttyname(),*getlogin(),*mytty,*myname,pid[5],stuff[230];
  1202.  
  1203.  
  1204.     if ((lgnfd=fopen(LGNFILE,"r"))== NULL) {
  1205.         perror("Open error on Mwrite/LGNFD");
  1206.         return;
  1207.         }
  1208.  
  1209.     mytty=ttyname(fileno(stdin));
  1210.     myname=getlogin();
  1211.     init_flds(); /* Initialize the array */
  1212.     max_i=0;
  1213.     
  1214.     /* Get the info & fill the structure */
  1215.     for(i=0;i<MAXUSERS;i++) {
  1216.         if (feof(lgnfd)) break;
  1217.         fscanf(lgnfd,"%s %s %s %s %d",logon_info[i].thetty,logon_info[i].uid_name,logon_info[i].logon_name,logon_info[i].room,&logon_info[i].thepid); 
  1218.         }
  1219.     max_i=i-1; /* max_i is physical number of users. I have to do this */
  1220.     fclose(lgnfd);
  1221.  
  1222.  
  1223.     if (strcmp(attr,"m_local")==0) {
  1224.         for(i=0;i<max_i;i++) {
  1225.         if ((y=strcmp(logon_info[i].logon_name,&name)==0)&&(echo==0)) {
  1226.             continue; }
  1227.         sprintf(pid,"%s%d",PATH,logon_info[i].thepid);
  1228.         if (y=strcmp(logon_info[i].room, myroom) == 0) {  
  1229.             if ((outfd=fopen(pid,"a"))==NULL) {
  1230.                 perror("Open error to %s",logon_info[i].thetty);
  1231.                 continue;
  1232.                 }
  1233.             fprintf(outfd,"%s says,`%s'\n",&name,msg);
  1234.         if (max_i==1) {
  1235.             fprintf(outfd,"Greeves says,`Talking to yourself again, %s? I see.'\n",&name);
  1236.             }
  1237.             fflush(outfd);fclose(outfd);
  1238.                  }  
  1239.         }  
  1240.     }
  1241.  
  1242.     if (strcmp(attr,"m_all")==0) {
  1243.         for(i=0;i<max_i;i++) {
  1244.         if ((y=strcmp(logon_info[i].logon_name,&name)==0)&&(echo==0)) {
  1245.             continue; }
  1246.             sprintf(pid,"%s%d",PATH,logon_info[i].thepid);  
  1247.             if ((outfd=fopen(pid,"a"))==NULL) {
  1248.                 perror("Open error to %s",logon_info[i].thetty);
  1249.                 continue;
  1250.                 }
  1251.             sprintf(stuff,"%s yells,`%s'\n",&name,msg);
  1252.                         fwrite(stuff, sizeof(char), strlen(stuff), outfd);
  1253.             fflush(outfd);fclose(outfd);
  1254.         }
  1255.     /* So as not to abuse the /YELL command and have people ticked off
  1256.      * at you for disturbing their conversation with rash yells, I built
  1257.      * in this humorous yell counter. Feel free to change the counts
  1258.      * and/or the printf's
  1259.      */
  1260.         yellcnt=yellcnt+1;
  1261.         if (yellcnt==3) {
  1262.             printf("Greeves says,`Could you please keep it down. You are disturbing others.\n");
  1263.         }
  1264.         if (yellcnt==4) {
  1265.             printf("Greeves says,`One more outburst like that, and you will have to leave.\n");
  1266.         }
  1267.         if (yellcnt==5) {
  1268.             printf("Greeves says,`Allright buster, you've had it!!\n");
  1269.             printf("`Greeves takes you by the scruff of the neck and boots you out the door.'\n");
  1270.             sprintf(stuff,"### %s was just forcibly removed by the butler for yelling too much.\n\0",&name);
  1271.             mwrite(SENDALL,"",stuff);
  1272.             do_logout();
  1273.             exit(0);
  1274.         }
  1275.     }
  1276.     if (strcmp(attr,"s_local")==0) {
  1277.  
  1278.         for(i=0;i<max_i;i++) {
  1279.         sprintf(pid,"%s%d",PATH,logon_info[i].thepid);
  1280.         if (y=strcmp(logon_info[i].room, myroom) == 0) {  
  1281.             if ((outfd=fopen(pid,"a"))==NULL) {
  1282.                 perror("Open error to %s",logon_info[i].thetty);
  1283.                 continue;
  1284.                 }
  1285.             sprintf(stuff,"%s\n\0",msg);
  1286.             fwrite(stuff,sizeof(char),strlen(stuff),outfd);
  1287.             fflush(outfd);fclose(outfd);
  1288.                  }  
  1289.         }  
  1290.     }
  1291.     if (strcmp(attr,"s_all")==0) {
  1292.  
  1293.         for(i=0;i<max_i;i++) {
  1294.             sprintf(pid,"%s%d",PATH,logon_info[i].thepid);
  1295.             if ((outfd=fopen(pid,"a"))==NULL) {
  1296.                 perror("Open error to %s",logon_info[i].thetty);
  1297.                 continue;
  1298.                 }
  1299.             sprintf(stuff,"%s\n\0",msg);
  1300.             fwrite(stuff, sizeof(char), strlen(stuff), outfd);
  1301.             fflush(outfd);fclose(outfd);
  1302.         }
  1303.     }
  1304.     if (strcmp(attr,"m_whisper")==0) {
  1305.  
  1306.         for(i=0;i<max_i;i++) {
  1307.             sprintf(pid,"%s%d",PATH,logon_info[i].thepid); 
  1308.             if (strcmp(logon_info[i].logon_name,who)==0) {
  1309.                 if ((outfd=fopen(pid,"a"))==NULL) {
  1310.                 perror("Open error to %s",logon_info[i].thetty);
  1311.                 return;
  1312.                 }
  1313.                 sprintf(stuff,"%s whispers, `%s'\n",&name,msg);
  1314.                 fwrite(stuff, sizeof(char), strlen(stuff), outfd);
  1315.                 fflush(outfd); fclose(outfd);
  1316.                 return;
  1317.                 }
  1318.             continue;
  1319.             }
  1320.         printf("`%s' is not logged into Mtalk.\n",who);
  1321.     }
  1322. } /** End of Mwrite function **/
  1323. logoff(who)
  1324. char *who;
  1325. {
  1326.  
  1327.     FILE *lgnfd,*outfd;
  1328.     int max_i,i,accessible,y;
  1329.     char *ttyname(),*getlogin(),*mytty,*myname,pid[5],stuff[80];
  1330.  
  1331.  
  1332.     if ((lgnfd=fopen(LGNFILE,"r"))== NULL) {
  1333.         perror("Open error on Mwrite/LGNFD");
  1334.         return;
  1335.         }
  1336.  
  1337.     mytty=ttyname(fileno(stdin));
  1338.     myname=getlogin();
  1339.     init_flds(); /* Initialize the array */
  1340.     max_i=0;
  1341.     
  1342.     /* Get the info & fill the structure */
  1343.     for(i=0;i<MAXUSERS;i++) {
  1344.         if (feof(lgnfd)) break;
  1345.         fscanf(lgnfd,"%s %s %s %s %d",logon_info[i].thetty,logon_info[i].uid_name,logon_info[i].logon_name,logon_info[i].room,&logon_info[i].thepid); 
  1346.         }
  1347.     max_i=i-1; /* max_i is physical number of users. I have to do this */
  1348.     fclose(lgnfd);
  1349.  
  1350.     for(i=0;i<max_i;i++) {
  1351.         if (strcmp(who,logon_info[i].logon_name)==0) {
  1352.             kill(logon_info[i].thepid,SIGINT);
  1353.             return;
  1354.         }
  1355.     continue;
  1356.     } /* Reached if Unsuccessful */
  1357.     printf("That person is not logged on.");
  1358.     return;
  1359. } /* Notreached  */
  1360.  
  1361.  
  1362.