1 /* $NetBSD: rmjob.c,v 1.24 2009/01/18 09:57:26 lukem Exp $ */
4 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
35 static char sccsid
[] = "@(#)rmjob.c 8.2 (Berkeley) 4/28/95";
37 __RCSID("$NetBSD: rmjob.c,v 1.24 2009/01/18 09:57:26 lukem Exp $");
41 #include <sys/param.h>
53 #include "pathnames.h"
56 * rmjob - remove the specified jobs from the queue.
60 * Stuff for handling lprm specifications
62 extern char *user
[]; /* users to process */
63 extern int users
; /* # of users in user array */
64 extern int requ
[]; /* job number of spool entries */
65 extern int requests
; /* # of spool requests */
66 extern char *person
; /* name of person doing lprm */
68 static char root
[] = "root";
69 static int all
= 0; /* eliminate all files (root only) */
70 static int cur_daemon
; /* daemon's pid */
71 static char current
[40]; /* active control file name */
73 extern uid_t uid
, euid
; /* real and effective user id's */
75 static void do_unlink(const char *);
76 static void alarmer(int);
83 struct dirent
**files
;
88 * If the format was `lprm -' and the user isn't the super-user,
89 * then fake things to look like he said `lprm user'.
93 all
= 1; /* all files in local queue */
99 if (!strcmp(person
, "-all")) {
101 fatal("The login name \"-all\" is reserved");
102 all
= 1; /* all those from 'from' */
108 fatal("cannot chdir to spool directory");
109 if ((nitems
= scandir(".", &files
, iscf
, NULL
)) < 0)
110 fatal("cannot access spool directory");
115 * Check for an active printer daemon (in which case we
116 * kill it if it is reading our file) then remove stuff
117 * (after which we have to restart the daemon).
119 if (lockchk(LO
) && chk(current
)) {
121 assasinated
= kill(cur_daemon
, SIGINT
) == 0;
124 fatal("cannot kill printer daemon");
129 for (i
= 0; i
< nitems
; i
++)
130 process(files
[i
]->d_name
);
134 * Restart the printer daemon if it was killed
136 if (assasinated
&& !startdaemon(printer
))
137 fatal("cannot restart printer daemon\n");
142 * Process a lock file: collect the pid of the active
143 * daemon and the file name of the active spool entry.
144 * Return boolean indicating existence of a lock file.
147 lockchk(const char *s
)
153 if ((fp
= fopen(s
, "r")) == NULL
) {
155 fatal("can't access lock file");
162 return(0); /* no daemon present */
164 cur_daemon
= atoi(line
);
165 if (kill(cur_daemon
, 0) < 0 && errno
!= EPERM
) {
167 return(0); /* no daemon present */
169 for (i
= 1; (n
= fread(current
, sizeof(char), sizeof(current
), fp
)) <= 0; i
++) {
182 * Process a control file.
185 process(const char *file
)
192 if ((cfp
= fopen(file
, "r")) == NULL
)
193 fatal("cannot open %s", file
);
195 while (get_line(cfp
)) {
197 case 'U': /* unlink associated files */
198 if (strchr(line
+1, '/') || strncmp(line
+1, "df", 2))
208 do_unlink(const char *file
)
213 printf("%s: ", host
);
217 printf(ret
? "cannot dequeue %s\n" : "%s dequeued\n", file
);
221 * Do the dirty work in checking
224 chk(const char *file
)
232 * Check for valid cf file name (mostly checking current).
234 if (strlen(file
) < 7 || file
[0] != 'c' || file
[1] != 'f')
237 if (all
&& (from
== host
|| !strcmp(from
, file
+6)))
241 * get the owner's name from the control file.
244 if ((cfp
= fopen(file
, "r")) == NULL
)
247 while (get_line(cfp
)) {
255 if (users
== 0 && requests
== 0)
256 return(!strcmp(file
, current
) && isowner(line
+1, file
));
258 * Check the request list
260 for (n
= 0, cp
= file
+3; isdigit((unsigned char)*cp
); )
261 n
= n
* 10 + (*cp
++ - '0');
262 for (r
= requ
; r
< &requ
[requests
]; r
++)
263 if (*r
== n
&& isowner(line
+1, file
))
266 * Check to see if it's in the user list
268 for (u
= user
; u
< &user
[users
]; u
++)
269 if (!strcmp(*u
, line
+1) && isowner(line
+1, file
))
275 * If root is removing a file on the local machine, allow it.
276 * If root is removing a file from a remote machine, only allow
277 * files sent from the remote machine to be removed.
278 * Normal users can only remove the file from where it was sent.
281 isowner(const char *owner
, const char *file
)
283 if (!strcmp(person
, root
) && (from
== host
|| !strcmp(from
, file
+6)))
285 if (!strcmp(person
, owner
) && !strcmp(from
, file
+6))
288 printf("%s: ", host
);
289 printf("%s: Permission denied\n", file
);
294 * Check to see if we are sending files to a remote machine. If we are,
295 * then try removing files on the remote machine.
305 return; /* not sending to a remote machine */
308 * Flush stdout so the user can see what has been deleted
309 * while we wait (possibly) for the connection.
313 /* \5 RP space all */
314 len
= 1 + strlen(RP
) + 1 + strlen(all
? "-all" : person
);
315 for (i
= 0; i
< users
; i
++) {
316 len
+= strlen(user
[i
]) + 1;
318 for (i
= 0; i
< requests
; i
++) {
319 len
+= snprintf(line
, sizeof(line
), " %d", requ
[i
]);
323 if (len
> sizeof(line
))
329 cp
+= snprintf(s
, len
, "\5%s %s", RP
, all
? "-all" : person
);
330 for (i
= 0; i
< users
; i
++) {
332 strncpy(cp
, user
[i
], len
- (cp
- s
) - 2);
335 for (i
= 0; i
< requests
; i
++) {
336 (void)snprintf(cp
, len
- (cp
- s
) - 1, " %d", requ
[i
]);
345 printf("%s: ", host
);
346 printf("connection to %s is down\n", RM
);
348 struct sigaction osa
, nsa
;
350 if ((size_t)write(rem
, s
, len
) != len
)
351 fatal("Lost connection");
352 if (len
> sizeof(line
))
354 nsa
.sa_handler
= alarmer
;
355 sigemptyset(&nsa
.sa_mask
);
356 sigaddset(&nsa
.sa_mask
, SIGALRM
);
358 (void)sigaction(SIGALRM
, &nsa
, &osa
);
360 while ((i
= read(rem
, line
, sizeof(line
))) > 0) {
361 (void)fwrite(line
, 1, (size_t)i
, stdout
);
365 (void)sigaction(SIGALRM
, &osa
, NULL
);
377 * Return 1 if the filename begins with 'cf'
380 iscf(const struct dirent
*d
)
382 return(d
->d_name
[0] == 'c' && d
->d_name
[1] == 'f');