chiark / gitweb /
debugging for thing that crashed
[innduct.git] / expire / grephistory.c
1 /*  $Id: grephistory.c 7041 2004-12-19 08:33:49Z rra $
2 **
3 **  Get data from history database.
4 */
5
6 #include "clibrary.h"
7 #include <syslog.h>  
8 #include <sys/stat.h>
9
10 #include "inn/history.h"
11 #include "inn/innconf.h"
12 #include "inn/messages.h"
13 #include "libinn.h"
14 #include "paths.h"
15 #include "storage.h"
16
17 /*
18 **  Read stdin for list of Message-ID's, output list of ones we
19 **  don't have.  Or, output list of files for ones we DO have.
20 */
21 static void
22 IhaveSendme(struct history *h, char What)
23 {
24     char                *p;
25     char                *q;
26     char                buff[BUFSIZ];
27
28     while (fgets(buff, sizeof buff, stdin) != NULL) {
29         time_t arrived, posted, expires;
30         TOKEN token;
31
32         for (p = buff; ISWHITE(*p); p++)
33             ;
34         if (*p != '<')
35             continue;
36         for (q = p; *q && *q != '>' && !ISWHITE(*q); q++)
37             ;
38         if (*q != '>')
39             continue;
40         *++q = '\0';
41
42         if (!HIScheck(h, p)) {
43             if (What == 'i')
44                 printf("%s\n", p);
45             continue;
46         }
47
48         /* Ihave -- say if we want it, and continue. */
49         if (What == 'i') {
50             continue;
51         }
52
53         if (HISlookup(h, p, &arrived, &posted, &expires, &token))
54             printf("%s\n", TokenToText(token));
55     }
56 }
57
58
59 /*
60 **  Print a usage message and exit.
61 */
62 static void
63 Usage(void)
64 {
65     fprintf(stderr, "Usage: grephistory [flags] MessageID\n");
66     exit(1);
67 }
68
69
70 int
71 main(int ac, char *av[])
72 {
73     int                 i;
74     const char          *History;
75     char                *key;
76     char                What;
77     struct history      *history;
78     time_t arrived, posted, expires;
79     TOKEN token;
80     unsigned int        Verbosity = 0;
81
82     /* First thing, set up logging and our identity. */
83     openlog("grephistory", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
84     message_program_name = "grephistory";
85
86     /* Set defaults. */
87     if (!innconf_read(NULL))
88         exit(1);
89
90     History = concatpath(innconf->pathdb, _PATH_HISTORY);
91
92     What = '?';
93
94     /* Parse JCL. */
95     while ((i = getopt(ac, av, "vf:eilnqs")) != EOF)
96         switch (i) {
97         default:
98             Usage();
99             /* NOTREACHED */
100         case 'v':
101             Verbosity++;
102             break;
103         case 'f':
104             History = optarg;
105             break;
106         case 'e':
107         case 'i':
108         case 'l':
109         case 'n':
110         case 'q':
111         case 's':
112             if (What != '?') {
113                 die("only one [eilnqs] flag allowed");
114             }
115             What = (char)i;
116             break;
117         }
118     ac -= optind;
119     av += optind;
120
121     history = HISopen(History, innconf->hismethod, HIS_RDONLY);
122     if (history == NULL)
123         die("cannot open history");
124
125     /* Set operating mode. */
126     switch (What) {
127     case '?':
128         What = 'n';
129         break;
130     case 'i':
131     case 's':
132         IhaveSendme(history, What);
133         HISclose(history);
134         exit(0);
135         /* NOTREACHED */
136     }
137
138     /* All modes other than -i -l want a Message-ID. */
139     if (ac != 1)
140         Usage();
141
142     key = av[0];
143     if (*key == '[') {
144         warn("accessing history by hash isn't supported");
145         HISclose(history);
146         exit(1);
147     } else {
148         /* Add optional braces if not already present. */
149         if (*key != '<')
150             key = concat("<", key, ">", (char *) 0);
151     }
152
153     if (!HIScheck(history, key)) {
154         if (What == 'n') {
155             if (Verbosity > 0)
156                 die("not found (hash is %s)", HashToText(HashMessageID(key)));
157             else
158                 die("not found");
159         }
160     }
161     else if (What != 'q') {
162         if (HISlookup(history, key, &arrived, &posted, &expires, &token)) {
163             if (What == 'l') {
164                 printf("[]\t%ld~-~%ld\t%s\n", (long)arrived, (long)posted,
165                        TokenToText(token));
166             }
167             else {
168                 if (Verbosity > 0)
169                     printf("%s (hash is %s)\n", TokenToText(token),
170                             HashToText(HashMessageID(key)));
171                 else
172                     printf("%s\n", TokenToText(token));
173             }
174         }
175         else if (What == 'n')
176             printf("/dev/null\n");
177     }
178     HISclose(history);
179     return 0;
180 }