home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / fax-3.2.1 / cmd / faxspooler / queue_entry.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-31  |  8.0 KB  |  353 lines

  1. /*
  2.   This file is part of the NetFax system.
  3.  
  4.   (c) Copyright 1989 by David M. Siegel. 
  5.       All rights reserved.
  6.  
  7.     This program is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation.
  10.  
  11.     This program is distributed in the hope that it will be useful, 
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of 
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. */
  20.  
  21. #include <stdio.h>
  22. #include <malloc.h>
  23. #include <strings.h>
  24. #include <dirent.h>
  25. #include <sys/param.h>
  26.  
  27. #include "../../lib/libfax/libfax.h"
  28. #include "spooler.h"
  29. #include "queue_entry.h"
  30.  
  31. static int parse_string(), write_string(), parse_recip(), write_recip(),
  32.   parse_int(), write_int(), write_bit();
  33.  
  34. #define arg(f)  ((int)(&(((QueueEntry *)NULL)->f)))
  35. #define sarg(f) ((int)(((QueueEntry *)NULL)->f))
  36.  
  37. static struct _queue_switch {
  38.     char *ident;
  39.     int (*parse_func)();
  40.     int (*write_func)();
  41.     int offset;
  42.     int flag;
  43. } queue_switch[] = {
  44.     {"FILE",  parse_string, write_string, sarg(file), QUEUE_F_FILE},
  45.     {"USER",  parse_string, write_string, sarg(user), QUEUE_F_USER},
  46.     {"EMAIL", NULL,         write_bit,       NULL,       QUEUE_F_EMAIL},
  47.     {"RETRY", parse_int,    write_int,      arg(retry), QUEUE_F_RETRY}, 
  48.     {"TIME",  parse_int,    write_int,      arg(time),  QUEUE_F_TIME},
  49.     {"PAGES", parse_int,    write_int,      arg(pages), QUEUE_F_PAGES},
  50.     {"RECIP", parse_recip,  write_recip,  0,          QUEUE_F_RECIP},
  51. };
  52. #define queue_switch_len (sizeof(queue_switch)/sizeof(struct _queue_switch))
  53.  
  54. #undef arg
  55. #undef sarg
  56.  
  57. /* ARGSUSED */
  58. static int write_bit(qe, offset, key, fp)
  59.      QueueEntry *qe;
  60.      char *offset;
  61.      char *key;
  62.      FILE *fp;
  63. {
  64.     fprintf(fp, "%s:\n", key);
  65.  
  66.     return (0);
  67. }
  68.  
  69. /* ARGSUSED */
  70. static int parse_string(qe, offset, start)
  71.      QueueEntry *qe;
  72.      char *offset;
  73.      char *start;
  74. {
  75.     if (sscanf(start, "%s", offset) != 1)
  76.       return (-1);
  77.     
  78.     return (0);
  79. }
  80.  
  81. /* ARGSUSED */
  82. static int write_string(qe, offset, key, fp)
  83.      QueueEntry *qe;
  84.      char *offset;
  85.      char *key;
  86.      FILE *fp;
  87. {
  88.     fprintf(fp, "%s: %s\n", key, offset);
  89.  
  90.     return (0);
  91. }
  92.  
  93. /* ARGSUSED */
  94. static int parse_int(qe, offset, start)
  95.      QueueEntry *qe;
  96.      char *offset;
  97.      char *start;
  98. {
  99.     int *value = (int *)offset;
  100.     
  101.     if (sscanf(start, "%d", value) != 1)
  102.       return (-1);
  103.  
  104.     return (0);
  105. }
  106.  
  107. /* ARGSUSED */
  108. static int write_int(qe, offset, key, fp)
  109.      QueueEntry *qe;
  110.      char *offset;
  111.      char *key;
  112.      FILE *fp;
  113. {
  114.     int *value = (int *)offset;
  115.  
  116.     fprintf(fp, "%s: %d\n", key, *value);
  117.  
  118.     return (0);
  119. }
  120.  
  121. /* ARGSUSED */
  122. static int parse_recip(qe, offset, start)
  123.      QueueEntry *qe;
  124.      char *offset;
  125.      char *start;
  126. {
  127.     Recip *r;
  128.  
  129.     if ((r = (Recip *)calloc(1, sizeof(Recip))) == NULL) {
  130.     log(L_EMERG, "parse_recip: malloc failed: %m");
  131.     return (-1);
  132.     }
  133.  
  134.     /*
  135.      * Perform a simple parse of the recipient args.
  136.      */
  137.     if (sscanf(start, "%d %d %s %d %d %d",
  138.            &r->status, &r->dialer_code, r->phone, 
  139.            &r->attempts, &r->time_first, &r->time_last) != 6) {
  140.     log(L_WARNING, "parse recip failed");
  141.     return (-1);
  142.     }
  143.  
  144.     /*
  145.      * Perhaps this is a kludge, but when we restart we don't
  146.      * want to leave the entry in a state of sending.
  147.      */
  148.     if (r->status == SEND_STATUS_SENDING)
  149.       r->status = SEND_STATUS_PENDING;
  150.  
  151.     /*
  152.      * Add the recipient to the list of recipients.
  153.      */
  154.     list_add(qe->recip_list, (char *)r);
  155.  
  156.     return (0);
  157. }
  158.  
  159. static void write_a_recip(r, fp, key)
  160.      Recip *r;
  161.      FILE *fp;
  162.      char *key;
  163. {
  164.     fprintf(fp, "%s: %d %d %s %d %d %d\n",
  165.         key, r->status, r->dialer_code, r->phone, r->attempts, 
  166.         r->time_first, r->time_last);
  167. }
  168.  
  169. /* ARGSUSED */
  170. static int write_recip(qe, offset, key, fp)
  171.      QueueEntry *qe;
  172.      char *offset;
  173.      char *key;
  174.      FILE *fp;
  175. {
  176.     list_map(qe->recip_list, write_a_recip, fp, key);
  177.  
  178.     return (0);
  179. }
  180.  
  181. static int validate(qe)
  182.      QueueEntry *qe;
  183. {
  184.     if (!(qe->flags & QUEUE_F_FILE)) {
  185.     log(L_WARNING, "queue entry missing file name");
  186.     return (-1);
  187.     }
  188.  
  189.     if (!(qe->flags & QUEUE_F_USER)) {
  190.     log(L_WARNING, "queue entry missing user name");
  191.     return (-1);
  192.     }
  193.  
  194.     if (!(qe->flags & QUEUE_F_RECIP)) {
  195.     log(L_WARNING, "queue entry has no recipients");
  196.     return (-1);
  197.     }
  198.  
  199.     return (0);
  200. }
  201.  
  202. void queue_entry_free(qe)
  203.      QueueEntry *qe;
  204. {
  205.     list_free(qe->recip_list);
  206.     free(qe->recip_list);
  207.     cfree(qe);
  208. }
  209.  
  210. QueueEntry *queue_entry_read(filename)
  211.      char *filename;
  212. {
  213.     FILE *fp;
  214.     QueueEntry *qe;
  215.     char buf[1024];
  216.  
  217.     log(L_DEBUG, "reading queue file: %s", filename);
  218.  
  219.     if ((fp = fopen(filename, "r")) == NULL) {
  220.     log(L_WARNING, "can't open queue file %s for reading: %m", filename);
  221.     return (NULL);
  222.     }
  223.  
  224.     if ((qe = (QueueEntry *)calloc(1, sizeof(QueueEntry))) == NULL) {
  225.     log(L_EMERG, "can't malloc queue file storage: %m");
  226.     return (NULL);
  227.     }
  228.  
  229.     if ((qe->recip_list = list_make(NULL, free)) == NULL) {
  230.     log(L_EMERG, "can't make recipient list: %m");
  231.     return (NULL);
  232.     }
  233.  
  234.     while (fgets(buf, sizeof(buf), fp) != NULL) {
  235.     char *delim;
  236.     int i;
  237.  
  238.     if ((delim = index(buf, ':')) == NULL) {
  239.         log(L_WARNING, "missing ':' in queue file: %s", buf);
  240.         fclose(fp);
  241.         return (NULL);
  242.     }
  243.  
  244.     for (i = 0; i < queue_switch_len; i++) {
  245.         struct _queue_switch *qs = &queue_switch[i];
  246.         if (strncmp(qs->ident, buf, strlen(qs->ident)) == 0) {
  247.         qe->flags |= qs->flag;
  248.         if (qs->parse_func != NULL)
  249.           if ((*qs->parse_func)(qe, &((char *)qe)[qs->offset], delim+2)
  250.               < 0)
  251.             log(L_WARNING, "error reading qf \"%s\"", buf);
  252.         }
  253.     }
  254.     }
  255.  
  256.     fclose(fp);
  257.  
  258.     if (validate(qe) < 0) {
  259.     log(L_WARNING, "validation of qf %s failed", filename);
  260.     queue_entry_free(qe);
  261.     return (NULL);
  262.     }
  263.  
  264.     return (qe);
  265. }
  266.  
  267. int queue_entry_write(qe, qdir)
  268.      QueueEntry *qe;
  269.      char *qdir;
  270. {
  271.     char pathname[MAXPATHLEN];
  272.     FILE *fp;
  273.     int i;
  274.  
  275.     sprintf(pathname, "%s/%s/QF", qdir, qe->file);
  276.     if ((fp = fopen(pathname, "w+")) == NULL) {
  277.     log(L_WARNING, "can't open queue file %s for writing: %m", pathname);
  278.     return (-1);
  279.     }
  280.  
  281.     for (i = 0; i < queue_switch_len; i++) {
  282.     struct _queue_switch *qs = &queue_switch[i];
  283.     if (qs->flag & qe->flags)
  284.       if ((*qs->write_func)(qe, &((char *)qe)[qs->offset], qs->ident, fp)
  285.           < 0)
  286.         log(L_WARNING, "error writing qf");
  287.     }
  288.  
  289.     fclose(fp);
  290.  
  291.     return (0);
  292. }
  293.  
  294. /*
  295.  * Removes all the files associated with a queue entry.  Returns -1
  296.  * if something couldn't be deleted, though the function tries
  297.  * to delete as much as it can.
  298.  */
  299. int queue_entry_delete_files(file, qdir)
  300.      char *file;
  301.      char *qdir;
  302. {
  303.     char pathname[MAXPATHLEN];
  304.     DIR *dirp;
  305.     struct dirent *dp;
  306.     int rc = 0;
  307.     
  308.     sprintf(pathname, "%s/%s", qdir, file);
  309.  
  310.     log(L_DEBUG, "deleting queue files from: %s", pathname);
  311.  
  312.     if ((dirp = opendir(pathname)) == NULL) {
  313.     log(L_INFO, "error opening dir %s: %m", pathname);
  314.     rc = -1;
  315.     } else {
  316.     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  317.         char file[MAXPATHLEN];
  318.         if (strcmp(dp->d_name, ".") == 0)
  319.           continue;
  320.         if (strcmp(dp->d_name, "..") == 0)
  321.           continue;
  322.         sprintf(file, "%s/%s", pathname, dp->d_name);
  323.         if (unlink(file) < 0) {
  324.         log(L_INFO, "error deleting %s: %m", file);
  325.         rc = -1;
  326.         }
  327.     }
  328.     }
  329.     if (rmdir(pathname) < 0) {
  330.     log(L_INFO, "error deleting %s: %m", pathname);
  331.     return (-1);
  332.     }
  333.  
  334.     return (rc);
  335. }
  336.  
  337. static void print_a_recip(r)
  338.      Recip *r;
  339. {
  340.     printf("status=%d; dialer_code=%d; phone=%s; attempts=%d; times=%d,%d\n",
  341.        r->status, r->dialer_code, r->phone, r->attempts, 
  342.        r->time_first, r->time_last);
  343. }
  344.  
  345. void queue_entry_print(qe)
  346.      QueueEntry *qe;
  347. {
  348.     printf("*** %s\n", qe->file);
  349.     printf("flags=0x%x\n", qe->flags);
  350.     printf("recipients:\n");
  351.     list_map(qe->recip_list, print_a_recip);
  352. }
  353.