b393232c5476bac6ae621802c5dfb16f62428e4d
[openafs.git] / src / bozo / smail-notifier.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13
14 #include <afs/stds.h>
15 #include <sys/types.h>
16 #include <sys/file.h>
17 #include <sys/time.h>
18 #include <sys/stat.h>
19 #include <netdb.h>
20 #include <netinet/in.h>
21 #include <stdio.h>
22 #include <afs/afsutil.h>
23
24 /*
25  * XXX CHANGE the following depedent stuff XXX
26  */
27 #define SENDMAIL        "/afs/cellname/fs/dev/localtools/dest/bin/rcs-sendmail"
28 /*
29  * Replace it with  a bboard (i.e. transarc.bosserver.auto-reports)
30  */
31 #define RECIPIENT       "foo@cellname"
32
33 #include "AFS_component_version_number.c"
34
35 main(argc, argv)
36      int argc;
37      char **argv;
38 {
39     struct stat tstat;
40     FILE *fin = stdin;
41     char buf[BUFSIZ], *bufp, *bufp1, *typep, *cmd, *bp;
42     register afs_int32 code, c, fd, id, pflags = -1, len, core = 0, lastE = 0;
43     char comLine[60], coreName[40], name[40], lastErrorName[50];
44     afs_int32 pid = -1, lastExit = -1, lastSignal = -1, rsTime = -1, rsCount =
45         -1;
46     afs_int32 procStartTime = -1, procStarts = -1;
47     afs_int32 lastAnyExit = -1, lastErrorExit = -1, errorCode =
48         -1, errorSignal = -1, goal = -1;
49     char *timeStamp;
50
51     typep = (char *)malloc(50);
52     cmd = (char *)malloc(50);
53     bufp = bufp1 = (char *)malloc(1000);
54     while (fgets(buf, sizeof(buf), fin)) {
55         code = sscanf(buf, "%s %s\n", typep, cmd);
56         if (code < 2) {
57             continue;
58         }
59         if (!strcmp(typep, "BEGIN") && !strcmp(cmd, "bnode_proc")) {
60             while (fgets(buf, sizeof(buf), fin)) {
61                 code = sscanf(buf, "%s %s\n", typep, cmd);
62                 if (code < 2) {
63                     printf("**bnode_proc**: typed=%s, cmd=%s\n", typep, cmd);
64                     break;
65                 }
66                 if (!strcmp(typep, "comLine:"))
67                     strcpy(comLine, cmd);
68                 else if (!strcmp(typep, "coreName:"))
69                     strcpy(coreName, cmd);
70                 else if (!strcmp(typep, "pid:"))
71                     pid = atoi(cmd);
72 #ifdef  notdef
73                 else if (!strcmp(typep, "lastExit:"))
74                     lastExit = atoi(cmd);
75                 else if (!strcmp(typep, "lastSignal:"))
76                     lastSignal = atoi(cmd);
77 #endif
78                 else if (!strcmp(typep, "flags:"))
79                     pflags = atoi(cmd);
80                 else if (!strcmp(typep, "END")) {
81                     break;
82                 } else {
83                     printf
84                         ("Unexpected token %s in the bnode_proc (should be END)\n",
85                          typep);
86                     exit(1);
87                 }
88             }
89         } else if (!strcmp(typep, "BEGIN") && !strcmp(cmd, "bnode")) {
90             while (fgets(buf, sizeof(buf), fin)) {
91                 code = sscanf(buf, "%s %s\n", typep, cmd);
92                 if (code < 2) {
93                     printf("**bnode**: typed=%s, cmd=%s\n", typep, cmd);
94                     break;
95                 }
96                 if (!strcmp(typep, "name:"))
97                     strcpy(name, cmd);
98                 else if (!strcmp(typep, "rsTime:"))
99                     rsTime = atoi(cmd);
100                 else if (!strcmp(typep, "rsCount:"))
101                     rsCount = atoi(cmd);
102                 else if (!strcmp(typep, "procStartTime:"))
103                     procStartTime = atoi(cmd);
104                 else if (!strcmp(typep, "procStarts:"))
105                     procStarts = atoi(cmd);
106                 else if (!strcmp(typep, "lastAnyExit:"))
107                     lastAnyExit = atoi(cmd);
108                 else if (!strcmp(typep, "lastErrorExit:"))
109                     lastErrorExit = atoi(cmd);
110                 else if (!strcmp(typep, "errorCode:"))
111                     errorCode = atoi(cmd);
112                 else if (!strcmp(typep, "errorSignal:"))
113                     errorSignal = atoi(cmd);
114 /*
115                 else if (!strcmp(typep, "lastErrorName:"))
116                     strcpy(lastErrorName, cmd);
117 */
118                 else if (!strcmp(typep, "goal:"))
119                     goal = atoi(cmd);
120                 else if (!strcmp(typep, "END")) {
121                     break;
122                 } else {
123                     printf
124                         ("Unexpected token %s in the bnode (should be END)\n",
125                          typep);
126                     exit(1);
127                 }
128             }
129         } else {
130             printf("Unexpected token %s (should be BEGIN)\n", typep);
131             exit(1);
132         }
133     }
134     /*
135      * Now make up the text for the post
136      */
137     sprintf(buf, "/tmp/snote.%d", getpid());
138     fd = open(buf, O_RDWR | O_CREAT | O_TRUNC, 0600);
139     if (fd == -1) {
140         perror(buf);
141         printf("Unable to create temp file, %s\n", buf);
142         exit(1);
143     }
144     (void)sprintf(bufp, "Subject: Bosserver's automatic notification\n\n");
145     bufp += strlen(bufp);
146     (void)sprintf(bufp,
147                   "AUTOMATIC NOTIFICATION EVENT FOR AFS SERVER INSTANCE %s\n\n",
148                   name);
149     bufp += strlen(bufp);
150     (void)sprintf(bufp, "Server Process id was: %d\n", pid);
151     bufp += strlen(bufp);
152     (void)sprintf(bufp, "Server command line: %s\n", comLine);
153     bufp += strlen(bufp);
154     if (strcmp(coreName, "(null)"))
155         core = 1;
156     bp = comLine;
157     strcpy(bp, AFSDIR_SERVER_CORELOG_FILEPATH);
158     if (core) {
159         strcat(bp, coreName);
160         strcat(bp, ".");
161     }
162     strcat(bp, name);
163     if ((code = stat(bp, &tstat)) == 0) {
164         c = 1;
165         if ((lastAnyExit - tstat.st_ctime) > 300)       /* > 5 mins old */
166             c = 0;
167         core = 1;
168     } else
169         core = 0;
170     strcat(bp, " ");
171     (void)sprintf(bufp, "There is %score dump left %sfor this server\n",
172                   (core ? (c ? "a recent " : "an 'old' ") : "no "),
173                   (core ? bp : ""));
174     bufp += strlen(bufp);
175 #ifdef  notdef
176     (void)sprintf(bufp, "Last Exit code %d\n", lastExit);
177     bufp += strlen(bufp);
178     (void)sprintf(bufp, "Last Signal number %d\n", lastSignal);
179     bufp += strlen(bufp);
180 #endif
181     if (pflags == 1)
182         strcpy(bp, "PROCESS STARTED");
183     else if (pflags == 2)
184         strcpy(bp, "PROCESS EXITED");
185     else
186         strcpy(bp, "UNKNOWN");
187     (void)sprintf(bufp, "Process state %d (%s)\n", pflags, bp);
188     bufp += strlen(bufp);
189     timeStamp = ctime(&rsTime);
190     timeStamp[24] = 0;
191     (void)sprintf(bufp, "\nNumber of restarts since %s is %d\n", timeStamp,
192                   rsCount);
193     bufp += strlen(bufp);
194     if (procStartTime) {
195         timeStamp = ctime(&procStartTime);
196         timeStamp[24] = 0;
197         (void)sprintf(bufp,
198                       "Number of process restarts since the process started %s is %d\n",
199                       timeStamp, procStarts);
200     }
201     bufp += strlen(bufp);
202     if (lastAnyExit) {
203         timeStamp = ctime(&lastAnyExit);
204         timeStamp[24] = 0;
205         (void)sprintf(bufp, "Last time process exited for any reason: %s\n",
206                       timeStamp);
207     }
208     bufp += strlen(bufp);
209     if (lastErrorExit) {
210         timeStamp = ctime(&lastErrorExit);
211         timeStamp[24] = 0;
212         (void)sprintf(bufp, "Last time process exited unexpectedly: %s\n",
213                       timeStamp);
214     }
215     bufp += strlen(bufp);
216     (void)sprintf(bufp, "Last exit return code %d\n", errorCode);
217     bufp += strlen(bufp);
218     (void)sprintf(bufp, "Last process terminating signal %d\n", errorSignal);
219     bufp += strlen(bufp);
220 #ifdef  notdef
221     if (strcmp(lastErrorName, "(null)"))
222         lastE = 1;
223     if (lastE) {
224         (void)sprintf(bufp,
225                       "Short name of process that failed last in this bnode is: %s\n",
226                       lastErrorName);
227         bufp += strlen(bufp);
228     }
229 #endif
230     (void)sprintf(bufp, "The server is now %srunning\n",
231                   (goal ? "" : "not "));
232     bufp += strlen(bufp);
233     len = (int)(bufp - bufp1);
234     if (write(fd, bufp1, len) < 0) {
235         perror("Write");
236         exit(1);
237     }
238     close(fd);
239     /*
240      * Send the mail out
241      */
242     sprintf(bufp1, "%s %s -s TESTING < %s", SENDMAIL, RECIPIENT, buf);
243     code = system(bufp1);
244     unlink(buf);
245     exit(0);
246 }