/[mailutils]/mailutils/mail.local/main.c
ViewVC logotype

Diff of /mailutils/mail.local/main.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by gray, Mon Jan 21 15:04:11 2002 UTC revision 1.2 by gray, Tue Jan 22 15:19:58 2002 UTC
# Line 19  Line 19 
19    
20  int debug_level;  int debug_level;
21  int multiple_delivery;  int multiple_delivery;
22  int bounce_quota;  int ex_quota_tempfail;
23  int exit_code = EX_OK;  int exit_code = EX_OK;
24  uid_t uid;  uid_t uid;
25  char *maildir = MU_PATH_MAILDIR;  char *maildir = MU_PATH_MAILDIR;
# Line 27  char *quotadbname = NULL; Line 27  char *quotadbname = NULL;
27  int lock_timeout = 300;  int lock_timeout = 300;
28    
29  #define MAXFD 64  #define MAXFD 64
30    #define EX_QUOTA() (ex_quota_tempfail ? EX_TEMPFAIL : EX_UNAVAILABLE)
31    
32  static void print_help (void);  static void print_help (void);
33  static void print_license (void);  static void print_license (void);
# Line 37  FILE *make_tmp (const char *from, char * Line 38  FILE *make_tmp (const char *from, char *
38  void deliver (FILE *fp, char *name);  void deliver (FILE *fp, char *name);
39  void guess_retval (int ec);  void guess_retval (int ec);
40  void mailer_err (char *fmt, ...);  void mailer_err (char *fmt, ...);
41    void notify_biff (mailbox_t mbox, char *name, size_t size);
42    
43  char short_opts[] = "hf:Llm:q:r:s:x::v";  char short_opts[] = "hf:Llm:q:r:s:x::vW;";
44    
45  static struct option long_opts[] = {  static struct option long_opts[] = {
46      { "ex-multiple-delivery-success", no_argument, &multiple_delivery, 1 },
47      { "ex-quota-tempfail", no_argument, &ex_quota_tempfail, 1 },
48    { "from", required_argument, 0, 'f' },    { "from", required_argument, 0, 'f' },
49    { "help", no_argument, 0, 'h' },    { "help", no_argument, 0, 'h' },
50    { "license", no_argument, 0, 'L' },    { "license", no_argument, 0, 'L' },
51    { "maildir", required_argument, 0, 'm' },    { "maildir", required_argument, 0, 'm' },
   { "multiple-delivery", no_argument, 0, 'M' },  
52    { "quota-db", required_argument, 0, 'q' },    { "quota-db", required_argument, 0, 'q' },
53    { "source", required_argument, 0, 's' },    { "source", required_argument, 0, 's' },
54    { "timeout", required_argument, 0, 't' },    { "timeout", required_argument, 0, 't' },
# Line 62  main (int argc, char *argv[]) Line 65  main (int argc, char *argv[])
65    FILE *fp;    FILE *fp;
66    char *from = NULL;    char *from = NULL;
67    char *progfile_pattern = NULL;    char *progfile_pattern = NULL;
68    struct mda_data mda_data;    char *tempfile = NULL;
69      
70    /* Preparative work: close inherited fds, force a reasonable umask    /* Preparative work: close inherited fds, force a reasonable umask
71       and prepare a logging. */       and prepare a logging. */
72    close_fds ();    close_fds ();
# Line 76  main (int argc, char *argv[]) Line 79  main (int argc, char *argv[])
79    while ((c = getopt_long (argc, argv, short_opts, long_opts, NULL)) != EOF)    while ((c = getopt_long (argc, argv, short_opts, long_opts, NULL)) != EOF)
80      switch (c)      switch (c)
81        {        {
82          case 0: /* option already handled */
83            break;
84        case 'r':        case 'r':
85        case 'f':        case 'f':
86          if (from != NULL)          if (from != NULL)
# Line 98  main (int argc, char *argv[]) Line 103  main (int argc, char *argv[])
103          maildir = optarg;          maildir = optarg;
104          break;          break;
105                                    
       case 'M':  
         multiple_delivery++;  
         break;  
           
106  #ifdef USE_DBM  #ifdef USE_DBM
107        case 'q':        case 'q':
108          quotadbname = optarg;          quotadbname = optarg;
# Line 120  main (int argc, char *argv[]) Line 121  main (int argc, char *argv[])
121                    
122        case 'x':        case 'x':
123          if (optarg)          if (optarg)
124            debug_level = strtoul (optarg, NULL, 0);            {
125    #ifdef WITH_GUILE
126                if (strcmp (optarg, "guile") == 0)
127                  debug_guile = 1;
128                else
129    #endif
130                debug_level = strtoul (optarg, NULL, 0);
131              }
132          else          else
133            debug_level = 9;            {
134                debug_level = 9;
135    #ifdef WITH_GUILE          
136                debug_guile = 1;
137    #endif
138              }
139          break;          break;
140                    
141        case 'v':        case 'v':
# Line 146  main (int argc, char *argv[]) Line 159  main (int argc, char *argv[])
159        return 1;        return 1;
160      }      }
161                    
   if (!from)  
     {  
       struct passwd *pw = getpwuid (uid);  
       if (pw)  
         from = pw->pw_name;  
       else  
         {  
           mu_error ("From unknown");  
           return 1;  
         }  
     }  
   
162  #ifdef HAVE_MYSQL  #ifdef HAVE_MYSQL
163    mu_register_getpwnam (getMpwnam);    mu_register_getpwnam (getMpwnam);
164  #endif  #endif
# Line 172  main (int argc, char *argv[]) Line 173  main (int argc, char *argv[])
173      list_append (bookie, smtp_record);      list_append (bookie, smtp_record);
174    }    }
175    
176    memset (&mda_data, 0, sizeof mda_data);    fp = make_tmp (from, &tempfile);
   fp = make_tmp (from, &mda_data.tempfile);  
177        
178    if (multiple_delivery)    if (multiple_delivery)
179      multiple_delivery = argc > 1;      multiple_delivery = argc > 1;
180    
181  #ifdef WITH_GUILE  #ifdef WITH_GUILE
   mda_data.fp = fp;  
   mda_data.argv = argv;  
   mda_data.progfile_pattern = progfile_pattern;  
   
182    if (progfile_pattern)    if (progfile_pattern)
183      return prog_mda (&mda_data);      {
184          struct mda_data mda_data;
185          
186          memset (&mda_data, 0, sizeof mda_data);
187          mda_data.fp = fp;
188          mda_data.argv = argv;
189          mda_data.progfile_pattern = progfile_pattern;
190          mda_data.tempfile = tempfile;
191          return prog_mda (&mda_data);
192        }
193  #endif  #endif
194        
195    unlink (mda_data.tempfile);    unlink (tempfile);
196    for (; *argv; argv++)    for (; *argv; argv++)
197      mda (fp, *argv, NULL);      mda (fp, *argv, NULL);
198    return exit_code;    return exit_code;
# Line 280  mda (FILE *fp, char *username, mailbox_t Line 285  mda (FILE *fp, char *username, mailbox_t
285        if (attribute_is_deleted (attr))        if (attribute_is_deleted (attr))
286          return EX_OK;          return EX_OK;
287      }      }
288      
289    deliver (fp, username);    deliver (fp, username);
290    
291    if (multiple_delivery)    if (multiple_delivery)
# Line 332  make_tmp (const char *from, char **tempf Line 337  make_tmp (const char *from, char **tempf
337    FILE *fp;    FILE *fp;
338    char *buf = NULL;    char *buf = NULL;
339    size_t n = 0;    size_t n = 0;
340      int line;
341        
342    if (fd == -1 || (fp = fdopen(fd, "w+")) == NULL)    if (fd == -1 || (fp = fdopen (fd, "w+")) == NULL)
343      {      {
344        mailer_err("unable to open temporary file");        mailer_err ("unable to open temporary file");
345        exit (exit_code);        exit (exit_code);
346      }      }
     
   time (&t);  
   fprintf (fp, "From %s %s", from, ctime (&t));  
347    
348    while (getline(&buf, &n, stdin) > 0) {    line = 0;
349      if (!memcmp(buf, "From ", 5))    while (getline (&buf, &n, stdin) > 0) {
350        fputc('>', fp);      line++;
351        if (line == 1)
352          {
353            if (memcmp (buf, "From ", 5))
354              {
355                if (!from)
356                  {
357                    struct passwd *pw = getpwuid (uid);
358                    if (pw)
359                      from = pw->pw_name;
360                  }
361                if (from)
362                  {
363                    time (&t);
364                    fprintf (fp, "From %s %s", from, ctime (&t));
365                  }
366                else
367                  {
368                    mailer_err ("Can't determine sender address");
369                    exit (EX_UNAVAILABLE);
370                  }
371              }
372          }
373        else if (!memcmp (buf, "From ", 5))
374          fputc ('>', fp);
375      if (fputs (buf, fp) == EOF)      if (fputs (buf, fp) == EOF)
376        {        {
377          mailer_err ("temporary file write error");          mailer_err ("temporary file write error");
378          fclose(fp);          fclose (fp);
379          return NULL;          return NULL;
380        }        }
381    }    }
382    
383    if (buf && strchr(buf, '\n') == NULL)    if (buf && strchr (buf, '\n') == NULL)
384      putc('\n', fp);      putc ('\n', fp);
385    
386    putc('\n', fp);    putc ('\n', fp);
387    free (buf);    free (buf);
388        
389    return fp;    return fp;
# Line 459  deliver (FILE *fp, char *name) Line 486  deliver (FILE *fp, char *name)
486      {      {
487      case MQUOTA_EXCEEDED:      case MQUOTA_EXCEEDED:
488        mailer_err ("%s: mailbox quota exceeded for this recipient", name);        mailer_err ("%s: mailbox quota exceeded for this recipient", name);
489        exit_code = EX_UNAVAILABLE;        exit_code = EX_QUOTA();
490        failed++;        failed++;
491        break;        break;
492      case MQUOTA_UNLIMITED:      case MQUOTA_UNLIMITED:
# Line 475  deliver (FILE *fp, char *name) Line 502  deliver (FILE *fp, char *name)
502          {          {
503            mailer_err ("%s: message would exceed maximum mailbox size for this recipient",            mailer_err ("%s: message would exceed maximum mailbox size for this recipient",
504                        name);                        name);
505            exit_code = EX_UNAVAILABLE;            exit_code = EX_QUOTA();
506            failed++;            failed++;
507          }          }
508        break;        break;
# Line 503  deliver (FILE *fp, char *name) Line 530  deliver (FILE *fp, char *name)
530        free (buf);        free (buf);
531        switch_user_id (0);        switch_user_id (0);
532      }      }
533      
534      if (!failed)
535        notify_biff (mbox, name, size);
536    
537    locker_unlock (lock);    locker_unlock (lock);
538    /* FIXME: Flush the data */  
539    mailbox_close (mbox);    mailbox_close (mbox);
540    mailbox_destroy (&mbox);    mailbox_destroy (&mbox);
541  #if 0 /*FIXME*/  }
542    if (!failed)  
543      notify_biff (name, size);  void
544  #endif  notify_biff (mailbox_t mbox, char *name, size_t size)
545    {
546      static int fd = -1;
547      url_t url = NULL;
548      char *buf = NULL;
549      static struct sockaddr_in inaddr;
550        
551      if (fd == -1)
552        {
553          struct servent *sp;
554          
555          if ((sp = getservbyname ("biff", "udp")) == NULL)
556            return;
557    
558          inaddr.sin_family = AF_INET;
559          inaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
560          inaddr.sin_port = sp->s_port;
561          
562          fd = socket (AF_INET, SOCK_DGRAM, 0);
563          if (fd < 0)
564            fd = -2; /* Mark failed initialization */
565        }
566    
567      if (fd < 0)
568        return;
569      
570      mailbox_get_url (mbox, &url);
571      asprintf (&buf, "%s@%ld:%s", name, size, url_to_string (url));
572      if (buf)
573        {
574          sendto (fd, buf, strlen (buf), 0, (struct sockaddr *)&inaddr,
575                  sizeof inaddr);
576          free (buf);
577        }
578  }  }
579    
580  void  void
# Line 531  int temp_errors[] = { Line 594  int temp_errors[] = {
594  #ifdef EAGAIN  #ifdef EAGAIN
595    EAGAIN, /* Try again */    EAGAIN, /* Try again */
596  #endif  #endif
 #ifdef EDQUOT  
   EDQUOT, /* Disk quota esceeded */  
 #endif  
597  #ifdef EBUSY  #ifdef EBUSY
598    EBUSY, /* Device or resource busy */    EBUSY, /* Device or resource busy */
599  #endif  #endif
# Line 613  guess_retval (int ec) Line 673  guess_retval (int ec)
673    /* Temporary failures override hard errors. */    /* Temporary failures override hard errors. */
674    if (exit_code == EX_TEMPFAIL)    if (exit_code == EX_TEMPFAIL)
675      return;      return;
676    #ifdef EDQUOT
677      if (ec == EDQUOT)
678        {
679          exit_code = EX_QUOTA();
680          return;
681        }
682    #endif
683    
684    for (i = 0; i < sizeof (temp_errors)/sizeof (temp_errors[0]); i++)    for (i = 0; i < sizeof (temp_errors)/sizeof (temp_errors[0]); i++)
685      if (temp_errors[i] == ec)      if (temp_errors[i] == ec)
686        {        {
# Line 632  static char help_message[] = Line 700  static char help_message[] =
700  "   -h, --help               Display this help and exit\n"  "   -h, --help               Display this help and exit\n"
701  "   -L, --license            Display GNU General Public License\n"  "   -L, --license            Display GNU General Public License\n"
702  "   -m, --maildir PATH       Specify path to mailspool directory\n"  "   -m, --maildir PATH       Specify path to mailspool directory\n"
 "   -M, --multiple-delivery  Don't return errors when delivering to multiple\n"  
 "                            recipients\n"  
703  #ifdef USE_DBM  #ifdef USE_DBM
704  "   -q, --quota-db FILE      Specify path to quota database.\n"  "   -q, --quota-db FILE      Specify path to quota database.\n"
705  #endif  #endif
# Line 641  static char help_message[] = Line 707  static char help_message[] =
707  "   -s, --source PATTERN     Set name pattern for user-defined mail filters.\n"  "   -s, --source PATTERN     Set name pattern for user-defined mail filters.\n"
708  #endif  #endif
709  "   -t, --timeout NUMBER     Set timeout for acquiring the lockfile\n"  "   -t, --timeout NUMBER     Set timeout for acquiring the lockfile\n"
710    #ifdef WITH_GUILE
711    "   -x, --debug guile        Start with guile debugging evaluator and backtraces\n"
712    #endif
713  "   -x, --debug NUMBER       Set debugging level\n"  "   -x, --debug NUMBER       Set debugging level\n"
714  "   -v, --version            Display program version and exit.\n"  "   -v, --version            Display program version and exit.\n"
715    "   --ex-multiple-delivery-success Don't return errors when delivering to\n"
716    "                            multiple recipients\n"
717    "   --ex-quota-tempfail      Return temporary failure if disk or mailbox quota\n"
718    "                            is exceeded\n"
719  "\nReport bugs to bug-mailutils@gnu.org\n";  "\nReport bugs to bug-mailutils@gnu.org\n";
720    
721    printf ("%s", help_message);    printf ("%s", help_message);

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26