source: trunk/athena/bin/discuss/libds/dsc_enter.c @ 12439

Revision 12439, 5.9 KB checked in by kcr, 26 years ago (diff)
Autoconfiscation and cleanup.
Line 
1/*
2 *
3 *      Copyright (C) 1988, 1989 by the Massachusetts Institute of Technology
4 *      Developed by the MIT Student Information Processing Board (SIPB).
5 *      For copying information, see the file mit-copyright.h in this release.
6 *
7 */
8/*
9 * dsc_enter.c - enter a transaction from a file into discuss.
10 *
11 *      $Id: dsc_enter.c,v 1.13 1999-02-02 20:40:26 kcr Exp $
12 */
13
14#ifndef lint
15static char rcsid[] =
16    "$Id: dsc_enter.c,v 1.13 1999-02-02 20:40:26 kcr Exp $";
17#endif
18
19#include <stdio.h>
20#include <string.h>
21#if HAVE_FCNTL_H
22#include <fcntl.h>
23#endif
24#include <unistd.h>
25#include <errno.h>
26#include <ctype.h>
27#include <sys/types.h>
28#include <regex.h>
29
30#include <discuss/tfile.h>
31#include <discuss/types.h>
32
33/*
34 * Externals.
35 */
36
37extern tfile unix_tfile();
38
39#define DEFAULT_SUBJECT "No subject found in mail header"
40
41char *dsc_enter_deflist[] = {
42        "^cc$", "^date$", "^from$","^to$","-cc$","-to$","-from$",
43        NULL
44};
45               
46static void strndowncpy();
47static bool list_compare();
48
49/*
50 * The stream `source' is assumed to contain a transaction in
51 * approximate RFC822 format.
52 *
53 * An attempt is made to `censor' its headers and enter it in the
54 * discuss meeting `mtg_path' on `mtg_host'.
55 */
56
57dsc_enter(file, mtg_host, mtg_path, trn_no)
58        FILE *file;
59        char *mtg_host, *mtg_path;
60        int *trn_no;
61{
62        return dsc_enter_filter(file, mtg_host, mtg_path,
63                                dsc_enter_deflist, (char **)NULL, trn_no);
64}
65
66/*
67 * Macro which defines the matching algorithm.
68 */
69#define field_ok(key, save, reject) \
70        ((((save) == NULL) || list_compare((key), (save))) && \
71         (((reject) == NULL) || !list_compare((key), (reject))))
72
73/*
74 * The stream `source' is assumed to contain a transaction in
75 * approximate RFC822 format.
76 *
77 * An attempt is made to scan its headers and
78 * enter it in the discuss meeting `mtg_path' on `mtg_host'.
79 *
80 * If `accept_headers' is non-NULL, only headers maching the regexps
81 * are allowed.
82 *
83 * If `reject_headers' is non-NULL, headers maching the regexps in it
84 * are explicitly rejected.
85 */
86
87dsc_enter_filter(source, mtg_host, mtg_path, accept_headers,
88                 reject_headers, trn_no)
89        FILE *source;
90        char *mtg_host;
91        char *mtg_path;
92        char *accept_headers[], *reject_headers[]; /* NULL terminated. */
93        int *trn_no;                    /* Transaction number entered. */
94{
95        int fd;                         /* Temporary file descriptor */
96        FILE *f;                        /* Temporary file pointer */
97        tfile transaction;              /* Also points to temp file. */
98
99        char line[BUFSIZ+1];            /* Current line. */
100        char key[BUFSIZ+1];             /* Keyword for line. */
101        char subject[BUFSIZ+1];         /* Transaction subject. */
102
103        bool no_subject_yet = TRUE;     /* No subject seen yet? */
104        bool ok_prev = FALSE;           /* Prev header line ok? */
105        bool iscont = FALSE;            /* This line is continuation? */
106
107        int reply_to = 0;               /* Transaction number to reply to. */
108        int header_count = 0;           /* Header line count */
109       
110        int fatal;                      /* Do we lose contacting the mtg? */
111        int result;                     /* Return code */
112
113        char filename[60];              /* temporary filename */
114        char module[1024];              /* discuss RPC module name */
115
116        register int i;                 /* iteration variable */
117
118        static char *subjlist[] = {     /* matches subject: */
119                "subject",  NULL
120        };
121
122        static char *inreplyto[] = {    /* matches in-reply-to: */
123                "in-reply-to",  NULL
124        };
125
126        /*
127         * Find a temporary file.
128         */
129        (void) mktemp(strcpy(filename, "/tmp/DSXXXXXX"));
130       
131        if ((fd = open(filename, O_RDWR|O_EXCL|O_CREAT, 0600)) < 0 ||
132            (f = fdopen(fd, "w+")) == NULL) {
133                result = errno;
134                goto out;
135        }
136       
137        reply_to = 0;
138       
139        for (;;) {
140                if (fgets(line, BUFSIZ, source) == NULL ||
141                    line[0] == '\n' ||
142                    strcmp(line, "--text follows this line--") == 0)
143                        break;
144                else if (isspace(line[0]))
145                        iscont = TRUE;
146                else if (!iscont) {
147                        /* skip to colon, if any */
148                        for (i=0; line[i] && line[i] != ':'; i++)
149                                continue;
150                       
151                        strndowncpy(key, line, i);
152                       
153                        if (list_compare (key, subjlist)) {
154                                /*
155                                 * skip whitespace at start of
156                                 * subject.
157                                 */     
158
159                                while(isspace(line[++i])) ;
160
161                                /*
162                                 * if luser tries two subject lines, we
163                                 * ignore the second subject line
164                                 */
165
166                                if (no_subject_yet) {
167                                        int len;
168                                        (void) strcpy(subject, line+i);
169                                        len = strlen(subject);
170                                        if (len && (subject[--len] == '\n'))
171                                                subject[len]='\0';
172                                        no_subject_yet = FALSE;
173                                }       
174                        } else if (list_compare (key, inreplyto)) {
175                                char *cp;
176                                /*
177                                 * Look for a trn number between [].
178                                 */
179                                if ((cp = strchr(line,'[')) && strchr(cp, ']')) {
180                                        cp++;
181                                        if (isdigit(*cp))
182                                                reply_to = atoi(cp);
183                                }
184                        }
185                }
186                ok_prev = ((iscont && ok_prev) ||
187                           (!iscont && field_ok(key, accept_headers, reject_headers)));
188                if (ok_prev) {
189                        header_count++;
190                        fputs(line, f);
191                }
192                iscont = line[strlen(line)-1] != '\n';
193        }
194        if (header_count > 0) {
195                fputs("\n", f);
196        }
197        /* copy rest of message */
198        while (fgets(line,BUFSIZ,source) != NULL) {
199                fputs(line, f);
200        }
201        /* did it really get there? */
202        if (fflush(f) == EOF) {
203                result = errno;
204                goto out;
205        }
206        /* overwrite subject */
207        if (no_subject_yet)
208                (void) strcpy(subject, DEFAULT_SUBJECT);
209
210        /* find the server */
211        (void) strcpy(module, "discuss@");
212        (void) strcat(&module[8], mtg_host);
213
214        init_rpc();
215        set_module(module, &fatal, &result);
216        if (result && fatal) goto out;
217
218        /* back to the beginning */
219        (void) rewind(f);
220        (void) lseek(fileno(f), (long)0, SEEK_SET);
221        /* create transaction stream */
222        transaction = unix_tfile(fileno(f));
223
224        /* drop it in the meeting */
225        add_trn(mtg_path, transaction, subject, reply_to, trn_no, &result);
226       
227out:
228        if (f) {
229                (void) fclose(f);
230        }
231        if (transaction) tdestroy(transaction);
232        (void) unlink(filename);
233
234        return result;
235}
236
237static bool list_compare(s,list)
238        char *s,**list;
239{
240        regex_t reg;
241
242        while (*list!=NULL) {
243                if (regcomp(&reg, *list++, REG_NOSUB) != 0)
244                        return(FALSE);
245                if (regexec(&reg, s, 0, NULL, 0) == 0) {
246                        regfree(&reg);
247                        return(TRUE);
248                }
249                regfree(&reg);
250        }
251        return(FALSE);
252}
253
254static void strndowncpy(dp, sp, count)
255        register char *dp, *sp;
256        register int count;
257{
258        register unsigned char c;
259
260        while ((c = *sp++) && count > 0) {
261            *dp++ = isupper(c) ? tolower(c) : c;
262            count--;
263        }
264        *dp++ = '\0';
265}
Note: See TracBrowser for help on using the repository browser.