home *** CD-ROM | disk | FTP | other *** search
- Subject: v16i029: Public lineprinter spooler package, Part16/16
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: papowell@julius.cs.umn.edu
- Posting-number: Volume 16, Issue 29
- Archive-name: plp/part16
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 16 (of 16)."
- # Contents: src/control_ops.c
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'src/control_ops.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/control_ops.c'\"
- else
- echo shar: Extracting \"'src/control_ops.c'\" \(28050 characters\)
- sed "s/^X//" >'src/control_ops.c' <<'END_OF_FILE'
- X/***************************************************************************
- X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
- X ***************************************************************************
- X * MODULE: Control_ops.c
- X ***************************************************************************
- X * Revision History: Created Mon Jan 18 07:48:12 CST 1988
- X * $Log: control_ops.c,v $
- X * Revision 3.2 88/06/24 17:55:14 papowell
- X * MODS for VAX 4.3BSD UNIX
- X *
- X * Revision 3.1 88/06/18 09:34:02 papowell
- X * Version 3.0- Distributed Sat Jun 18 1988
- X *
- X * Revision 2.2 88/05/14 10:21:23 papowell
- X * Modified -X flag handling
- X *
- X * Revision 2.1 88/05/09 10:07:50 papowell
- X * PLP: Released Version
- X *
- X * Revision 1.9 88/04/28 11:02:11 papowell
- X * removed unused variables, shuts up lint
- X *
- X * Revision 1.8 88/04/27 17:59:14 papowell
- X * Added debugging statements to C_lpq, C_lprm
- X *
- X * Revision 1.7 88/04/07 12:31:32 papowell
- X *
- X * Revision 1.6 88/04/06 12:12:24 papowell
- X * Minor updates, changes in error message formats.
- X * Elimination of the AF_UNIX connections, use AF_INET only.
- X * Better error messages.
- X *
- X * Revision 1.5 88/03/25 14:59:13 papowell
- X * Debugged Version:
- X * 1. Added the PLP control file first transfer
- X * 2. Checks for MX during file transfers
- X * 3. Found and fixed a mysterious bug involving the SYSLOG facilities;
- X * apparently they open files and then assume that they will stay
- X * open.
- X * 4. Made sure that stdin, stdout, stderr was available at all times.
- X *
- X * Revision 1.4 88/03/12 10:03:38 papowell
- X * *** empty log message ***
- X *
- X * Revision 1.3 88/03/11 19:29:57 papowell
- X * Minor Changes, Updates
- X *
- X * Revision 1.2 88/03/05 15:01:56 papowell
- X * Minor Corrections, Lint Problems
- X *
- X * Revision 1.1 88/03/01 11:08:19 papowell
- X * Initial revision
- X *
- X ***************************************************************************/
- X#ifndef lint
- static char id_str1[] =
- X "$Header: control_ops.c,v 3.2 88/06/24 17:55:14 papowell Exp $ PLP Copyright 1988 Patrick Powell";
- X#endif lint
- X
- X#include "lp.h"
- X
- X/***************************************************************************
- X * Control_ops()
- X * 1. get the printcap entries
- X * 2. check for permissions
- X * 3. determine the function to be carried out
- X * 4. carry out the function
- X ***************************************************************************/
- static int op_init; /* flag for operation initialization */
- X
- X
- X/*
- X * dispatch is a data structure that contains the names and flagss
- X * of control commands.
- X */
- struct dispatch{
- X char *name;
- X int distinct;
- X int (*routine)();
- X int flags;
- X char *summary;
- X};
- X
- int C_bad(), C_help(), C_abort(), C_clean(), C_disable(),
- X C_enable(), C_exit(), C_kill(), C_restart(), C_lpq(), C_lprm(),
- X C_start(), C_status(), C_stop(), C_topq(), C_remote(), C_lpd();
- X
- X#define NEED_OPT 1 /* we check for other options */
- X#define ALL_ALLOWED 2 /* check for all */
- X#define NEED_PRIV 4 /* privileged operation */
- X#define ALL_DEF 8 /* if no parameter, all is default */
- X#define NO_PR_LIST 0x10 /* printer list */
- X#define REMOTE_OP 0x20 /* remote allowed */
- X#define SERVER_OP 0x40 /* server allowed */
- X#define ON_REMOTE 0x80 /* not if you have RM and NW */
- X#define IS_OPT(x) ((x)&NEED_OPT)
- X#define IS_ALL(x) ((x)&ALL_ALLOWED)
- X#define IS_PRIV(x) ((x)&NEED_PRIV)
- X#define IS_ALL_DEF(x) ((x)&ALL_DEF)
- X#define IS_NO_PR_LIST(x) ((x)&NO_PR_LIST)
- X#define IS_REMOTE(x) ((x)&REMOTE_OP)
- X#define IS_SERVER(x) ((x)&SERVER_OP)
- X#define IS_ON_REMOTE(x) ((x)&ON_REMOTE)
- X
- static struct dispatch
- dispatch[] = {
- X{ "", 0, 0, 0, "not a command" },
- X{ "?", 1, C_help, 0, "? is same as 'help'" },
- X{ "abort", 1, C_abort,
- X NEED_OPT | NEED_PRIV |ALL_ALLOWED |REMOTE_OP |SERVER_OP |ON_REMOTE,
- X "abort ( all | Printer ): kill off server and disable printing" },
- X{ "clean", 1, C_clean, NEED_OPT | NEED_PRIV |ALL_ALLOWED |REMOTE_OP |ON_REMOTE,
- X "clean ( all | Printer ): remove all crud from queue (dangerous!)"},
- X{ "disable", 1, C_disable, NEED_OPT | NEED_PRIV |ALL_ALLOWED |REMOTE_OP |ON_REMOTE,
- X "disable ( all | Printer ): disable queueing"},
- X{ "enable", 2, C_enable, NEED_OPT | NEED_PRIV |ALL_ALLOWED |REMOTE_OP |ON_REMOTE,
- X "enable ( all | Printer ): enable queuing"},
- X{ "exit", 2, C_exit, 0, "exit: terminate" },
- X{ "help", 1, C_help, 0 ,"help [all] [command]: print command summary"},
- X{ "kill", 1, C_kill,
- X NEED_OPT | NEED_PRIV |ALL_ALLOWED |REMOTE_OP |SERVER_OP |ON_REMOTE,
- X "kill ( all | Printer ): kill off server and then restart printing" },
- X{ "lpd", 3, C_lpd, 0,
- X "lpd : check out lpd process"},
- X{ "lpq", 3, C_lpq, 0,
- X "lpq ( parms ) : call lpq"},
- X{ "lprm", 3, C_lprm, 0,
- X "lprm ( parms ) : call lpq"},
- X{ "quit", 1, C_exit, 0, "quit (same as exit): terminate" },
- X{ "remote", 3, C_remote, 0,
- X "remote command: do the action on remote printer"},
- X{ "restart", 3, C_restart, NEED_OPT | ALL_ALLOWED |REMOTE_OP |SERVER_OP,
- X "restart ( all | Printer ): start a server"},
- X{ "start", 4, C_start,
- X NEED_OPT | NEED_PRIV |ALL_ALLOWED |REMOTE_OP |SERVER_OP |ON_REMOTE,
- X "start ( all | Printer ): enable printing and start server"},
- X{ "status", 4, C_status, ALL_DEF |ALL_ALLOWED | NEED_OPT,
- X "status [all] [Printer]: print status"},
- X{ "stop", 3, C_stop,
- X NEED_OPT | NEED_PRIV |ALL_ALLOWED |REMOTE_OP |SERVER_OP |ON_REMOTE,
- X "stop ( all | Printer ): disable further printing"},
- X{ "topq", 1, C_topq, NO_PR_LIST | NEED_OPT |REMOTE_OP | ON_REMOTE| NEED_PRIV,
- X "topq Printer (Host | jobnumber)*: move job to top of queue"},
- X};
- int ncmds = sizeof(dispatch)/sizeof(struct dispatch);
- X
- X/***************************************************************************
- X * Control_ops()
- X * This routine is called with the parameters in the Parms[] array.
- X * It will check to see if the command is valid, and if so, will
- X * do any other actions.
- X ***************************************************************************/
- int
- Control_ops()
- X{
- X int command; /* command we are going to do */
- X char **list; /* list of Printers */
- X int i, all; /* doing for all Printers */
- X
- X /*
- X * set the flagss needed
- X */
- X Is_local = ( strcmp( From, Host ) == 0 );
- X Is_root = ( strcmp( Person, "root" ) == 0);
- X op_init = 0;
- X command = 0;
- X all = 0;
- X /*
- X * check to see that we have a valid command
- X */
- X if(Debug>4)Show_ops();
- X if( Parmcount < 1 ){
- X (void)fprintf( stdout, "no command\n" );
- X return( 0 );
- X }
- X command = find_command( Parms[0].str );
- X if( command == 0 ){
- X (void)fprintf( stdout, "unknown command %s\n", Parms[0].str );
- X return( 0 );
- X }
- X if(Debug>3)log(XLOG_DEBUG,"Control_ops: command %s, flags 0x%x, %s",
- X dispatch[command].name,dispatch[command].flags,dispatch[command].summary);
- X if( !Is_local && !IS_REMOTE(dispatch[command].flags) ){
- X log(XLOG_INFO,"command %s cannot be done remotely", Parms[0].str);
- X return( 0 );
- X }
- X
- X /*
- X * call the appropriate routine
- X */
- X Shift_parms(1);
- X /*
- X * If no option processing just dispatch
- X */
- X if( !IS_OPT(dispatch[command].flags) ){
- X return( (*dispatch[command].routine)(&dispatch[command]));
- X }
- X /*
- X * if no options and IS_ALL is the default, set up the all flag
- X */
- X if( Parmcount == 0 ){
- X if( IS_ALL_DEF(dispatch[command].flags) ){
- X all = 1;
- X } else {
- X (void)fprintf( stdout, "no parameters, use: %s\n",
- X dispatch[command].summary);
- X return( 0 );
- X }
- X } else if( strcmp( Parms[0].str, "all" ) == 0 ){
- X if( IS_ALL(dispatch[command].flags) ){
- X all = 1;
- X } else {
- X (void)fprintf( stdout, "'all' not allowed, use: %s\n",
- X dispatch[command].summary);
- X return( 0 );
- X }
- X }
- X /*
- X * set up Printer from parameters
- X */
- X if( all ){
- X if(Debug>2)log(XLOG_DEBUG,"'all' parameter" );
- X for( list = All_printers(); *list; ++list ){
- X Printer = *list;
- X if( service( &dispatch[command] ) == 0 ){
- X return( 0 );
- X }
- X }
- X } else {
- X for( i = 0; i < Parmcount; ++i ){
- X Printer = Parms[0].str;
- X Shift_parms(1);
- X if( service( &dispatch[command] ) == 0 ){
- X return( 0 );
- X }
- X if( IS_NO_PR_LIST(dispatch[command].flags) ){
- X break;
- X }
- X }
- X }
- X return( 1 );
- X}
- X
- X/***************************************************************************
- X * service( struct dispatch *cmd );
- X * 1. check on the printcap entry
- X * 2. chdir to the spool directory
- X * 3. dispatch the particular routine
- X ***************************************************************************/
- X
- service( cmd )
- X struct dispatch *cmd;
- X{
- X char *st, *ps;
- X int perms = 'C'; /* Permission Checking */
- X
- X if(Debug>4)log(XLOG_DEBUG,"service: printer '%s', cmd '%s'",
- X Printer, cmd->name );
- X if(Get_pc_entry(Printer, Status_pc_vars, Status_pc_len) == 0){
- X log(XLOG_INFO,"service: Printer %s does not have printcap entry", Printer);
- X return( 0 );
- X }
- X if( RM && NW && IS_ON_REMOTE(cmd->flags) ){
- X (void)fprintf( stdout,
- X "remote printer and network file system, use \'remote %s %s\'\n",
- X cmd->name, Printer );
- X return( 0 );
- X }
- X /*
- X * we may have a server specified
- X */
- X if( SS && *SS ){
- X ps = PS;
- X st = ST;
- X if( Set_pc_entry(SS, Status_pc_vars, Status_pc_len) == 0){
- X log(XLOG_INFO,"service: Server %s queue %s does not have printcap entry",
- X Printer,SS);
- X return( 0 );
- X }
- X PS = ps;
- X ST = st;
- X LO = Printer;
- X SV = 0;
- X }
- X if( SD == 0 || *SD == 0 ){
- X log( XLOG_INFO,"service: Printer %s does not have spool directory", Printer);
- X return( 0 );
- X }
- X /* chdir to spool directory */
- X if (chdir(SD) < 0) {
- X logerr( XLOG_INFO,"service: cannot chdir to %s", SD);
- X return( 0 );
- X }
- X /*
- X * check on the privileges needed
- X * You have to be local and root OR have C privs
- X */
- X if( IS_PRIV(cmd->flags) && !( Is_local && Is_root )
- X && !( Permfile && *Permfile
- X && Checkperm(Permfile,From,Person,First_name,&perms,(int *)0,0))){
- X (void)fprintf(stdout,
- X "You do not have Printer control perms on '%s'\n", Printer);
- X return( 0 );
- X }
- X return( (*cmd->routine)(cmd));
- X}
- X
- X/***************************************************************************
- X * int find_command( char *str )
- X * look in the command table for a match. The "distinct" entry is used
- X * to determine the numbers of characters for a match.
- X ***************************************************************************/
- X
- int
- find_command( str )
- X char *str;
- X{
- X int i;
- X
- X for( i = 1; i < ncmds; ++ i ){
- X if( strncmp( str, dispatch[i].name, dispatch[i].distinct ) == 0
- X && strncmp( str, dispatch[i].name, strlen(str)) == 0 ){
- X return( i );
- X }
- X }
- X return( 0 );
- X}
- X
- X/***************************************************************************
- X * C_bad()
- X * Cannot decide what to do with the command
- X ***************************************************************************/
- int
- C_bad()
- X{
- X (void)fprintf(stdout, "bad command %s\n", Parms[0].str );
- X return( 1 );
- X}
- X/***************************************************************************
- X * C_help()
- X * Print a help message for each command listed,
- X * or a simple list of commands
- X ***************************************************************************/
- int
- C_help()
- X{
- X int i, cmd;
- X
- X if( Parmcount < 2 || strcmp( Parms[1].str, "all" ) == 0 ){
- X for( i = 1; i < ncmds; ++i ){
- X Print_sum( i );
- X }
- X } else {
- X for( i = 1; i < Parmcount; ++i ){
- X cmd = find_command( Parms[i].str );
- X if( cmd > 0 ){
- X Print_sum( cmd );
- X } else {
- X (void)fprintf(stdout, "not a command: %s", Parms[i].str );
- X }
- X }
- X }
- X}
- X
- X/***************************************************************************
- X * Print_sum( cmd )
- X * prints the command summary line
- X ***************************************************************************/
- Print_sum( cmd )
- X{
- X (void)fprintf(stdout, "%s\n", dispatch[cmd].summary );
- X}
- X
- X
- X/***************************************************************************
- X * C_exit()
- X * terminate gracefully
- X ***************************************************************************/
- C_exit()
- X{
- X exit( 0 );
- X}
- X/***************************************************************************
- X * C_stop()
- X * Sets the DISABLE_PRINT perm bit in the lockfile perms
- X * Returns: 1 if successful, 0 if not;
- X ***************************************************************************/
- C_stop()
- X{
- X int s;
- X
- X if(Debug>4)log(XLOG_DEBUG,"C_stop: printer %s, lock '%s'", Printer, LO );
- X (void)Checklockfile( LO, (int *)0,(char *)0,0,&LO_statb );
- X if((s=chmod_daemon(LO,(int)(LO_statb.st_mode&0777) |DISABLE_PRINT)) < 0){
- X logerr(XLOG_INFO,"cannot chmod lockfile %s", LO);
- X } else {
- X (void)fprintf(stdout,"%s: printing disabled\n", Printer);
- X }
- X return( s >= 0 );
- X}
- X/***************************************************************************
- X * C_start()
- X * 1. Clears the DISABLE_PRINT perm bit in the lockfile perms
- X * 2. Starts the Printer
- X * Returns: 1 if successful, 0 if not;
- X ***************************************************************************/
- C_start()
- X{
- X int s;
- X
- X if(Debug>4)log(XLOG_DEBUG,"C_start: printer %s, lock '%s'", Printer, LO );
- X (void)Checklockfile( LO, (int *)0,(char *)0,0,&LO_statb );
- X if((s=chmod_daemon(LO, (int)(LO_statb.st_mode & ENABLE_PRINT))) < 0){
- X logerr(XLOG_INFO,"cannot chmod lockfile %s", LO);
- X } else {
- X (void)fprintf(stdout,"%s: printing enabled\n", Printer);
- X }
- X /*
- X * start the server
- X */
- X if( s >= 0 ){
- X s = C_restart();
- X }
- X return( s >= 0 );
- X}
- X/***************************************************************************
- X * C_disable()
- X * Sets the DISABLE_QUEUE perm bit in the lockfile perms
- X * Returns: 1 if successful, 0 if not;
- X ***************************************************************************/
- C_disable()
- X{
- X int s;
- X
- X if(Debug>4)log(XLOG_DEBUG,"C_disable: printer %s, lock '%s'", Printer, LO );
- X (void)Checklockfile( LO, (int *)0,(char *)0,0,&LO_statb );
- X if((s=chmod_daemon(LO,(int)(LO_statb.st_mode&0777) | DISABLE_QUEUE)) < 0){
- X logerr(XLOG_INFO,"cannot chmod lockfile %s", LO);
- X } else {
- X (void)fprintf(stdout,"%s: queueing disabled\n", Printer);
- X }
- X return( s >= 0 );
- X}
- X/***************************************************************************
- X * C_enable()
- X * 1. Clears the DISABLE_QUEUE perm bit in the lockfile perms
- X * Returns: 1 if successful, 0 if not;
- X ***************************************************************************/
- C_enable()
- X{
- X int s;
- X
- X if(Debug>4)log(XLOG_DEBUG,"C_enable: printer %s, lock '%s'", Printer, LO );
- X (void)Checklockfile( LO, (int *)0,(char *)0,0,&LO_statb );
- X if((s=chmod_daemon(LO, (int)(LO_statb.st_mode & ENABLE_QUEUE))) < 0){
- X logerr(XLOG_INFO,"cannot chmod lockfile %s", LO);
- X } else {
- X (void)fprintf(stdout,"%s: queueing enabled\n", Printer);
- X }
- X return( s >= 0 );
- X}
- X/***************************************************************************
- X * C_restart()
- X * 1. Attempts to fire up the server
- X * Returns: 1 if successful, 0 if not;
- X ***************************************************************************/
- C_restart()
- X{
- X /*
- X * start the server
- X */
- X
- X if(Debug>4)log(XLOG_DEBUG,"C_restart: printer %s, lock '%s'", Printer, LO );
- X (void)Startserver();
- X return( 1 );
- X}
- X
- X/*
- X * killserver(): kills the current server to stop printing
- X */
- static int
- killserver()
- X{
- X int s; /* Success of operation */
- X int pid; /* server PID */
- X /*
- X * Kill the current server to stop printing now.
- X */
- X s = 1;
- X if( Checklockfile( LO, &pid, (char *)0, 0,&LO_statb )){
- X if( kill(pid, SIGINT) < 0 ){
- X (void)logerr(XLOG_INFO,"server (pid %d) not killed", pid);
- X s = 0;
- X } else {
- X (void)fprintf(stdout,"%s: server (pid %d) killed\n",
- X Printer, pid);
- X }
- X } else {
- X (void)fprintf(stdout,"%s: no server present\n", Printer);
- X }
- X return(s);
- X}
- X/***************************************************************************
- X * C_abort()
- X * 1. Does C_stop()
- X * 2. kills off server if there is one
- X * Returns: 1 if successful, 0 if not;
- X ***************************************************************************/
- C_abort()
- X{
- X int s; /* Success of operation */
- X
- X if(Debug>4)log(XLOG_DEBUG,"C_abort: printer %s, lock '%s'", Printer, LO );
- X s = C_stop();
- X if( s ){
- X s = killserver();
- X }
- X return( s );
- X}
- X/***************************************************************************
- X * C_kill()
- X * 1. Does C_abort()
- X * 2. Does C_start()
- X * Returns: 1 if successful, 0 if not;
- X ***************************************************************************/
- C_kill()
- X{
- X int s; /* Success of operation */
- X
- X if(Debug>4)log(XLOG_DEBUG,"C_kill: printer %s, lock '%s'", Printer, LO );
- X s = C_abort();
- X if( s ){
- X s = C_start();
- X }
- X return( s );
- X}
- X
- X/***************************************************************************
- X * C_clean()
- X * 1. Removes all entries in the specified spool directory.
- X * Returns: 1 if successful, 0 if not;
- X ***************************************************************************/
- C_clean()
- X{
- X int c; /* ACME Integers, Inc. */
- X DIR *dirp;
- X struct direct *d;
- X
- X if(Debug>4)log(XLOG_DEBUG,"C_clean: printer %s, lock '%s'", Printer, LO );
- X if ((dirp = opendir(SD)) == NULL) {
- X logerr(XLOG_INFO,"cannot examine spool directory %s");
- X return( 0 );
- X }
- X while ((d = readdir(dirp)) != NULL) {
- X c = d->d_name[0];
- X if ((c == 'c' || c == 't' || c == 'd') && d->d_name[1]=='f') {
- X if (unlink_daemon(d->d_name) < 0){
- X (void)fprintf(stdout,"cannot remove %s\n", d->d_name);
- X } else {
- X (void)fprintf(stdout,"removed %s\n", d->d_name);
- X }
- X }
- X }
- X closedir(dirp);
- X return( 1 );
- X}
- X/*
- X * Print the status of each queue listed or all the queues.
- X */
- static char *hdr_format = "%-12.12s %-4s %-10s %s\n";
- static char *data_format = "%-12.12s %4d %-10s %s%s%s\n";
- C_status()
- X{
- X int active, pid; /* active server and its pid */
- X char buf[BUFSIZ]; /* buffer */
- X char *prstat, *actstat, *qstat, *rqstat; /* Printer and queue status */
- X char *st, *ps;
- X char sbuf[BUFSIZ]; /* status buffer */
- X char servers[BUFSIZ];
- X char *sp, *ep, *sr; /* ACME Pointers, Inc. */
- X
- X if(Debug>3)log(XLOG_INFO,"C_status: printer %s", Printer);
- X if(Get_pc_entry(Printer, Status_pc_vars, Status_pc_len) == 0){
- X log(XLOG_INFO,"Printer %s does not have printcap entry", Printer);
- X return( 0 );
- X }
- X /* we have a server here */
- X if( SS && *SS ){
- X ps = PS;
- X st = ST;
- X if( Set_pc_entry(SS, Status_pc_vars, Status_pc_len) == 0){
- X log(XLOG_INFO,"Server %s queue %s does not have printcap entry",
- X Printer,SS);
- X return( 0 );
- X }
- X PS = ps;
- X ST = st;
- X LO = Printer;
- X SV = 0;
- X }
- X if( SD == 0 || *SD == 0 ){
- X log( XLOG_INFO,"Printer %s does not have spool directory", Printer);
- X return( 0 );
- X }
- X /* chdir to spool directory */
- X if (chdir(SD) < 0) {
- X logerr( XLOG_INFO,"cannot chdir to %s", SD);
- X return( 0 );
- X }
- X /*
- X * start by getting active server information
- X */
- X buf[0] = 0;
- X active = Checklockfile( LO, &pid, buf, sizeof( buf),&LO_statb);
- X
- X /*
- X * get numbers of jobs in queue
- X */
- X
- X Jobcount = Getq();
- X
- X /*
- X * now format the info appropriately
- X */
- X qstat = (LO_statb.st_mode & DISABLE_QUEUE) ? "disabled " : "enabled ";
- X prstat = ( LO_statb.st_mode & DISABLE_PRINT) ? "disabled " : "enabled ";
- X /*
- X * get active server
- X */
- X if(Debug>4)log(XLOG_DEBUG,"C_status: active '%d', Jobcount '%d', '%s'",
- X active, Jobcount, buf );
- X if( SV == 0 || *SV == 0 ){
- X if( Jobcount == 0 && active == 0 ){
- X (void)sprintf( sbuf,"" );
- X } else if( Jobcount == 0 && active ){
- X (void)sprintf( sbuf,"(server %d)", pid, buf );
- X } else if( Jobcount && active == 0 ){
- X (void)sprintf( sbuf,"(no server)" );
- X } else {
- X (void)sprintf( sbuf,"(server %d, job %s)", pid, buf );
- X }
- X actstat = sbuf;
- X } else {
- X (void)strcpy( servers, SV );
- X (void)sprintf( sbuf, hdr_format, "", "", "X", "" );
- X if( (sp = index( sbuf, 'X' ) ) == 0 ){
- X fatal(XLOG_INFO,"C_status: header format bad" );
- X }
- X *sp = 0;
- X for( sp = servers; sp; sp = ep ){
- X ep = index( sp, ',');
- X if( ep ){
- X *ep = 0;
- X ep = ep + 1;
- X }
- X active = Checklockfile( sp, &pid,buf,sizeof(buf),&LO_statb );
- X if( LO_statb.st_mode & DISABLE_PRINT){
- X sr = "dis";
- X } else {
- X sr = "enb";
- X }
- X if( active == 0 ){
- X (void)sprintf( sbuf+strlen(sbuf),"(%s: %s, no server)",sp, sr);
- X } else {
- X (void)sprintf( sbuf+strlen(sbuf),"(%s: %s, %d, job %s)",
- X sp, sr, pid, buf );
- X }
- X }
- X actstat = sbuf;
- X }
- X if( LO_statb.st_mode & FORCE_REQUE ){
- X rqstat = ", reorder requested";
- X } else {
- X rqstat = "";
- X }
- X /* displays heading if not already displayed */
- X if (!op_init) {
- X (void)fprintf(stdout,hdr_format,
- X SS ? "Server" : "Queue", "Jobs", "Queueing", "Printing" );
- X op_init = 1;
- X }
- X /* prints the queue status */
- X (void)fprintf(stdout,data_format, Printer, Jobcount, qstat,
- X prstat,rqstat,actstat);
- X /* prints the Printer status */
- X printstatus();
- X (void)fflush(stdout);
- X return(1);
- X}
- X
- X/*
- X * Put the specified jobs at the top of Printer queue.
- X */
- C_topq()
- X{
- X int i; /* ACME Integer, Inc. */
- X int changed; /* We changed the queue */
- X char *cfname; /* control file name */
- X
- X (void)fprintf(stdout,"%s:\n", Printer);
- X
- X /*
- X * put the parameters in the list in the correct position
- X */
- X if( Parmcount == 0 ){
- X if(Debug>4)log(XLOG_DEBUG,"C_topq: no parameters" );
- X return( 0 );
- X }
- X if(Debug>4)log(XLOG_DEBUG,"C_topq: '%s'(%d)", Parms[0].str, Parms[0].num );
- X /* get number of jobs in the queue */
- X Jobcount = Getq();
- X /*
- X * go through the queue and find the jobs to be promoted
- X */
- X changed = 0;
- X for( i = 0; i < Jobcount; ++i ){
- X if(Match_entry( &Queue[i] )){
- X /*
- X * Reposition the job by setting its priority to high level
- X * and then fix the control file
- X */
- X if(promote(Queue[i].q_name)) {
- X changed++;
- X Queue[i].q_name[0] = 0;
- X }
- X }
- X }
- X /*
- X * Put the other high priority jobs lower
- X */
- X if( !changed ){
- X return( 1 );
- X }
- X for( i = 0; i < Jobcount; i++) {
- X cfname = Queue[i].q_name;
- X if(*cfname && cfname[2] == 'A'){
- X touch(cfname);
- X }
- X }
- X (void)fprintf(stdout, "queue order changed\n");
- X /*
- X * Turn on the public execute bit of the lock file to
- X * get lpd to rebuild the queue after the current job.
- X */
- X (void)Checklockfile( LO, (int *)0,(char *)0,0,&LO_statb );
- X if( chmod_daemon(LO, (int)(LO_statb.st_mode & 0777) | FORCE_REQUE) < 0 ){
- X logerr( XLOG_INFO, "cannot force requeue on lockfile %s", LO );
- X return( 0 );
- X }
- X return( 1 );
- X}
- X
- X/***************************************************************************
- X * promote( char *cfname )
- X * promote a file to the A priority, and head of the list.
- X ***************************************************************************/
- promote(cfname)
- X char *cfname;
- X{
- X char buf[BUFSIZ];
- X
- X (void)strcpy( buf, cfname);
- X buf[STARTPR] = 'A';
- X if(Debug>0)log( XLOG_DEBUG, "renaming %s to %s", cfname, buf );
- X if( strcmp( buf, cfname) && rename( cfname, buf ) < 0 ){
- X logerr( XLOG_INFO,"cannot rename %s to %s", cfname, buf );
- X return(0);
- X }
- X (void)fprintf( stdout, "promoting %s to %s\n", cfname, buf );
- X return( 1 );
- X}
- X
- X
- X/*
- X * Change the modification time of the file.
- X * Returns boolean if successful.
- X */
- touch(cfname)
- X char *cfname;
- X{
- X FILE *fp;
- X int i;
- X
- X if( (fp = Lockcf(cfname)) == NULL ){
- X logerr(XLOG_INFO,"cannot open %s\n", cfname);
- X } else if( (i = getc(fp)) == EOF ){
- X logerr(XLOG_INFO,"cannot read %s\n", cfname);
- X } else if(fseek(fp, 0L, 0) < 0 ){;
- X /* set pointer back to top of file */
- X logerr(XLOG_INFO,"cannot seek %s\n", cfname);
- X } else if( putc( i, fp) == EOF ){
- X logerr(XLOG_INFO,"cannot write %s\n", cfname);
- X } else if( fflush( fp ) == EOF ){
- X logerr(XLOG_INFO,"cannot flush %s\n", cfname);
- X }
- X if( fp != NULL ){
- X (void)fclose(fp);
- X }
- X}
- X
- X/*
- X * Show_ops()
- X * show the values of the local options
- X */
- X
- Show_ops()
- X{
- X int i;
- X (void)fprintf(stdout,"From: %s, Host %s, Person %s\n",From,Host,Person);
- X (void)fprintf(stdout,"Is_local %d, Is_root %d\n", Is_local, Is_root );
- X (void)fprintf(stdout,"Parmcount %d ", Parmcount );
- X for( i = 0; i < Parmcount; ++i ){
- X (void)fprintf(stdout, " '%s'(%d)", Parms[i].str, Parms[i].num );
- X }
- X (void)fprintf(stdout,"\n");
- X (void)fflush(stdout);
- X}
- X
- X/***************************************************************************
- X * C_lpq()
- X * invoke Lpq with parameters.
- X * use the "system()" facility to do this.
- X ***************************************************************************/
- C_lpq()
- X{
- X char buf[BUFSIZ];
- X char *bp, *ep; /* ACME Pointers, Inc. */
- X int i;
- X
- X ep = buf+sizeof(buf);
- X bp = estrcp( buf, "lpq", ep );
- X for( i = 0; i < Parmcount; ++i ){
- X bp = estrcp( bp, " ", ep );
- X bp = estrcp( bp, Parms[i].str, ep );
- X }
- X if(Debug>4)log(XLOG_DEBUG,"C_lpq: '%s'", buf );
- X i = system( buf );
- X if(Debug>4)log(XLOG_DEBUG,"C_lpq: status %d", i );
- X return( i );
- X}
- X
- X/***************************************************************************
- X * C_lprm()
- X * invoke Lprm with parameters.
- X * use the "system()" facility to do this.
- X ***************************************************************************/
- C_lprm()
- X{
- X char buf[BUFSIZ];
- X char *bp, *ep; /* ACME Pointers, Inc. */
- X int i;
- X
- X ep = buf+sizeof(buf);
- X bp = estrcp( buf, "lprm", ep );
- X for( i = 0; i < Parmcount; ++i ){
- X bp = estrcp( bp, " ", ep );
- X bp = estrcp( bp, Parms[i].str, ep );
- X }
- X if(Debug>4)log(XLOG_DEBUG,"C_lprm: '%s'", buf );
- X i = system( buf );
- X if(Debug>4)log(XLOG_DEBUG,"C_lprm: status %d", i );
- X return( i );
- X}
- X
- X/***************************************************************************
- X * C_remote()
- X * do the indicated command on the remote host
- X * command has the form: "remote op printer"
- X * 1. get the command and see if it can be done remotely
- X * Parms[0] will be op, Parms[1] will be printer
- X * 2. check the printer and make sure that it is a remote printer
- X * 3. send the remote command to the far end, and get the information
- X * sent back.
- X ***************************************************************************/
- X
- C_remote(cmd)
- X struct dispatch *cmd;
- X{
- X char **list; /* list of printers */
- X int i; /* ACME Integers and Bearings, Inc. */
- X int command; /* command we are going to do */
- X
- X if( Parmcount < 2 ){
- X (void)fprintf( stdout, "no or missing command or parameters\n" );
- X return( 0 );
- X }
- X command = find_command( Parms[0].str );
- X if( command == 0 ){
- X (void)fprintf( stdout, "unknown command %s\n", Parms[0].str );
- X return( 0 );
- X }
- X if(Debug>3)log(XLOG_DEBUG,"C_remote: command %s, %d, %s",
- X dispatch[command].name,dispatch[command].flags,dispatch[command].summary);
- X
- X if( !IS_REMOTE(dispatch[command].flags) ){
- X (void)fprintf( stdout, "command %s cannot be done remotely\n",
- X Parms[0].str );
- X }
- X
- X /*
- X * check on the printer
- X */
- X if( strcmp("all", Parms[0].str) == 0){
- X if(Debug>2)log(XLOG_DEBUG,"'all' parameter" );
- X for( list = All_printers(); *list; ++list ){
- X Printer = *list;
- X if( remote_cando(dispatch[command].flags) ){
- X Remote_control(dispatch[command].name);
- X }
- X }
- X } else {
- X for( i = 1; i < Parmcount; ++i ){
- X Printer = Parms[i].str;
- X if( remote_cando(dispatch[command].flags) ){
- X Remote_control(dispatch[command].name);
- X }
- X }
- X }
- X return( 1 );
- X}
- X
- X/***************************************************************************
- X * remote_cando()
- X * returns 0 if not able to do to remote site, 1 otherwise
- X *
- X ***************************************************************************/
- remote_cando(flags)
- X{
- X int perms = 'C'; /* Permission Checking */
- X
- X if(Get_pc_entry(Printer, Status_pc_vars, Status_pc_len) == 0){
- X log(XLOG_INFO,"Printer %s does not have printcap entry", Printer);
- X return( 0 );
- X }
- X if( RM == 0 || RP == 0 ){
- X if(Debug>5)log(XLOG_DEBUG,"%s not remote", Printer );
- X return( 0 );
- X }
- X /*
- X * check on the privileges needed
- X * You have to be local and root OR have C privs
- X */
- X if( IS_PRIV(flags) && !( Is_local && Is_root )
- X && !( Permfile && *Permfile
- X && Checkperm(Permfile,From,Person,First_name,&perms,(int *)0,0))){
- X (void)fprintf(stdout,
- X "You do not have printer control perms on '%s'\n", Printer);
- X return( 0 );
- X }
- X return( 1 );
- X}
- X
- X/***************************************************************************
- X * C_lpd()
- X * 1. Check to see if there is an active lpd server by checking the
- X * lock file.
- X * 2. Check to see if the /dev/printer is available as well.
- X ***************************************************************************/
- X
- C_lpd()
- X{
- X int f;
- X
- X (void)Checklockfile(Masterlock, &f, (char *)0, 0, &LO_statb );
- X if(f){
- X (void)fprintf(stdout, "active LPD %d\n", f );
- X } else {
- X (void)fprintf( stdout, "LPD is not active\n" );
- X }
- X (void)fflush(stdout);
- X}
- END_OF_FILE
- if test 28050 -ne `wc -c <'src/control_ops.c'`; then
- echo shar: \"'src/control_ops.c'\" unpacked with wrong size!
- fi
- # end of 'src/control_ops.c'
- fi
- echo shar: End of archive 16 \(of 16\).
- cp /dev/null ark16isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 16 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-