reindent-20030715
[openafs.git] / src / procmgmt / afskill.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 /* Kill command based on process management library (procmgmt.h).
11  * Intended for use on Windows NT, where it will only signal processes
12  * linked with the process management library (except SIGKILL).
13  */
14
15 #include <afsconfig.h>
16 #include <afs/param.h>
17
18 RCSID
19     ("$Header$");
20
21 #include <afs/stds.h>
22
23 #include <stddef.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <errno.h>
27 #include <string.h>
28
29 #include "procmgmt.h"
30
31
32 /* Define NULL-terminated array of signal name/number pairs */
33 typedef struct {
34     char *name;
35     int number;
36 } signal_map_t;
37
38 static signal_map_t signalMap[] = {
39     {"HUP", SIGHUP},
40     {"INT", SIGINT},
41     {"QUIT", SIGQUIT},
42     {"ILL", SIGILL},
43     {"ABRT", SIGABRT},
44     {"FPE", SIGFPE},
45     {"KILL", SIGKILL},
46     {"SEGV", SIGSEGV},
47     {"TERM", SIGTERM},
48     {"USR1", SIGUSR1},
49     {"USR2", SIGUSR2},
50     {"CLD", SIGCLD},
51     {"CHLD", SIGCHLD},
52     {"TSTP", SIGTSTP},
53     {NULL, 0}
54 };
55
56
57 static void
58 PrintSignalList(void)
59 {
60     int i;
61
62     for (i = 0; signalMap[i].name; i++) {
63         printf("%s ", signalMap[i].name);
64     }
65     printf("\n");
66 }
67
68 static int
69 SignalArgToNumber(const char *sigargp)
70 {
71     long signo;
72     char *endp;
73     int i;
74
75     /* check for numeric signal arg */
76     errno = 0;
77     signo = strtol(sigargp, &endp, 0);
78
79     if (errno == 0 && *endp == '\0') {
80         return (int)signo;
81     }
82
83     /* check for named signal arg */
84     for (i = 0; signalMap[i].name; i++) {
85         if (!strcasecmp(signalMap[i].name, sigargp)) {
86             return signalMap[i].number;
87         }
88     }
89
90     return -1;                  /* invalid signal argument */
91 }
92
93
94 static void
95 PrintUsage(const char *whoami)
96 {
97     printf("usage: %s [-signal] [pid] ...\n", whoami);
98     printf("       %s -l\n", whoami);
99 }
100
101
102
103 int
104 main(int argc, char *argv[])
105 {
106     int status = 0;
107     char *whoami;
108
109     /* set whoami to last component of argv[0] */
110     if ((whoami = strrchr(argv[0], '/')) != NULL) {
111         whoami++;
112     } else if ((whoami = strrchr(argv[0], '\\')) != NULL) {
113         whoami++;
114     } else {
115         whoami = argv[0];
116     }
117
118     /* parse command arguments */
119     if (argc <= 1) {
120         /* no arguments; print usage statement */
121         PrintUsage(whoami);
122
123     } else if (!strcmp(argv[1], "-l")) {
124         /* request to print a list of valid signals */
125         PrintSignalList();
126
127     } else {
128         /* request to send a signal */
129         int i;
130         int signo = SIGTERM;    /* SIGTERM is default if no signal specified */
131
132         for (i = 1; i < argc; i++) {
133             char *curargp = argv[i];
134
135             if (i == 1 && *curargp == '-') {
136                 /* signal argument specified; translate to a number */
137                 curargp++;      /* advance past signal flag indicator ('-') */
138
139                 if ((signo = SignalArgToNumber(curargp)) == -1) {
140                     printf("%s: unknown signal %s.\n", whoami, curargp);
141                     PrintUsage(whoami);
142                     status = 1;
143                     break;
144                 }
145             } else {
146                 /* pid specified; send signal */
147                 long pid;
148                 char *endp;
149
150                 errno = 0;
151                 pid = strtol(curargp, &endp, 0);
152
153                 if (errno != 0 || *endp != '\0' || pid <= 0) {
154                     printf("%s: invalid pid value %s.\n", whoami, curargp);
155                     status = 1;
156                 } else {
157                     if (kill((pid_t) pid, signo)) {
158                         if (errno == EINVAL) {
159                             printf("%s: invalid signal number %d.\n", whoami,
160                                    signo);
161                             status = 1;
162                             break;
163
164                         } else if (errno == ESRCH) {
165                             printf("%s: no such process %d.\n", whoami,
166                                    (int)pid);
167                             status = 1;
168
169                         } else if (errno == EPERM) {
170                             printf("%s: no privilege to signal %d.\n", whoami,
171                                    (int)pid);
172                             status = 1;
173
174                         } else {
175                             printf("%s: failed to signal %d (errno = %d).\n",
176                                    whoami, (int)pid, (int)errno);
177                             status = 1;
178                         }
179                     }
180                 }
181             }
182         }
183     }
184
185     return status;
186 }