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