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