home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume13 / dominion / part26 / mail.c < prev    next >
C/C++ Source or Header  |  1992-02-11  |  8KB  |  328 lines

  1.   /* mail.c -- dominion mail system */
  2.  
  3. /*
  4.  * Copyright (C) 1990 Free Software Foundation, Inc.
  5.  * Written by the dominion project.
  6.  *
  7.  * This file is part of dominion.
  8.  *
  9.  * dominion is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU General Public License as published
  11.  * by the Free Software Foundation; either version 1, or (at your option)
  12.  * any later version.
  13.  *
  14.  * This software is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this software; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23.  
  24. #include "dominion.h"
  25. #include <stdio.h>
  26. #ifdef AMIGA
  27. # include <exec/types.h>
  28. # include <string.h>
  29. #else
  30. # include <sys/types.h>
  31. #endif
  32.  
  33. #include <time.h>
  34. #ifdef SYSV
  35. # include <string.h>
  36. #else
  37. # include <strings.h>
  38. #endif
  39.  
  40. extern Suser user;
  41. extern Sworld world;
  42. extern char *libdir;
  43. extern int ruid, euid;
  44. extern char *get_char_option();
  45.  
  46. char *mail_forwarding(nation)
  47.      int nation;
  48. {
  49.   return get_char_option(nation,"MAIL_FORWARD");
  50. }
  51.  
  52.   /* This function checks if mailbox for nation 'id' is locked. */
  53. has_mail_lock(id)
  54.      int id;
  55. {
  56.   FILE *lock_fp;
  57.   char lock_fn[PATHLEN];
  58.   int ret;
  59.  
  60. /*  ruid = getuid();
  61.   euid = geteuid();
  62. */
  63.   if (mail_forwarding(id))
  64.       return 0;
  65.  
  66.   sprintf(lock_fn,"%s/%d.lock", MAIL_DIR, id);
  67.     /* if it's locked: close and return 1 */
  68.   if ((lock_fp = fopen(lock_fn, "r")) != NULL) {
  69.     fclose(lock_fp);
  70.     ret=1;
  71.   } else {
  72.     ret=0;
  73.   }
  74.   return(ret);
  75. } /* has_mail_lock */
  76.  
  77.   /* This function locks a user's mailbox */
  78. lock_mail(nation)
  79. int nation;
  80. {
  81.   FILE *lock_fp;
  82.   char lock_fn[100];
  83.   
  84.   if (mail_forwarding(nation))
  85.       return;
  86.  
  87.   sprintf(lock_fn, "%s/%d.lock", MAIL_DIR, nation);
  88.   if ((lock_fp = fopen(lock_fn, "w")) != NULL) {
  89.       fprintf(lock_fp, "%ld; Nation %s\n", time(0L), user.np->name);
  90.       fclose(lock_fp);
  91.     }
  92. }
  93.  
  94.   /* This unlock's a user's mailbox */
  95. unlock_mail(nation)
  96. int nation;
  97. {
  98.   char lock_fn[100];
  99.   
  100.   if (mail_forwarding(nation))
  101.       return;
  102.  
  103.   sprintf(lock_fn, "%s/%d.lock", MAIL_DIR, nation);
  104.   unlink(lock_fn);
  105. }
  106.  
  107.   /* This calls the system to edit the given file with the preferred editor */
  108. void edit(t_fn)
  109.      char *t_fn;
  110. {
  111.   int tmp;
  112.   char *edit_prog, *getenv();
  113.   char edit_command[200], command[200];
  114.  
  115.   if ((edit_prog=getenv("DOMINION_EDITOR"))==NULL
  116.       && (edit_prog = getenv("VISUAL")) == NULL
  117.       && (edit_prog = getenv("EDITOR")) == NULL) {
  118.       edit_prog = DEFAULT_EDITOR;
  119.     }
  120. #ifdef UID_SECURITY
  121.     /* we must fork, so that in the child we set the
  122.        real user id, whereas the parent continues with
  123.        the effective user id.
  124.      */
  125.   if (fork() == 0) {        /* child has fork() == 0 */
  126.     setuid(ruid);        /* so this user cannot poke around */
  127.     close(creat(t_fn, 0600));
  128.     sprintf(edit_command, "%s %s", edit_prog, t_fn);
  129.     system(edit_command);
  130.     /* change owner so that it can be processed once the uid changes back */
  131. /*
  132.     sprintf(command, "chown %d %s", euid, t_fn);
  133.     system(command);
  134. */
  135.     chown(t_fn, euid, getgid()); /* use the system call to chown() */
  136. /*
  137.     printf("waiting; type a few returns\n");
  138.     fflush(stdout);
  139.     getchar();
  140.     getchar();
  141. */
  142.     exit(0);
  143.   }
  144.   wait(0);
  145. #else /* UID_SECURITY */
  146.   creat(t_fn, 0666);
  147.   sprintf(command, "chmod 666 %s", t_fn);
  148.   system(command);
  149.   sprintf(edit_command, "%s %s", edit_prog, t_fn);
  150.   system(edit_command);
  151. #endif /* UID_SECURITY */
  152. }
  153.  
  154. /* Insert a file (with the name in_name) into the open file stream pointed
  155.    to by out_pntr */
  156. void insert(in_name, out_pntr)
  157.      char *in_name;
  158.      FILE *out_pntr;
  159. {
  160.   FILE *in_pntr;
  161.   int c;
  162.  
  163.   if ((in_pntr=fopen(in_name, "r"))!=NULL)
  164.     {
  165.       while((c=fgetc(in_pntr))!=EOF)
  166.     fputc(c, out_pntr);
  167.       fclose(in_pntr);
  168.     }
  169. } /* insert */
  170.  
  171.  
  172. char *fix_name(s,fixed)
  173. /* Elm and etc. want the name that mail is from to contain no white space */
  174. char *s,*fixed;
  175. {
  176.   char *poss = s, *posf = fixed;
  177.  
  178.   if (s == NULL) { return NULL; }
  179.   for ( poss = s;(poss != '\0') && (posf - fixed < NAMELEN);  poss++ , posf++)
  180.   {
  181.     if ((*poss == ' ') || (*poss == '\t'))
  182.     {
  183.       *posf = '_';
  184.     } else
  185.     {
  186.       *posf = *poss;
  187.     }
  188.   }
  189.   if (posf - fixed < NAMELEN) { *posf = '\0' ; }
  190.   else { *(fixed + NAMELEN - 1) = '\0'; }
  191.   return fixed;
  192. }
  193. /* Send mail from one nation to another. mailfile is the _name_ of the
  194.    file containing the body of the mail. sender and receiver are the full
  195.    names of the appropriate nations. Guess what subject is... */
  196.  
  197. int mail_send(mailfile, sender, receiver, subject)
  198.      char mailfile[];
  199.      int sender, receiver;
  200.      char subject[];
  201. {
  202.   time_t now_secs;
  203.   char lock_fn[200], dest_fn[200], tmp_fname[PATHLEN], *now_chars;
  204.   FILE *lock_fp, *dest_fp, *temp_fp;
  205.   char s_name[NAMELEN], r_name[NAMELEN];
  206.   int temp;
  207.   char *forward, fixed_name[NAMELEN];
  208.  
  209.   if ((forward = get_char_option(receiver,"MAIL_FORWARD")) != NULL) {
  210.       char command[2048];
  211. #ifdef UID_SECURITY
  212.       int pid;
  213. #endif
  214.  
  215.       strcpy(tmp_fname, "/usr/tmp/domXXXXXX");
  216.       mktemp(tmp_fname);
  217.       temp_fp = fopen(tmp_fname, "w");
  218.       if (!temp_fp) {
  219.       perror("Could not open temp file");
  220.       return 1;
  221.       }
  222.       fprintf(temp_fp,"From: %s of %s\n",world.nations[sender].leader,
  223.           world.nations[sender].name);
  224.       fprintf(temp_fp,"To: %s of %s\n",world.nations[receiver].leader,
  225.           world.nations[receiver].name);
  226.       fprintf(temp_fp,"Subject: %s\n\n",subject);
  227.       fclose(temp_fp);
  228.  
  229. #ifdef UID_SECURITY
  230.       sprintf(command, "chmod +r %s", tmp_fname);
  231.       system(command);
  232. #endif
  233.  
  234.       sprintf(command, "cat %s %s | %s '%s'", tmp_fname, mailfile,
  235.                           MAILER, forward);
  236.  
  237. /*
  238.       printf("\r\n ready to run the cat command; type some returns \r\n");
  239.       fflush(stdout);
  240.       getchar();
  241.       getchar();
  242. */
  243.       system(command);
  244. #ifdef CONFUSED_UID
  245. #ifdef UID_SECURITY
  246.       /* we must fork, so that in the child we set the
  247.      real user id, whereas the parent continues with
  248.      the effective user id.
  249.        */
  250.  
  251.       if ((pid=fork()) == 0) {        /* child has fork() == 0 */
  252.       setuid(getuid());        /* so this user cannot poke around */
  253. #endif
  254.       system(command);
  255. #ifdef UID_SECURITY
  256.       exit(0);
  257.       }
  258. /*      else if (pid < 0)
  259.       perror("Could not fork mailer");
  260.       else
  261.       while (wait(0) != pid);
  262. */
  263.       wait(0);
  264. #endif /* UID_SECURITY */
  265. #endif /* CONFUSED_UID */
  266.  
  267.       unlink(tmp_fname);
  268.       return 0;            /* we've forwarded, so that's all */
  269.   }
  270.  
  271.   /* Set the names of the files used in mail */
  272.   sprintf(dest_fn, "%s/mail.%d", MAIL_DIR, receiver);
  273.  
  274. /*  sprintf(lock_fn, "%d.lock", receiver); */
  275.   strcpy(tmp_fname, "dommaXXXXXX");
  276.   mktemp(tmp_fname);
  277.  
  278.     /* Get the time right now */
  279.   now_secs=time(0L);
  280.   now_chars=ctime(&now_secs);
  281.  
  282.     /* If not make sure it won't be used */
  283. /*  lock_fp=fopen(lock_fn, "w");
  284.   fprintf(lock_fp, "Mail being sent by %s at %s\n", user.np->name, now_chars);
  285.   fclose(lock_fp);
  286. */
  287.  
  288.     /* Copy the mail that's there right now out */
  289.   if ((temp_fp = fopen(tmp_fname, "w")) == NULL) { 
  290.     fprintf(stderr,"Error: Cannot write to mail file %s\n",tmp_fname);
  291.     clean_exit();
  292.     exit(1);
  293.   }
  294.   insert(dest_fn, temp_fp);
  295.   fclose(temp_fp);
  296.     /* Put in the new mail */
  297.   if ((dest_fp=fopen(dest_fn, "w"))!=NULL) {
  298.        /* Some header stuff */
  299.       fix_name(world.nations[sender].leader, fixed_name);
  300.       fprintf(dest_fp, "From %s %s", fixed_name,now_chars);
  301.       fprintf(dest_fp, "Date: %s", now_chars);
  302.       fprintf(dest_fp, "From: %s of %s\n", world.nations[sender].leader,
  303.           world.nations[sender].name);
  304.       fprintf(dest_fp, "To: %s of %s\n", world.nations[receiver].leader,
  305.           world.nations[receiver].name);
  306.       fprintf(dest_fp, "Subject: %s\n\n", subject);
  307.  
  308.         /* Now the body of the message */
  309.       insert(mailfile, dest_fp);
  310.       fprintf(dest_fp, "\n");
  311.         /* and now copy the old mail back in */
  312.       insert(tmp_fname, dest_fp);
  313.       fclose(dest_fp);
  314.     } /* if fopen dest_fp */
  315.   else {
  316.     if (sender==0) {
  317.       fprintf(stderr, "Couldn't open dest_fn\n");
  318.     }
  319.   }
  320.     /* Remove the old unnecessary files */
  321.   unlink(tmp_fname);
  322.   unlink(mailfile);
  323. /*  unlink(lock_fn); */
  324.   unlock_mail(receiver);
  325.   return(0);
  326. } /* mail_send */
  327.  
  328.