home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / UUCPbb_2_1_src.lzh / UUCPBB21 / cnvrtmail.c < prev    next >
Text File  |  1994-09-25  |  24KB  |  906 lines

  1. /*
  2. ** This utility converts the spooled mail format from Rick Adams' uucp mailer
  3. ** (v4.2 and earlier) to a new format used by MAIL and RMAIL.  The original
  4. ** format kept all mail in the file ../MAIL/<user>.  The new format keeps all
  5. ** the mail in the *directory* ../MAIL/<user>.  The difference is that each
  6. ** message is kept as an individual file.  This makes the code for MAIL and
  7. ** RMAIL simpler.  One can easily delete and read mail in reverse order
  8. ** without needing to shuffle lots files around on the CoCo.
  9. **
  10. ** Written by Bob Billson <bob@kc2wz.bubble.org>  1992 Mar 2
  11. **
  12. ** This program requires Carl Kreider's CLIB.L to compile.
  13. */
  14.  
  15. #define MAIN
  16.  
  17. #include "uucp.h"
  18. #include <direct.h>
  19. #include <password.h>
  20. #include <time.h>
  21. #ifndef _OSK
  22. #include <utime.h>
  23. #endif
  24. #include <modes.h>
  25. #include "dir_6809.h"
  26.  
  27. #define REALNAMESIZE  18
  28. #define STRINGSIZE    36
  29.  
  30. QQ char *mail_list = "mail..list";
  31. QQ int deleteold;
  32. QQ FILE *log;                                         /* dummy variables to */
  33. char fname[100];                                      /* keep docmd.c happy */
  34. char rootdir[4];
  35. char *strupr(), *strlwr();
  36. unsigned who_owns_the();
  37.  
  38. struct {
  39.      char name[PWNSIZ+1];
  40.      int id;
  41.   } users[PWEMAX];
  42.  
  43.  
  44.  
  45. main (argc, argv)
  46. int argc;
  47. char *argv[];
  48. {
  49.      char line[PWSIZ+1], *p, *p2;
  50.      register FILE *pwfile;
  51.      int i;
  52.  
  53.      pflinit();                        /* tell compiler longs will be used */
  54.      deleteold = FALSE;                /* don't delete old mail file */
  55.      i = 0;
  56.      log = stderr;                     /* don't log error, show them */
  57.  
  58.      if (getuid() != 0)
  59.           fatal ("Sorry only the superuser can run this program");
  60.  
  61.      if (argc > 1) 
  62.           if (strcmp (argv[1], "-k") == 0)         /* remove old mail file */
  63.                deleteold = TRUE;
  64.           else if (strcmp (argv[1], "-o") == 0)    /* convert v5.0 to 5.1+ */
  65.             {
  66.                cnvrtUUCPbb();
  67.                exit (0);
  68.             }
  69.           else
  70.                usage();
  71.  
  72.      if ((pwfile = fopen (PASSWORD, "r")) == NULL)
  73.           fatal ("cannot open password file");
  74.  
  75.      if ((maildir = getenv ("MAIL")) != NULL)
  76.           maildir = strdup (maildir);
  77.      else
  78.           fatal ("MAIL environment undefined");
  79.  
  80.      while ((fgets (line, sizeof (line), pwfile) != NULL)  &&  (i < PWEMAX))
  81.        {
  82.           if ((p = strchr (line, OS9DLM)) == NULL)
  83.                pwerror();
  84.  
  85.           *p = '\0';
  86.           strcpy (users[i].name, line);
  87.  
  88.           /* skip password entry */
  89.           ++p;
  90.  
  91.           if ((p = strchr (p, OS9DLM)) == NULL)
  92.                pwerror();
  93.  
  94.           /* point to uid field */
  95.           p2 = ++p;
  96.  
  97.           if ((p = strchr (p2, OS9DLM)) == NULL)
  98.                pwerror();
  99.  
  100.           *p = '\0';
  101.           users[i++].id = atoi (p2);
  102.        }
  103.  
  104.      fclose (pwfile);
  105.  
  106.      /* what device is the mail directory on? */
  107.      strncpy (rootdir, maildir, 3);
  108.      rootdir[3] = '\0';
  109.  
  110.      chdir (maildir);
  111.      user_ok (i);
  112.      make_dirs (i);
  113.      makesequencefiles();
  114.      free (maildir);
  115.      puts ("\nConversion finished.  Mail is now in the new format.\n");
  116. }
  117.  
  118.  
  119.  
  120. /* double-check to be sure each user is an actual user not a remote system */
  121. int user_ok (last_user)
  122. int last_user;
  123. {
  124.      register int i;
  125.      char c, *answers;
  126.      
  127.      answers = malloc (last_user * sizeof (char));
  128.  
  129.      if (answers == NULL)
  130.           fatal ("user_ok() can't malloc answers array");
  131.  
  132.      for (;;)
  133.        {
  134.           puts ("\fVerify that these users are valid to RECEIVE mail on this system:");
  135.  
  136.           for (i = 0; i < last_user; ++i) 
  137.             {
  138.                do
  139.                  {
  140.                     printf ("\nIs '%s' a valid mail user?  y/n --> ",
  141.                              users[i].name);
  142.  
  143.                     fflush (stdout);
  144.                     read (0, &c, 1);
  145.                     tolower (c);
  146.                  }
  147.                while (c != 'y'  &&  c != 'n');
  148.  
  149.                answers[i] = c;
  150.             }
  151.  
  152.           fputs ("\n\nAre all these correct?  ", stdout);
  153.           fflush (stdout);
  154.           read (0, &c, 1);
  155.  
  156.           if (tolower (c) == 'y')
  157.                break;
  158.        }
  159.  
  160.      /* ignore bad user names */
  161.      for (i = 0; i < last_user; ++i)
  162.           if (answers[i] == 'n')
  163.                users[i].name[0] = '\0';
  164.  
  165.      free (answers);
  166.      putchar ('\f');
  167. }
  168.  
  169.  
  170.  
  171. int make_dirs (last_user)
  172. int last_user;
  173. {
  174.      register int i = 0;
  175.      char temp[100], mailpath[80];
  176.      int path, success, mailwaiting;
  177.      FILE *infile;
  178.  
  179.      while (i < last_user)
  180.        {
  181.           /* be sure we are superuser */
  182.           asetuid (0);
  183.  
  184.           if (users[i].name[0] == '\0')
  185.             {
  186.                ++i;
  187.                continue;
  188.             }
  189.  
  190.           /* move the original mail file to the root directory.  If there */
  191.           /* is no mail file, then there is no mail waiting for this user */
  192.  
  193.           if ((infile = fopen (users[i].name, "r")) == NULL)
  194.                mailwaiting = FALSE;
  195.           else
  196.             {
  197.                mailwaiting = TRUE; 
  198.                sprintf (mailpath, "%s/%s.oldmail", rootdir, users[i].name);
  199.                printf ("\ncopying original mail file to '%s'...", mailpath);
  200.                fflush (stdout);
  201.                filemovf (infile, mailpath);
  202.                setnewowner (mailpath, users[i].id);
  203.  
  204.                /* make sure we can read the mail */
  205.                path = open (mailpath, 2);
  206.                _ss_attr (path, S_IREAD|S_IWRITE);
  207.                close (path);
  208.  
  209.                /* remove the original mail file */
  210.                unlink (users[i].name);
  211.             }
  212.  
  213.           /* Make a mail directory for each user with the user as the owner */
  214.           printf ("\nmaking mail directory for '%s'...", users[i].name);
  215.           fflush (stdout);
  216.           mknod (strupr (users[i].name), S_IREAD|S_IWRITE|S_IEXEC);
  217.           strlwr (users[i].name);
  218.           setnewowner (users[i].name, users[i].id);
  219.           putchar ('\n');
  220.  
  221.           /* if there is spooled mail, convert it to the new format */
  222.           if (mailwaiting)
  223.             {
  224.                success = cnvrtmail (i);
  225.  
  226.                /* back to being superuser */
  227.                asetuid (0);
  228.  
  229.                /* do we get rid of the old mail? */
  230.                if (success  &&  deleteold)
  231.                  {
  232.                     printf ("      ...deleting old mail file: %s", mailpath);
  233.                     fflush (stdout);
  234.  
  235.                     if (unlink (mailpath) == NULL)
  236.                          putchar ('\n');
  237.                     else
  238.                          printf ("...can't delete the file, error %d\n", errno);
  239.                  }
  240.                else
  241.                     printf ("left old mail file as '%s'.\n",
  242.                                 mailpath);
  243.             }
  244.           else
  245.             {
  246.                /* no waiting mail to convert */
  247.                printf ("user '%s' has no waiting mail to process\n",
  248.                          users[i].name);
  249.             }
  250.  
  251.           asetuid (0);
  252.           putchar ('\n');
  253.           ++i;
  254.        }
  255. }
  256.  
  257.  
  258.  
  259. /* Convert mail to new format.  Returns FALSE if error occurred, TRUE
  260. ** otherwise.
  261. */
  262.  
  263. int cnvrtmail (uindex)
  264. int uindex;
  265. {
  266.      FILE *infile, *outfile;
  267.      char line[256], temp[100], mailpath[80], fname[128];
  268.      struct sgtbuf date;
  269.      register int count;
  270.      long nowtime;
  271.      static long prevtime = 0L;
  272.      int done;
  273.  
  274.      fputs ("converting mail to new format...", stdout);
  275.      fflush (stdout);
  276.  
  277.      /* open the old format mail file */
  278.      sprintf (mailpath, "%s/%s.oldmail", rootdir, users[uindex].name);
  279.  
  280.      if ((infile = fopen (mailpath, "r")) == NULL)
  281.        {
  282.           printf ("\nError converting mail for '%s'.\n", users[uindex].name);
  283.           return (FALSE);
  284.        }
  285.  
  286.      if (mfgets (line, sizeof (line), infile) != NULL) 
  287.        {
  288.           fputs ("messages converted:    ", stdout);
  289.           fflush (stdout);
  290.        }
  291.  
  292.      /*
  293.       * Go through the entire spooled mail file.  Put each message in a
  294.       * separate file in the new mail directory.  Each message is given the
  295.       * name 'mYYYYMMDDHHMMSS'.
  296.       */
  297.  
  298.      count = 0;
  299.      done = FALSE;
  300.  
  301.      while (!done)
  302.        {
  303.           /* be sure we are superuser */
  304.           asetuid (0);
  305.  
  306.           /* beginning of message? */
  307.           if (strncmp (line, ">From ", 6) == 0
  308.               || strncmp (line, "From ", 5) == 0)
  309.             {
  310.                for (;;)
  311.                  {
  312.                     getime (&date);
  313.                     nowtime = o2utime (&date);
  314.  
  315.                     /* don't give two messages the same file name */
  316.                     if (nowtime != prevtime)
  317.                          break;
  318.  
  319.                     sleep (1);
  320.                  }
  321.  
  322.                prevtime = nowtime;
  323.  
  324.                /* Account for change of century just in case this code */
  325.                /* is still being used after 1999. <grin>               */
  326.  
  327.                sprintf (fname, "%s/m%s%02d%02d%02d%02d%02d%02d",
  328.                         users[uindex].name,
  329.                         date.t_year > 90  &&  date.t_year <= 99 ? "19" : "20",
  330.                         date.t_year, date.t_month, date.t_day, date.t_hour,
  331.                         date.t_minute, date.t_second);
  332.  
  333.  
  334.                if ((outfile = fopen (fname, "w")) == NULL)
  335.                  {
  336.                     sprintf (temp, "\nerror processing mail for %s...can't create '%s'...error %d",
  337.                                users[uindex].name, fname, errno);
  338.                     fatal (temp);
  339.                  }
  340.  
  341.                fixperms (outfile);
  342.  
  343.                /* send out the first line */
  344.                if (line[0] != '>')
  345.                     fprintf (outfile, ">%s\n", line);
  346.                else
  347.                     fprintf (outfile, "%s\n", line);
  348.  
  349.                /* move the rest of the messsage */
  350.                if (copymsg (infile, outfile, line))  
  351.                     fclose (outfile);
  352.  
  353.                setnewowner (fname, users[uindex].id);
  354.                printf ("\b\b\b%3d", ++count);
  355.                fflush (stdout);
  356.             }
  357.           else
  358.                done = TRUE;
  359.        }
  360.  
  361.      fclose (infile);
  362.  
  363.      /* create the mail..list file in the user's mail directory */
  364.      fputs ("\ncreating user's 'mail..list' file...", stdout);
  365.      fflush (stdout);
  366.      rebuildmail (count, users[uindex].name, users[uindex].id);
  367.      putchar ('\n');
  368.  
  369.      /* back to super user */
  370.      asetuid (0);
  371.      return (TRUE);
  372. }
  373.  
  374.  
  375.  
  376. int copymsg (in, out, line)
  377. register FILE *in;
  378. FILE *out;
  379. char *line;
  380. {
  381.      register char *p;
  382.      char temp[256];
  383.  
  384.      p = temp;
  385.  
  386.      while (mfgets (p, sizeof (temp), in) != NULL)
  387.        {
  388.           /* beginning of next message? */
  389.           if (((strncmp (p, "From ", 5) == 0)
  390.               || (strncmp (p, ">From ", 6) == 0))  && p)
  391.             {
  392.                strcpy (line, p);
  393.                return (TRUE);
  394.             }
  395.           else
  396.                fprintf (out, "%s\n", p);
  397.        }
  398.      line[0] = '\0';
  399.      return (FALSE);
  400. }
  401.  
  402.  
  403.  
  404. /* 
  405. ** Copy old /dd/MAIL/sequence to /DD/SYS/UUCP/sequence.mail.  Create new other
  406. ** sequence files.
  407. */
  408.  
  409. int makesequencefiles()
  410. {
  411.      char line[100];
  412.      FILE *old, *new;
  413.      int newsequence = FALSE,
  414.          sequence;
  415.  
  416.      fputs ("updating news and mail sequence files...", stdout);
  417.      fflush (stdout);
  418.  
  419.      /*
  420.      ** rename the news sequence file, /DD/SYS/UUCP/sequence to 
  421.      ** /DD/SYS/UUCP/sequence.news
  422.      */
  423.  
  424.      asetuid (0);
  425.      sprintf (line, "rename %s/sequence %s", UUCPSYS, NEWSEQ);
  426.      docmd_na (line);
  427.  
  428.      /* now move the mail sequence file to /DD/SYS/UUCP/sequence.mail */
  429.      if ((new = fopen (MAILSEQ, "w")) == NULL)
  430.        {
  431.           sprintf (line, "can't create %s...error %d", MAILSEQ, errno);
  432.           fatal (line);
  433.        }
  434.  
  435.      /* try to find the old sequence file */
  436.      sprintf (line, "%s/sequence", maildir);
  437.  
  438.      if ((old = fopen (line, "r")) == NULL)
  439.           newsequence = TRUE;
  440.  
  441.      if (!newsequence)
  442.           fscanf (old, "%d", &sequence);
  443.      else
  444.           sequence = 0;
  445.  
  446.      /* copy it to the new sequence file */
  447.      fprintf (new, "%ld", sequence);
  448.      fclose (old);
  449.  
  450.      /* make it secure */
  451.      fixperms (new);
  452.      fclose (new);
  453.  
  454.      /* remove the old sequence file */
  455.      sprintf (line, "attr %s/sequence w", maildir);
  456.  
  457.      if (docmd_na (line) == 0)
  458.         {
  459.           sprintf (line, "%s/sequence", maildir);
  460.           unlink (line);
  461.        }
  462.      else
  463.           printf ("\ncould not find and deleted old sequence file '%s/sequence'\n",
  464.                    maildir);
  465.  
  466.      /* create the spool sequence file */
  467.      if ((new = fopen (GENSEQ, "w")) == NULL)
  468.        {
  469.           sprintf (line, "\ncan't create %s...error %d", GENSEQ, errno);
  470.           fatal (line);
  471.        }
  472.  
  473.      /* and initialize it */
  474.      fputs ("0000", new);
  475.      fclose (new);
  476.      putchar ('\n');
  477. }
  478.  
  479.  
  480.  
  481. int setnewowner (file_or_dir, owner)
  482. char *file_or_dir;
  483. unsigned owner;
  484. {
  485.      struct fildes fd;
  486.      register int path;
  487.  
  488.      asetuid (0);
  489.  
  490.      if (((path = open (file_or_dir, S_IWRITE)) == ERROR)  &&
  491.             ((path = open (file_or_dir, S_IFDIR | S_IWRITE)) == ERROR))
  492.        {
  493.           fprintf (stderr, "setnewowner(): can't open path to '%s'\n", 
  494.                      file_or_dir);
  495.           return (FALSE);
  496.        }
  497.  
  498.      if (_gs_gfd (path, &fd, sizeof (struct fildes)) == ERROR)
  499.        {
  500.           close (path);
  501.           return (FALSE);
  502.        }
  503.  
  504.      /* set new owner */
  505.      fd.fd_own = owner;
  506.  
  507.      /* update the file descriptor */
  508.      if (_ss_pfd (path, &fd) == ERROR)
  509.        {
  510.           close (path);
  511.           return (FALSE);
  512.        }
  513.  
  514.      close (path);
  515.      return (TRUE);
  516. }
  517.  
  518.  
  519.  
  520. /* make slight update in Bob Billson's UUCPbb mail and mail..list files */
  521.  
  522. int cnvrtUUCPbb()
  523. {
  524.      char dirname[200], mbox[100];
  525.      unsigned owner;
  526.      DIR *dir;
  527.      struct direct *dirptr;                      /* defined in dir.h -- REB */
  528.  
  529.      if ((dir = opendir (maildir)) == NULL)
  530.        {
  531.           sprintf (mbox, "ERROR--can't open %s", maildir);
  532.           fatal (mbox);
  533.        }
  534.  
  535.      putchar ('\n');
  536.  
  537.      /* loop through each directory in ./SPOOL/MAIL */ 
  538.      while ((dirptr = readdir (dir)) != NULL)
  539.        {
  540.           if (dirptr->d_name[0] == '.')
  541.                continue;
  542.  
  543.           strcpy (mbox, dirptr->d_name);
  544.           sprintf (dirname, "%s/%s", maildir, mbox);
  545.           printf ("updating mail for '%s'...", mbox);
  546.           fflush (stdout);
  547.  
  548.           /*************************************************\
  549.           * change to the mail directory for the system and *
  550.           * look for mail to convert.                       *
  551.           \*************************************************/
  552.  
  553.           owner = who_owns_the (dirname);
  554.  
  555.           if (chdir (dirname) != ERROR)
  556.                updatemail (mbox, owner);
  557.           else
  558.                printf ("ERROR--can't change to %s's directory...continuing",
  559.                         dirname);
  560.        }
  561.      closedir (dir);
  562. }
  563.  
  564.  
  565.  
  566. int updatemail (username, owner)
  567. char *username;
  568. unsigned owner;
  569. {
  570.      FILE *old, *new;
  571.      DIR *dp;                                  /* defined in dir.h */
  572.      register struct direct *dirbuf;           /*                  */
  573.      char oldfilename[80], newfilename[80], buff[256], cmd[128];
  574.      int mailcount;
  575.  
  576.      /* remove the old mail..list file if it exists */
  577.      unlink (mail_list);
  578.  
  579.      /*****************************************************************
  580.       * open mail directory; exit on error.  Our current data directory
  581.       * should already be the correct spool directory for this user.
  582.       *****************************************************************/
  583.  
  584.      if ((dp = opendir (".")) == NULL)
  585.           fatal ("updatemail(): not enough memory to read directory");
  586.  
  587.      /* scan the directory */
  588.      mailcount = 0;
  589.      fputs ("messages converted:    ", stdout);
  590.      fflush (stdout);
  591.  
  592.      while ((dirbuf = readdir (dp)) != NULL)
  593.        {
  594.           if (dirbuf->d_name[0] == '.')
  595.                continue;
  596.  
  597.           strcpy (oldfilename, dirbuf->d_name);
  598.           printf ("\b\b\b%3d", mailcount);
  599.           fflush (stdout);
  600.  
  601.           if ((old = fopen (oldfilename, "r")) == NULL)
  602.             {
  603.                fprintf ("can't open mail '%s' for reading\n", oldfilename);
  604.                --mailcount;
  605.                continue;
  606.             }
  607.  
  608.           /* get the first line -- >From or From */
  609.           if (mfgets (buff, sizeof (buff), old) == NULL)
  610.             {
  611.                fclose (old);
  612.                unlink (oldfilename);
  613.                printf ("\n'%s' is an empty file...deleting it\n",
  614.                         oldfilename);
  615.  
  616.                printf ("messages converted: %3d", mailcount);
  617.                fflush (stdout);
  618.                --mailcount;
  619.                continue;
  620.             }
  621.  
  622.           /* already >From ? */
  623.           if (buff[0] == '>')
  624.             {
  625.                fclose (old);
  626.                ++mailcount;
  627.                continue;
  628.             }
  629.  
  630.           sprintf (newfilename, "%s.tmp", oldfilename);
  631.  
  632.           /* new letter file */
  633.           if ((new = fopen (newfilename, "w")) != NULL)
  634.             {
  635.                setnewowner (newfilename, owner);
  636.                fixperms (new);
  637.             }
  638.           else
  639.             {
  640.                fprintf (stderr, "can't create new mail file '%s'\n",
  641.                          newfilename);
  642.                continue;
  643.             }
  644.  
  645.           /* convert From to >From */
  646.           fprintf (new, ">%s\n", buff);
  647.  
  648.           /* copy the rest of the message unchanged */
  649.           fastcopy (old, new, FALSE, FALSE);
  650.  
  651.           /* don't need the old mail file anymore */
  652.           unlink (oldfilename);
  653.  
  654.           /* rename the new one */
  655.           sprintf (cmd, "rename %s %s", newfilename, oldfilename);
  656.  
  657.           if (docmd_na (cmd) != 0)
  658.                fprintf (stderr, "can't rename %s to %s...error #%d\n",
  659.                                 oldfilename, newfilename, errno);
  660.           ++mailcount;
  661.        }
  662.  
  663.      closedir (dp);
  664.  
  665.      /*******************************************************************\
  666.      * back up to ./SPOOL/MAIL directory. rebuildmail() expects us there *
  667.      * and create the mail..list file in the user's directory            *
  668.      * when we return from rebuildmail we will be back in ./SPOOL/MAIL   *
  669.      \*******************************************************************/
  670.  
  671.      chdir ("..");
  672.  
  673.      if (mailcount > 0)
  674.        {
  675.           fputs ("\n         rebuilding 'mail..list' file...", stdout);
  676.           fflush (stdout);
  677.           rebuildmail (verifycount (username), username, owner);
  678.        }
  679.  
  680.      puts ("\n");
  681. }
  682.  
  683.  
  684.  
  685. unsigned who_owns_the (file_or_dir)
  686. char *file_or_dir;
  687. {
  688.      struct fildes buffer;
  689.      register int path;
  690.  
  691.      asetuid (0);
  692.  
  693.      if (((path = open (file_or_dir, S_IWRITE)) == ERROR)  &&
  694.             ((path = open (file_or_dir, S_IFDIR | S_IWRITE)) == ERROR))
  695.        {
  696.           fprintf (stderr, "who_owns_the(): can't open path to '%s'...error %d\n", 
  697.                      file_or_dir, errno);
  698.           exit (0);
  699.        }
  700.  
  701.      if (_gs_gfd (path, &buffer, sizeof (struct fildes)) == ERROR)
  702.        {
  703.           fprintf  (stderr, "who_owns_the(): can't get file descriptor...error #%d\n", errno);
  704.           exit (0);
  705.        }
  706.  
  707.      close (path);
  708.      return (buffer.fd_own);
  709. }
  710.  
  711.  
  712.  
  713. int rebuildmail (mailcount, username, userid)
  714. int mailcount;
  715. char *username;
  716. unsigned userid;
  717. {
  718.      FILE *mptr, *lptr;
  719.      DIR *dirptr;
  720.      struct direct *mbox;                        /* defined in dir.h -- REB */
  721.      register int i;
  722.      char temp[128];
  723.      static struct mbag  {
  724.                 char letter[32];
  725.               } *ltrs;
  726.  
  727.      ltrs = (struct mbag *) malloc (mailcount * sizeof (struct mbag));
  728.  
  729.      if (ltrs == NULL)
  730.           fatal ("rebuildmail() can't malloc() ltrs array");
  731.  
  732.      asetuid (0);
  733.      chdir (username);
  734.      dirptr = opendir (".");
  735.  
  736.      if (dirptr == NULL)
  737.           fatal ("rebuildmail() not enough memory for mailbox directory (too many letters)");
  738.  
  739.      /* read in the letter filenames */
  740.      i = 0;
  741.  
  742.      while ((mbox = readdir (dirptr)) != NULL)
  743.           if (mbox->d_name[0] != '.')
  744.                strcpy (ltrs[i++].letter, mbox->d_name);
  745.  
  746.      closedir (dirptr);
  747.      qsort (ltrs, mailcount, sizeof (struct mbag), strucmp);
  748.  
  749.      if ((mptr = fopen (mail_list, "w")) == NULL)
  750.        {
  751.           fputs ("rebuildmail() can't create 'mail..list'\n", stderr);
  752.           exit (0);
  753.        }
  754.  
  755.      /* make sure the same owner owns new mail..list file */
  756.      chown (mail_list, userid);
  757.  
  758.      /* make sure nobody else can mess with us for now */
  759.      _ss_attr (fileno (mptr), S_ISHARE|S_IREAD|S_IWRITE);
  760.  
  761.      for (i = 0; i < mailcount; ++i)
  762.           if ((lptr = fopen (ltrs[i].letter, "r")) == NULL)
  763.             {
  764.                fprintf (stderr, "rebuildmail(): can't open '%s'\n",
  765.                                 ltrs[i].letter);
  766.                continue;
  767.             }
  768.           else
  769.             {
  770.                getheader (lptr, mptr, ltrs[i].letter);
  771.                fclose (lptr);
  772.             }
  773.  
  774.      free (ltrs);
  775.  
  776.      /* for our eyes only */
  777.      fixperms (mptr);
  778.      fclose (mptr);
  779.      free (ltrs);
  780.      chdir ("..");
  781. }
  782.  
  783.  
  784.  
  785. int getheader (fp, mptr, filename)
  786. FILE *fp, *mptr;
  787. char *filename;
  788. {
  789.      char mline[256], subj[28], frm[27], resentfrm[128], resentrply[128];
  790.      register char *p;
  791.      int linecount;
  792.      long _gs_size();
  793.      char *getval(), *getstring();
  794.  
  795.      subj[0] = frm[0] = resentfrm[0] = resentrply[0] = '\0';
  796.      p = mline;
  797.  
  798.      while (mfgets (mline, sizeof (mline), fp) != NULL  &&  *p)
  799.           if (*p == 'F' &&  strnucmp ("From: ", p, 6) == 0)
  800.                strncpy (frm, getval (p), sizeof (frm));
  801.           else if (*p == 'R')
  802.             {
  803.                if (strnucmp (p, "Resent-From: ", 13) == 0)
  804.                  {
  805.                     strcpy (resentfrm, getval (p));
  806.                     resentfrm[sizeof (frm) - 1] = '\0';
  807.                  }
  808.                else
  809.                     if (strnucmp (p, "Resent-Reply-To: ", 17) == 0)
  810.                       {
  811.                          strcpy (resentrply, getval (p));
  812.                          resentrply[sizeof (resentrply) - 1] = '\0';
  813.                       }
  814.             }
  815.           else if (*p == 'S'  && (strncmp ("Subject: ", p, 9) == 0)
  816.                               || (strncmp ("Subj: ", p, 6) == 0))
  817.             {
  818.                strncpy (subj, getstring (p), sizeof (subj));
  819.                subj[sizeof (subj) - 1] = '\0';
  820.             }
  821.  
  822.      if (resentrply[0] != '\0')
  823.           strncpy (frm, resentrply, sizeof (frm));
  824.      else
  825.           if (resentfrm[0] != '\0')
  826.                strncpy (frm, resentfrm, sizeof (frm));
  827.  
  828.      /* make sure frm is terminated properly */
  829.      frm[sizeof (frm) - 1] = '\0';
  830.  
  831.      /* count the lines */
  832.      p = mline;
  833.      linecount = 0;
  834.  
  835.      while (mfgets (p, sizeof (mline), fp) != NULL)
  836.           ++linecount;
  837.  
  838.      fprintf (mptr, "N%s|%s|%s|%d|%ld\n",
  839.                     filename, frm[0] != '\0' ? frm : " ",
  840.                     subj[0] != '\0' ? subj : " ",
  841.                     linecount, _gs_size (fileno (fp)));
  842. }
  843.  
  844.  
  845.  
  846. int verifycount (whosemail)
  847. char *whosemail;
  848. {
  849.      DIR *dirptr;
  850.      struct direct *list;                        /* defined in dir.h -- REB */
  851.      register int count_1;
  852.  
  853.      chdir (whosemail);
  854.  
  855.      if ((dirptr = opendir (".")) == NULL)   
  856.           fatal ("checkmail() can't open mailbox");
  857.  
  858.      /* now count our letters */
  859.      count_1 = 0;
  860.  
  861.      while ((list = readdir (dirptr)) != NULL) 
  862.           if (list->d_name[0] != '.') 
  863.                ++count_1;
  864.  
  865.      closedir (dirptr);
  866.      chdir ("..");
  867.      return (count_1);
  868. }
  869.  
  870.  
  871.  
  872. int pwerror()
  873. {
  874.      fatal ("error in password file entry");
  875. }
  876.  
  877.  
  878.  
  879. int fatal (msg)
  880. char *msg;
  881.      fprintf (stderr, "cnvrtmail: %s\n", msg);
  882.      exit (0);
  883. }
  884.  
  885.  
  886.  
  887. int usage()
  888. {
  889.      register char **hlp;
  890.      static char *helptxt[] = {
  891.        "cnvrtmail: convert Rick's Adams spool mail format v4.2 and earlier to new",
  892.        "           format",
  893.        "Usage: cnvrtmail [opt]\n",
  894.        "  opt: ",
  895.        "       -k   = delete user's old mail file",
  896.        "       -o   = update v5.0 to v5.1 format",
  897.        NULL
  898.      };
  899.  
  900.      for (hlp = helptxt; *hlp !=NULL; ++hlp)
  901.           fprintf(stderr, "%s\n", *hlp);
  902.  
  903.      exit (0);
  904. }
  905.