home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume36 / msend / part01 / write.c < prev   
Encoding:
C/C++ Source or Header  |  1993-03-22  |  6.3 KB  |  291 lines

  1. /* write.c:
  2.  *
  3.  * these routines are used for writing to users
  4.  *
  5.  * (c) Copyright 1988, 1989, 1990 Jim Frost.  All Rights Reserved.  Please see
  6.  * the accompanying file "Copyright" for more information.
  7.  */
  8.  
  9. #include "Copyright"
  10. #include "config.h"
  11. #include "msend.h"
  12. #ifdef M_SYS
  13. #include <unistd.h>
  14. #endif
  15. #if defined(_AIX) && defined(USE_LOCKF)
  16. #include <sys/lockf.h>
  17. #endif
  18.  
  19. extern int  errno;
  20.  
  21. #ifdef SECURE_PORT
  22. extern short notsecure;
  23. #endif
  24.  
  25. /* this writes to the tty specified in si and saves the message in spool
  26.  */
  27.  
  28. static int ttywrite(si)
  29. struct simsg *si;
  30. { FILE *f;
  31.   char fname[MAXFILENAME];
  32.   int  uid;
  33.  
  34.   /* try to write to user's tty
  35.    */
  36.  
  37.   sprintf(fname,"/dev/%s",si->ttty);
  38.   if ((f= fopen(fname,"w")) == NULL)
  39.     if (errno == EACCES)
  40.       return(RE_NOMSGS);
  41.     else
  42.       return(RE_SYSERR);
  43. #ifdef SECURE_PORT
  44.   if (notsecure)
  45.     fprintf(f,"\r\n[Bogus? %s]\r\n",si->msg);
  46.   else
  47. #endif
  48.     if (isatty(fileno(f)))
  49.       fprintf(f,"\r\n[%s]\r\n",si->msg);
  50.   fclose(f);
  51.  
  52.   /* save the message in the spool for "huh" option
  53.    */
  54.  
  55.   if (getuid() == ROOTUID) {
  56.     if ((uid= getid(si->taddr)) < 0) /* write to file as if we were user */
  57.       return(RE_NOUSER);
  58.     seteuid(uid);
  59.   }
  60. #ifdef SPOOLDIR
  61.   sprintf(fname,"%s/%s",SPOOLDIR,si->taddr);
  62. #else
  63.   sprintf(fname,"%s/.msendmsgs",gethome(si->taddr));
  64. #endif
  65.  
  66.  
  67.   if ((f= fopen(fname,"a")) != NULL) {
  68. #ifndef USE_LOCKF
  69.     flock(fileno(f),LOCK_EX);
  70. #else
  71.     lockf(fileno(f), F_TLOCK, 0);
  72. #endif
  73.     fprintf(f,"[%s]\n",si->msg);
  74. #ifndef USE_LOCKF
  75.     flock(fileno(f),LOCK_UN);
  76. #else
  77.     lockf(fileno(f), F_ULOCK, 0);
  78. #endif
  79.     fclose(f);
  80.   }
  81.  
  82.   if (getuid() == ROOTUID)
  83.     seteuid(DAEMONUID);
  84.  
  85.   return(RE_OK);
  86. }
  87.  
  88. void broadcast(si)
  89. struct simsg *si;
  90. { char   s[80];
  91.   struct utmp *u;
  92.  
  93.   sprintf(s,"Broadcast message %s",si->msg); /* log it! */
  94.   error(s);
  95.  
  96.   /* loop for every utmp entry and try to write.  ignore any
  97.    * errors returned by ttywrite.  we have to implement the
  98.    * entire write command here or else we get an infinite
  99.    * loop on the first utmp entry.
  100.    */
  101.  
  102.   while (u= getutent()) {
  103. #ifdef SYSVUTMP
  104.     if (u->ut_type != USER_PROCESS)
  105.       continue;
  106. #endif
  107.     if (strcmp(u->ut_name,"")) {
  108.       sprintf(si->ttty,u->ut_line);
  109.       sprintf(si->taddr,u->ut_name);
  110.       ttywrite(si);
  111.     }
  112.   }
  113.   endutent();
  114. }
  115.  
  116. /* single user
  117.  */
  118.  
  119. int writeuser(si)
  120. struct simsg     *si;
  121. { struct utmp    *u;  /* utmp entry */
  122.   struct stat    stb;
  123.   struct rimsg   ri;
  124.   char   *home;
  125.   char   ttyname[sizeof("/dev/")+MAXTTY+1];
  126.   char   token[MAXTOKEN+1];
  127.   char   fname[MAXFILENAME+1];
  128.   char   line[MAXLINE+1];
  129.   FILE   *f;
  130.   time_t ltime;
  131.   int    ttystat;
  132.   int    notfound;
  133.   int    allttys;
  134.   int    forward;
  135.   int    fwderr;
  136.   int    ttyerr;
  137.   int    uid;
  138.  
  139.   /* send to particular tty
  140.    */
  141.  
  142.   if (si->mode & SM_TTY) {
  143.  
  144.     /* look up user of that tty.
  145.      */
  146.  
  147.     ttystat= RE_SYSERR;
  148.     while (u= getutent())
  149.       if (!strcmp(u->ut_line,si->ttty)) {
  150.         strcpy(si->taddr,u->ut_name);
  151.         strcpy(si->ttty,u->ut_line);
  152.         ttystat= ttywrite(si);
  153.         break;
  154.       }
  155.     endutent();
  156.     if (ttystat == RE_SYSERR)
  157.       errno= ENODEV;          /* error message for user */
  158.     return(ttystat);
  159.   }
  160.  
  161.   /* open user's options file and see if they want some special
  162.    * propagation
  163.    */
  164.  
  165.   allttys= 0;
  166.   forward= 0;
  167.   fwderr= RE_OK;
  168.  
  169.   if ((home= gethome(si->taddr)) == NULL)
  170.     return(RE_NOUSER);
  171.   if (getuid() == ROOTUID) {
  172.     if ((uid= getid(si->taddr)) < 0)
  173.       return(RE_NOUSER);
  174.     seteuid(uid);
  175.   }
  176.  
  177.   sprintf(fname,"%s/.msendrc",home);
  178.   if ((f= fopen(fname,"r")) != NULL) {
  179.     while (fgets(line,MAXLINE,f) != NULL) {
  180.       sscanf(line,"%s",token);
  181.  
  182.       /* tty options
  183.        */
  184.  
  185.       if (!strcmp(token,"allttys"))
  186.         allttys= 1;
  187.       else if (!strcmp(token,"write-to-tty")) {
  188.         sscanf(line,"%*s %s",si->ttty);
  189.         ttywrite(si);
  190.         forward= 1; /* same idea as forwarding */
  191.       }
  192.  
  193.       /* forwarding options.  note that we return the first error that
  194.        * we get when forwarding so the user has some idea that something
  195.        * went wrong.  compound errors will be lost.  we ignore obvious
  196.        * host loops.
  197.        */
  198.  
  199.       else if (!strcmp(token,"forward-to-user")) {
  200.         sscanf(line,"%*s %s",si->taddr);
  201.         if ((striphost(si->taddr,si->tohost)) && (!fwdloop(si->tohost))) {
  202.           si->fwdcount++;
  203.           forward= 1;
  204.           sendmessage(si,&ri,si->mode);
  205.           if (fwderr == RE_OK)
  206.             fwderr= ri.h.errno;
  207.     }
  208.       }
  209.       else if (!strcmp(token,"forward-to-tty")) {
  210.         sscanf(line,"%*s %s %s",si->ttty,si->taddr);
  211.         if ((striphost(si->taddr,si->tohost)) && (!fwdloop(si->tohost))) {
  212.           forward= 1;
  213.           si->fwdcount++;
  214.           sendmessage(si,&ri,si->mode);
  215.           if (fwderr == RE_OK)
  216.             fwderr= ri.h.errno;
  217.         }
  218.       }
  219.       else if (!strcmp(token,"write-and-forward-to-user")) {
  220.         sscanf(line,"%*s %s",si->taddr);
  221.         if ((striphost(si->taddr,si->tohost)) && (!fwdloop(si->tohost))) {
  222.           si->fwdcount++;
  223.           sendmessage(si,&ri,si->mode);
  224.           if (fwderr == RE_OK)
  225.             fwderr= ri.h.errno;
  226.         }
  227.       }
  228.     }
  229.     fclose(f);
  230.     if (forward)
  231.       return(fwderr);
  232.   }
  233.  
  234.   if (getuid() == ROOTUID)
  235.     seteuid(DAEMONUID);
  236.  
  237.   /* send to least idle user or all writable ttys, depending on mode.
  238.    */
  239.  
  240.   ltime= (time_t)0;
  241.   notfound= 1;
  242.   ttyerr= RE_OK;
  243.  
  244.   while (u= getutent()) {
  245.     if (!strcmp(u->ut_name,si->taddr)) {     /* match user */
  246.       sprintf(ttyname,"/dev/%s",u->ut_line);
  247.  
  248.       if (stat(ttyname,&stb) != -1) {
  249.         notfound= 0;
  250.         if (stb.st_mode & 022) /* see if we have permission */
  251.           if (allttys) {
  252.  
  253.             /* write to every possible tty
  254.              */
  255.  
  256.             strcpy(si->ttty,u->ut_line);
  257.             if (ttyerr != RE_OK)
  258.               ttywrite(si);
  259.             else
  260.               ttyerr= ttywrite(si);
  261.           }
  262.           else {
  263.  
  264.             /* look for least idle terminal
  265.              */
  266.  
  267.             if (!ltime) {
  268.               ltime= stb.st_mtime;
  269.               strcpy(si->ttty,u->ut_line);
  270.             }
  271.             else if (stb.st_mtime > ltime) { /* less idle */
  272.               ltime= stb.st_mtime;
  273.               strcpy(si->ttty,u->ut_line);
  274.             }
  275.       }
  276.       }
  277.     }
  278.   }
  279.   endutent();
  280.  
  281.   if (allttys)
  282.     return(ttyerr);
  283.  
  284.   if (notfound)
  285.     return(RE_NOTTHERE);
  286.   else if (!ltime)
  287.     return(RE_NOMSGS);
  288.  
  289.   return(ttywrite(si));
  290. }
  291.