Rearranged whitespace (and comments) in all the code!
[mmh] / uip / whom.c
1 /*
2  * whom.c -- report to whom a message would be sent
3  *
4  * This code is Copyright (c) 2002, by the authors of nmh.  See the
5  * COPYRIGHT file in the root directory of the nmh distribution for
6  * complete copyright information.
7  */
8
9 #include <h/mh.h>
10 #include <h/signals.h>
11 #include <signal.h>
12
13 static struct swit switches[] = {
14 #define ALIASW  0
15         { "alias aliasfile", 0 },
16 #define CHKSW  1
17         { "check", 0 },
18 #define NOCHKSW  2
19         { "nocheck", 0 },
20 #define DRAFTSW  3
21         { "draft", 0 },
22 #define DFOLDSW  4
23         { "draftfolder +folder", 6 },
24 #define DMSGSW  5
25         { "draftmessage msg", 6 },
26 #define NDFLDSW  6
27         { "nodraftfolder", 0 },
28 #define VERSIONSW  7
29         { "version", 0 },
30 #define HELPSW  8
31         { "help", 0 },
32 #define CLIESW  9
33         { "client host", -6 },
34 #define SERVSW  10
35         { "server host", -6 },
36 #define SNOOPSW  11
37         { "snoop", -5 },
38 #define PORTSW  15
39         { "port server port name/number", 4 },
40         { NULL, 0 }
41 };
42
43
44 int
45 main (int argc, char **argv)
46 {
47         pid_t child_id;
48         int i, status, isdf = 0;
49         int distsw = 0, vecp = 0;
50         char *cp, *dfolder = NULL, *dmsg = NULL;
51         char *msg = NULL, **ap, **argp, backup[BUFSIZ];
52         char buf[BUFSIZ], **arguments, *vec[MAXARGS];
53
54 #ifdef LOCALE
55         setlocale(LC_ALL, "");
56 #endif
57         invo_name = r1bindex (argv[0], '/');
58
59         /* read user profile/context */
60         context_read();
61
62         arguments = getarguments (invo_name, argc, argv, 1);
63         argp = arguments;
64
65         vec[vecp++] = invo_name;
66         vec[vecp++] = "-whom";
67         vec[vecp++] = "-library";
68         vec[vecp++] = getcpy (m_maildir (""));
69
70         while ((cp = *argp++)) {
71                 if (*cp == '-') {
72                         switch (smatch (++cp, switches)) {
73                                 case AMBIGSW:
74                                         ambigsw (cp, switches);
75                                         done (1);
76                                 case UNKWNSW:
77                                         adios (NULL, "-%s unknown", cp);
78
79                                 case HELPSW:
80                                         snprintf (buf, sizeof(buf), "%s [switches] [file]", invo_name);
81                                         print_help (buf, switches, 1);
82                                         done (1);
83                                 case VERSIONSW:
84                                         print_version(invo_name);
85                                         done (1);
86
87                                 case CHKSW:
88                                 case NOCHKSW:
89                                 case SNOOPSW:
90                                         vec[vecp++] = --cp;
91                                         continue;
92
93                                 case DRAFTSW:
94                                         msg = draft;
95                                         continue;
96
97                                 case DFOLDSW:
98                                         if (dfolder)
99                                                 adios (NULL, "only one draft folder at a time!");
100                                         if (!(cp = *argp++) || *cp == '-')
101                                                 adios (NULL, "missing argument to %s", argp[-2]);
102                                         dfolder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp,
103                                                         *cp != '@' ? TFOLDER : TSUBCWF);
104                                         continue;
105                                 case DMSGSW:
106                                         if (dmsg)
107                                                 adios (NULL, "only one draft message at a time!");
108                                         if (!(dmsg = *argp++) || *dmsg == '-')
109                                                 adios (NULL, "missing argument to %s", argp[-2]);
110                                         continue;
111                                 case NDFLDSW:
112                                         dfolder = NULL;
113                                         isdf = NOTOK;
114                                         continue;
115
116                                 case ALIASW:
117                                 case CLIESW:
118                                 case SERVSW:
119                                 case PORTSW:
120                                         vec[vecp++] = --cp;
121                                         if (!(cp = *argp++) || *cp == '-')
122                                                 adios (NULL, "missing argument to %s", argp[-2]);
123                                         vec[vecp++] = cp;
124                                         continue;
125                         }
126                 }
127                 if (msg)
128                         adios (NULL, "only one draft at a time!");
129                 else
130                         vec[vecp++] = msg = cp;
131         }
132
133         /* allow Aliasfile: profile entry */
134         if ((cp = context_find ("Aliasfile"))) {
135                 char *dp = NULL;
136
137                 for (ap = brkstring(dp = getcpy(cp), " ", "\n"); ap && *ap; ap++) {
138                         vec[vecp++] = "-alias";
139                         vec[vecp++] = *ap;
140                 }
141         }
142
143         if (msg == NULL) {
144 #ifdef WHATNOW
145                 if (dfolder || (cp = getenv ("mhdraft")) == NULL || *cp == '\0')
146 #endif /* WHATNOW */
147                         cp  = getcpy (m_draft (dfolder, dmsg, 1, &isdf));
148                 msg = vec[vecp++] = cp;
149         }
150         if ((cp = getenv ("mhdist"))
151                         && *cp
152                         && (distsw = atoi (cp))
153                         && (cp = getenv ("mhaltmsg"))
154                         && *cp) {
155                 if (distout (msg, cp, backup) == NOTOK)
156                         done (1);
157                 vec[vecp++] = "-dist";
158                 distsw++;
159         }
160         vec[vecp] = NULL;
161
162         closefds (3);
163
164         if (distsw) {
165                 for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++)
166                         sleep (5);
167         }
168
169         switch (distsw ? child_id : OK) {
170                 case NOTOK:
171                                 advise (NULL, "unable to fork, so checking directly...");
172                 case OK:
173                         execvp (postproc, vec);
174                         fprintf (stderr, "unable to exec ");
175                         perror (postproc);
176                         _exit (-1);
177
178                 default:
179                         SIGNAL (SIGHUP, SIG_IGN);
180                         SIGNAL (SIGINT, SIG_IGN);
181                         SIGNAL (SIGQUIT, SIG_IGN);
182                         SIGNAL (SIGTERM, SIG_IGN);
183
184                         status = pidwait(child_id, OK);
185
186                         unlink (msg);
187                         if (rename (backup, msg) == NOTOK)
188                                 adios (msg, "unable to rename %s to", backup);
189                         done (status);
190         }
191
192         return 0;  /* dead code to satisfy the compiler */
193 }