2 Copyright (C) 2001-2005 Ben Kibbey <bjk@arbornet.org>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Try and kill off a users login process(s). This needs the userinfo utility
21 * from http://arbornet.org/~bjk/userinfo/ with the login.so module loaded
22 * and chained (-x) before this module.
25 * gcc -O2 -g -Wall -shared -fPIC -o kill.so kill.c
28 * ui -x login.so -p -- -O ./kill.so --
30 * Or with any other options you'd want. Just make sure the first option to
31 * the login module is -p.
33 * Ben Kibbey <bjk@arbornet.org>
38 #include <sys/types.h>
46 #define KILL_OPTION_STRING "s:"
48 void add_string(char ***, int *, char *);
58 static struct signals sigs
[] = {
94 void kill_init(int *chainable
)
96 do_sigs
= realloc(do_sigs
, (sig_index
+ 2) * sizeof(int *));
97 do_sigs
[sig_index
++] = 1;
98 do_sigs
= realloc(do_sigs
, (sig_index
+ 2) * sizeof(int *));
99 do_sigs
[sig_index
++] = 9;
114 printf(" Kill a login process; requires login.so (-s SIGHUP,9):\n");
115 printf("\t-s Send these comma separated signals (integers or strings).\n\n");
119 char *kill_options_init(char **defaults
)
122 return KILL_OPTION_STRING
;
125 int kill_options(int argc
, char **argv
)
129 while ((opt
= getopt(argc
, argv
, KILL_OPTION_STRING
)) != -1) {
137 while ((tmp
= strsep(&optarg
, ",")) != NULL
) {
144 for (i
= 0; sigs
[i
].sig
!= -1; i
++) {
145 if (sig
== sigs
[i
].sig
) {
146 do_sigs
= realloc(do_sigs
, (sig_index
+ 2) * sizeof(int *));
147 do_sigs
[sig_index
++] = sig
;
153 for (i
= 0; sigs
[i
].name
; i
++) {
154 if (strcasecmp(tmp
, sigs
[i
].name
) == 0) {
155 do_sigs
= realloc(do_sigs
, (sig_index
+ 2) * sizeof(int *));
156 do_sigs
[sig_index
++] = sigs
[i
].sig
;
161 warnx("kill.so: invalid signal -- %s", tmp
);
166 warnx("kill.so: invalid option -- %c", optopt
);
175 static int killit(pid_t pid
, int sig
)
177 if (kill(pid
, 0) == -1)
180 if (kill(pid
, sig
) == -1)
186 int kill_exec(char ***result
, const struct passwd
*pw
, const int
187 multi
, const int verbose
, const char *tf
)
190 char **strings
= NULL
;
191 int strings_index
= 0;
193 char line
[LINE_MAX
] = {'\0'};
195 char m
[2] = {multi
, '\0'};
198 add_string(&strings
, &strings_index
, "!");
200 /* There may be more than one pid for multiple logins. Separated the
201 * output with the multi-string deliminator and send the signals to each
203 while ((tmp
= strsep(&*result
[0], m
)) != NULL
) {
206 if (isdigit(*tmp
) == 0) {
207 strncat(line
, "!", sizeof(line
));
208 strncat(line
, m
, sizeof(line
));
213 for (i
= 0; i
< sig_index
; i
++) {
214 if (killit(pid
, do_sigs
[i
]) == 0) {
222 strncat(line
, s
, sizeof(line
));
223 strncat(line
, m
, sizeof(line
));
228 line
[strlen(line
) - 1] = '\0';
229 add_string(&strings
, &strings_index
, line
);