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