464c4b333041a8f23d529c21683ca1f1b100db5c
* Copyright (c) 1983 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
static char sccsid
[] = "@(#)cmds.c 5.4 (Berkeley) %G%";
* lpc -- line printer control program -- commands:
* kill an existing daemon and disable printing.
register char *cp1
, *cp2
;
printf("Usage: abort {all | printer ...}\n");
if (argc
== 2 && !strcmp(argv
[1], "all")) {
while (getprent(line
) > 0) {
while ((c
= *cp2
++) && c
!= '|' && c
!= ':')
if ((status
= pgetent(line
, printer
)) < 0) {
printf("cannot open printer description file\n");
} else if (status
== 0) {
printf("unknown printer %s\n", printer
);
if ((SD
= pgetstr("sd", &bp
)) == NULL
)
if ((LO
= pgetstr("lo", &bp
)) == NULL
)
(void) sprintf(line
, "%s/%s", SD
, LO
);
printf("%s:\n", printer
);
* Turn on the owner execute bit of the lock file to disable printing.
if (stat(line
, &stbuf
) >= 0) {
if (chmod(line
, (stbuf
.st_mode
& 0777) | 0100) < 0)
printf("\tcannot disable printing\n");
printf("\tprinting disabled\n");
} else if (errno
== ENOENT
) {
if ((fd
= open(line
, O_WRONLY
|O_CREAT
, 0760)) < 0)
printf("\tcannot create lock file\n");
printf("\tprinting disabled\n");
printf("\tno daemon to abort\n");
printf("\tcannot stat lock file\n");
* Kill the current daemon to stop printing now.
if ((fp
= fopen(line
, "r")) == NULL
) {
printf("\tcannot open lock file\n");
if (!getline(fp
) || flock(fileno(fp
), LOCK_SH
|LOCK_NB
) == 0) {
(void) fclose(fp
); /* unlocks as well */
printf("\tno daemon to abort\n");
if (kill(pid
= atoi(line
), SIGTERM
) < 0)
printf("\tWarning: daemon (pid %d) not killed\n", pid
);
printf("\tdaemon (pid %d) killed\n", pid
);
* Remove all spool files and temporaries from the spooling area.
register char *cp1
, *cp2
;
printf("Usage: clean {all | printer ...}\n");
if (argc
== 2 && !strcmp(argv
[1], "all")) {
while (getprent(line
) > 0) {
while ((c
= *cp2
++) && c
!= '|' && c
!= ':')
if ((status
= pgetent(line
, printer
)) < 0) {
printf("cannot open printer description file\n");
} else if (status
== 0) {
printf("unknown printer %s\n", printer
);
if ((c
== 't' || c
== 'c' || c
== 'd') && d
->d_name
[1] == 'f')
* Comparison routine for scandir. Sort by job number and machine, then
* by `cf', `tf', or `df', then by the sequence letter A-Z, a-z.
struct direct
**d1
, **d2
;
if (c1
= strcmp((*d1
)->d_name
+ 3, (*d2
)->d_name
+ 3))
return((*d1
)->d_name
[2] - (*d2
)->d_name
[2]);
if (c1
== 'd' || c2
== 'c')
* Remove incomplete jobs from spooling area.
register char *cp
, *cp1
, *lp
;
if ((SD
= pgetstr("sd", &bp
)) == NULL
)
printf("%s:\n", printer
);
for (lp
= line
, cp
= SD
; *lp
++ = *cp
++; )
nitems
= scandir(SD
, &queue
, select
, sortq
);
printf("\tcannot examine spool directory\n");
cp1
= queue
[i
+ 1]->d_name
;
if (*cp1
!= 'd' || strcmp(cp
+ 3, cp1
+ 3))
* Must be a df with no cf (otherwise, it would have
* been skipped above) or a tf file (which can always
printf("\tcannot remove %s\n", name
);
printf("\tremoved %s\n", name
);
* Enable queuing to the printer (allow lpr's).
register char *cp1
, *cp2
;
printf("Usage: enable {all | printer ...}\n");
if (argc
== 2 && !strcmp(argv
[1], "all")) {
while (getprent(line
) > 0) {
while ((c
= *cp2
++) && c
!= '|' && c
!= ':')
if ((status
= pgetent(line
, printer
)) < 0) {
printf("cannot open printer description file\n");
} else if (status
== 0) {
printf("unknown printer %s\n", printer
);
if ((SD
= pgetstr("sd", &bp
)) == NULL
)
if ((LO
= pgetstr("lo", &bp
)) == NULL
)
(void) sprintf(line
, "%s/%s", SD
, LO
);
printf("%s:\n", printer
);
* Turn off the group execute bit of the lock file to enable queuing.
if (stat(line
, &stbuf
) >= 0) {
if (chmod(line
, stbuf
.st_mode
& 0767) < 0)
printf("\tcannot enable queuing\n");
printf("\tqueuing enabled\n");
register char *cp1
, *cp2
;
printf("Usage: disable {all | printer ...}\n");
if (argc
== 2 && !strcmp(argv
[1], "all")) {
while (getprent(line
) > 0) {
while ((c
= *cp2
++) && c
!= '|' && c
!= ':')
if ((status
= pgetent(line
, printer
)) < 0) {
printf("cannot open printer description file\n");
} else if (status
== 0) {
printf("unknown printer %s\n", printer
);
if ((SD
= pgetstr("sd", &bp
)) == NULL
)
if ((LO
= pgetstr("lo", &bp
)) == NULL
)
(void) sprintf(line
, "%s/%s", SD
, LO
);
printf("%s:\n", printer
);
* Turn on the group execute bit of the lock file to disable queuing.
if (stat(line
, &stbuf
) >= 0) {
if (chmod(line
, (stbuf
.st_mode
& 0777) | 010) < 0)
printf("\tcannot disable queuing\n");
printf("\tqueuing disabled\n");
} else if (errno
== ENOENT
) {
if ((fd
= open(line
, O_WRONLY
|O_CREAT
, 0670)) < 0)
printf("\tcannot create lock file\n");
printf("\tqueuing disabled\n");
printf("\tcannot stat lock file\n");
* Disable queuing and printing and put a message into the status file
* (reason for being down).
register char *cp1
, *cp2
;
printf("Usage: down {all | printer} [message ...]\n");
if (!strcmp(argv
[1], "all")) {
while (getprent(line
) > 0) {
while ((c
= *cp2
++) && c
!= '|' && c
!= ':')
putmsg(argc
- 2, argv
+ 2);
if ((status
= pgetent(line
, printer
)) < 0) {
printf("cannot open printer description file\n");
} else if (status
== 0) {
printf("unknown printer %s\n", printer
);
putmsg(argc
- 2, argv
+ 2);
register char *cp1
, *cp2
;
if ((SD
= pgetstr("sd", &bp
)) == NULL
)
if ((LO
= pgetstr("lo", &bp
)) == NULL
)
if ((ST
= pgetstr("st", &bp
)) == NULL
)
printf("%s:\n", printer
);
* Turn on the group execute bit of the lock file to disable queuing and
* turn on the owner execute bit of the lock file to disable printing.
(void) sprintf(line
, "%s/%s", SD
, LO
);
if (stat(line
, &stbuf
) >= 0) {
if (chmod(line
, (stbuf
.st_mode
& 0777) | 0110) < 0)
printf("\tcannot disable queuing\n");
printf("\tprinter and queuing disabled\n");
} else if (errno
== ENOENT
) {
if ((fd
= open(line
, O_WRONLY
|O_CREAT
, 0770)) < 0)
printf("\tcannot create lock file\n");
printf("\tprinter and queuing disabled\n");
printf("\tcannot stat lock file\n");
* Write the message into the status file.
(void) sprintf(line
, "%s/%s", SD
, ST
);
fd
= open(line
, O_WRONLY
|O_CREAT
, 0664);
if (fd
< 0 || flock(fd
, LOCK_EX
) < 0) {
printf("\tcannot create status file\n");
(void) write(fd
, "\n", 1);
(void) write(fd
, buf
, strlen(buf
));
* Kill and restart the daemon.
register char *cp1
, *cp2
;
printf("Usage: restart {all | printer ...}\n");
if (argc
== 2 && !strcmp(argv
[1], "all")) {
while (getprent(line
) > 0) {
while ((c
= *cp2
++) && c
!= '|' && c
!= ':')
if ((status
= pgetent(line
, printer
)) < 0) {
printf("cannot open printer description file\n");
} else if (status
== 0) {
printf("unknown printer %s\n", printer
);
* Enable printing on the specified printer and startup the daemon.
register char *cp1
, *cp2
;
printf("Usage: start {all | printer ...}\n");
if (argc
== 2 && !strcmp(argv
[1], "all")) {
while (getprent(line
) > 0) {
while ((c
= *cp2
++) && c
!= '|' && c
!= ':')
if ((status
= pgetent(line
, printer
)) < 0) {
printf("cannot open printer description file\n");
} else if (status
== 0) {
printf("unknown printer %s\n", printer
);
if ((SD
= pgetstr("sd", &bp
)) == NULL
)
if ((LO
= pgetstr("lo", &bp
)) == NULL
)
(void) sprintf(line
, "%s/%s", SD
, LO
);
printf("%s:\n", printer
);
* Turn off the owner execute bit of the lock file to enable printing.
if (enable
&& stat(line
, &stbuf
) >= 0) {
if (chmod(line
, stbuf
.st_mode
& (enable
==2 ? 0666 : 0677)) < 0)
printf("\tcannot enable printing\n");
printf("\tprinting enabled\n");
if (!startdaemon(printer
))
printf("\tcouldn't start daemon\n");
printf("\tdaemon started\n");
* Print the status of each queue listed or all the queues.
register char *cp1
, *cp2
;
while (getprent(line
) > 0) {
while ((c
= *cp2
++) && c
!= '|' && c
!= ':')
if ((status
= pgetent(line
, printer
)) < 0) {
printf("cannot open printer description file\n");
} else if (status
== 0) {
printf("unknown printer %s\n", printer
);
* Print the status of the printer queue.
register struct direct
*dp
;
if ((SD
= pgetstr("sd", &bp
)) == NULL
)
if ((LO
= pgetstr("lo", &bp
)) == NULL
)
if ((ST
= pgetstr("st", &bp
)) == NULL
)
printf("%s:\n", printer
);
(void) sprintf(line
, "%s/%s", SD
, LO
);
if (stat(line
, &stbuf
) >= 0) {
printf("\tqueuing is %s\n",
(stbuf
.st_mode
& 010) ? "disabled" : "enabled");
printf("\tprinting is %s\n",
(stbuf
.st_mode
& 0100) ? "disabled" : "enabled");
printf("\tqueuing is enabled\n");
printf("\tprinting is enabled\n");
if ((dirp
= opendir(SD
)) == NULL
) {
printf("\tcannot examine spool directory\n");
while ((dp
= readdir(dirp
)) != NULL
) {
if (*dp
->d_name
== 'c' && dp
->d_name
[1] == 'f')
printf("\tno entries\n");
printf("\t1 entry in spool area\n");
printf("\t%d entries in spool area\n", i
);
fd
= open(line
, O_RDONLY
);
if (fd
< 0 || flock(fd
, LOCK_SH
|LOCK_NB
) == 0) {
(void) close(fd
); /* unlocks as well */
printf("\tno daemon present\n");
(void) sprintf(line
, "%s/%s", SD
, ST
);
fd
= open(line
, O_RDONLY
);
(void) flock(fd
, LOCK_SH
);
while ((i
= read(fd
, line
, sizeof(line
))) > 0)
(void) fwrite(line
, 1, i
, stdout
);
(void) close(fd
); /* unlocks as well */
* Stop the specified daemon after completing the current job and disable
register char *cp1
, *cp2
;
printf("Usage: stop {all | printer ...}\n");
if (argc
== 2 && !strcmp(argv
[1], "all")) {
while (getprent(line
) > 0) {
while ((c
= *cp2
++) && c
!= '|' && c
!= ':')
if ((status
= pgetent(line
, printer
)) < 0) {
printf("cannot open printer description file\n");
} else if (status
== 0) {
printf("unknown printer %s\n", printer
);
if ((SD
= pgetstr("sd", &bp
)) == NULL
)
if ((LO
= pgetstr("lo", &bp
)) == NULL
)
(void) sprintf(line
, "%s/%s", SD
, LO
);
printf("%s:\n", printer
);
* Turn on the owner execute bit of the lock file to disable printing.
if (stat(line
, &stbuf
) >= 0) {
if (chmod(line
, (stbuf
.st_mode
& 0777) | 0100) < 0)
printf("\tcannot disable printing\n");
printf("\tprinting disabled\n");
} else if (errno
== ENOENT
) {
if ((fd
= open(line
, O_WRONLY
|O_CREAT
, 0760)) < 0)
printf("\tcannot create lock file\n");
printf("\tprinting disabled\n");
printf("\tcannot stat lock file\n");
* Put the specified jobs at the top of printer queue.
printf("Usage: topq printer [jobnum ...] [user ...]\n");
status
= pgetent(line
, printer
);
printf("cannot open printer description file\n");
} else if (status
== 0) {
printf("%s: unknown printer\n", printer
);
if ((SD
= pgetstr("sd", &bp
)) == NULL
)
if ((LO
= pgetstr("lo", &bp
)) == NULL
)
printf("%s:\n", printer
);
printf("\tcannot chdir to %s\n", SD
);
mtime
= queue
[0]->q_time
;
if (doarg(argv
[i
]) == 0) {
printf("\tjob %s is not in the queue\n", argv
[i
]);
for (i
= 0; i
< nitems
; i
++)
printf("\tqueue order unchanged\n");
* Turn on the public execute bit of the lock file to
* get lpd to rebuild the queue after the current job.
if (changed
&& stat(LO
, &stbuf
) >= 0)
(void) chmod(LO
, (stbuf
.st_mode
& 0777) | 01);
* Reposition the job by changing the modification time of
tvp
[0].tv_sec
= tvp
[1].tv_sec
= --mtime
;
tvp
[0].tv_usec
= tvp
[1].tv_usec
= 0;
return(utimes(q
->q_name
, tvp
));
* Checks if specified job name is in the printer's queue.
* Returns: negative (-1) if argument name is not in the queue.
register struct queue
**qq
;
register char *cp
, *machine
;
* Look for a job item consisting of system name, colon, number
if ((cp
= index(job
, ':')) != NULL
) {
* Check for job specified by number (example: 112 or 235ucbarpa).
jobnum
= jobnum
* 10 + (*job
++ - '0');
for (qq
= queue
+ nitems
; --qq
>= queue
; ) {
for (cp
= (*qq
)->q_name
+3; isdigit(*cp
); )
n
= n
* 10 + (*cp
++ - '0');
if (*job
&& strcmp(job
, cp
) != 0)
if (machine
!= NULL
&& strcmp(machine
, cp
) != 0)
printf("\tmoved %s\n", (*qq
)->q_name
);
* Process item consisting of owner's name (example: henry).
for (qq
= queue
+ nitems
; --qq
>= queue
; ) {
if ((fp
= fopen((*qq
)->q_name
, "r")) == NULL
)
if (line
[0] != 'P' || strcmp(job
, line
+1) != 0)
printf("\tmoved %s\n", (*qq
)->q_name
);
* Enable everything and start printer (undo `down').
register char *cp1
, *cp2
;
printf("Usage: up {all | printer ...}\n");
if (argc
== 2 && !strcmp(argv
[1], "all")) {
while (getprent(line
) > 0) {
while ((c
= *cp2
++) && c
!= '|' && c
!= ':')
if ((status
= pgetent(line
, printer
)) < 0) {
printf("cannot open printer description file\n");
} else if (status
== 0) {
printf("unknown printer %s\n", printer
);