# lps --- spool queue status monitor include ARGUMENT_DEFS include PRIMOS_KEYS include PRIMOS_ERRD include "lps_def.r.i" ARG_DECL integer Td (28), Dest (3), Paper (3) integer getarg character Queue_path (MAXPATH), Pack (33) string no_spoolq_msg "Can't find SPOOLQ directory" string no_qctrl_msg "Can't read queue" procedure cancel_entries forward procedure list_queue forward call timdat (Td, 28) # we need our login name in packed format PARSE_COMMAND_LINE ("c admpq"s, _ "Usage: lps (-c {} | {} [-{a |d|m|p |q}])"s) if (ARG_PRESENT (c)) cancel_entries else { # list spool queue(s) do i = 1, 3; { Paper (i) = " " Dest (i) = " " } if (ARG_PRESENT (p)) { call mapstr (ARG_TEXT (p), UPPER) i = 1 call ctop (ARG_TEXT (p), i, Paper, 3) } if (ARG_PRESENT (a)) { call mapstr (ARG_TEXT (q), UPPER) i = 1 call ctop (ARG_TEXT (a), i, Dest, 3) } for (i = 1; getarg (i, Pack, 33) ~= EOF; i += 1) { call mapstr (Pack, UPPER) list_queue } if (i == 1) { Pack (1) = EOS list_queue } } # cancel_entries --- cancel one or more entries from the queue procedure cancel_entries { local arg, junk, qnam, qent character arg (MAXARG), sprt (7) integer at, ap, code, entry, fd, i, junk (3), prt (3), qnam (16), qent (ENTSIZ) integer getto, getarg, ctoi longint entpos bool nameqv if (getto ("//spoolq/q.ctrl"s, qnam, junk, at) == ERR) { call print (ERROUT, "*s.*n"s, no_spoolq_msg) call error (EOS) } for (ap = 1; getarg (ap, arg, MAXARG) ~= EOF; ap += 1) { call mapstr (arg, LOWER) if (arg (1) == 'p'c && arg (2) == 'r'c && arg (3) == 't'c) i = 4 else i = 1 entry = ctoi (arg, i) if (arg (i) ~= EOS || entry <= 0 || entry >= MAXENTRIES) { call print (ERROUT, "*s: bad sequence number*n"s, arg) next } call encode (sprt, 7, "prt*3,,0i"s, entry) i = 1 call ctop (sprt, i, prt, 3) entpos = intl ((entry - 1) * ENTSIZ + HDRSIZ) call q$offc (fd, qnam, 6, KREAD + KGETU, code) if (code == 0) { call prwf$$ (KREAD + KPREA, fd, loc (qent), 4, entpos, junk, code) call srch$$ (KCLOS, 0, 0, fd, 0, junk) call break$ (ENABLE) } if (code ~= 0) { call print (ERROUT, "*s.*n"s, no_qctrl_msg) call error (EOS) } if (qent (1) == 0) call print (ERROUT, "*,6h: not found*n"p, prt) elif (~nameqv (qent (2), LOGIN_NAME) && ~nameqv (LOGIN_NAME, "SYSTEM")) { code = ERR call print (ERROUT, "*,6h: not yours*n"p, prt) } else { call satr$$ (KPROT, prt, 6, 16r4000000, junk) call srch$$ (KCLOS, prt, 6, 0, 0, junk) call srch$$ (KDELE, prt, 6, 0, 0, code) call satr$$ (KPROT, prt, 6, 16r7000000, junk) if (code == EFNTF) # print file already gone code = 0 if (code ~= 0) call print (ERROUT, "*,6h: in use*n"p, prt) } if (code == 0) { call q$rem (qnam, fd, entry, code) call srch$$ (KCLOS, 0, 0, fd, 0, junk) call break$ (ENABLE) if (code ~= 0) call print (ERROUT, "*,6h: can't cancel*n"p, prt) } } } # list_queue --- list the contents of the specified queue(s) procedure list_queue { local junk, qnam, f integer at, code, f1, f2, i, t1, t2, f, Buf (BUFSIZE), junk (3), qnam (16) integer getto bool Header_printed procedure print_area (from, to) forward call encode (Queue_path, MAXPATH, "/*s/spoolq/q.ctrl"s, Pack) if (getto (Queue_path, qnam, junk, at) ~= ERR) { call read_queue (qnam, f, Buf, f1, t1, f2, t2, code) call follow (EOS, 0) if (code == 0) { Header_printed = FALSE if (f1 ~= 0) { print_area (f1, t1) if (f2 ~= 0) print_area (f2, t2) } } else if (Pack (1) == EOS) call print (ERROUT, "*s.*n", no_qctrl_msg) else call print (ERROUT, "*s on disk *s.*n"s, no_qctrl_msg, Pack) } else if (Pack (1) == EOS) call print (ERROUT, "*s.*n"s, no_spoolq_msg) else call print (ERROUT, "*s on disk *s.*n"s, no_spoolq_msg, Pack) } # print_area --- print one area of the spool queue procedure print_area (from, to) { integer from, to local i character pflag (2), ssize (6), sdest (17), sname (25) integer i, ent, qent (ENTSIZ) integer ptoc bool nameqv string heading_format _ "*,,#u*6s *3s *5s *16s *5s *6s *6s *5s *14s*n" do ent = from, to; { if (Buf (ent * ENTSIZ - ENTSIZ + 1) == 0) # no entry here next call move$ (Buf (ent * ENTSIZ - ENTSIZ + 2), qent, ENTSIZ - 1) if (ARG_PRESENT (m) && ~nameqv (qent (OWNER_NAME), LOGIN_NAME) || ARG_PRESENT (d) && and (qent (OPTION_WORD), DEFER_BIT) == 0 || ARG_PRESENT (p) && ~nameqv (qent (PAPER_TYPE), Paper) || ARG_PRESENT (a) && ~nameqv (qent (DEST_NAME), Dest)) next if (and (qent (OPTION_WORD), COPIES_BIT) == 0) qent (COPIES) = 1 if (qent (ENTRY_SIZE) < 0) # still spooling call ctoc (" open"s, ssize, 6) else call encode (ssize, 6, "*5i"s, qent (ENTRY_SIZE)) pflag (1) = EOS if (and (qent (OPTION_WORD), DEST_BIT) ~= 0 || qent (PRINT_FLAG) == "<-") { i = ptoc (qent (DEST_NAME), ' 'c, sdest, 17) if (qent (DEST_NAME2) ~= " ") i += ptoc (qent (DEST_NAME2), ' 'c, sdest (i + 1), 17 - i) if (qent (PRINT_FLAG) == "<-") call ctoc ("*"s, pflag, 2) } else sdest (1) = EOS call ptoc (qent (ENTRY_NAME), ' 'c, sname, 25) if (~Header_printed) { Header_printed = TRUE if (Pack (1) ~= EOS) call print (STDOUT, "****** *s:*n"s, Pack) if (~ARG_PRESENT (q)) { call print (STDOUT, heading_format, ' 'c, "user"s, "prt"s, "time"s, "banner"s, " size"s, "copies"s, "form"s, "defer"s, "destination"s) call print (STDOUT, heading_format, '='c, EOS, EOS, EOS, EOS, EOS, EOS, EOS, EOS, EOS) } } if (ARG_PRESENT (q)) call print (STDOUT, "*3,,0i *,6h *5s *1s*6s *s*n"p, ent, qent (OWNER_NAME), ssize, pflag, sdest, sname) else { call print (STDOUT, "*,6h *3,,0i *2i:*2,,0i *,16h *5s *6i *,6h "p, qent (OWNER_NAME), ent, qent (ENTRY_TIME) / 60, mod (qent (ENTRY_TIME), 60), qent (ENTRY_NAME), ssize, qent (COPIES), qent (PAPER_TYPE)) if (and (qent (OPTION_WORD), DEFER_BIT) ~= 0) call print (STDOUT, "*2i:*2,,0i "s, qent (DEFER_TIME) / 60, mod (qent (DEFER_TIME), 60)) else call print (STDOUT, "*6x"p) call print (STDOUT, "*s*s*n"p, pflag, sdest) } } } stop end # read_queue --- read queue into buffer subroutine read_queue (qnam, f, qbuf, f1, t1, f2, t2, code) integer qnam (3), f, qbuf (ARB), f1, t1, f2, t2, code integer code, hbuf (HDRSIZ), junk longint pos procedure finish forward f1 = 0 f2 = 0 call q$offc (f, qnam, 6, KREAD+KGETU, code) if (code ~= 0) return call prwf$$ (KREAD, f, loc (hbuf), HDRSIZ, intl (0), junk, code) if (code ~= 0) finish if (hbuf (7) == 0) # queue is empty finish f1 = hbuf (3) # start of first valid area t1 = hbuf (4) - 1 # end of first valid area if (t1 - f1 < 0) # check for wrap around t1 = MAXENTRIES pos = intl (f1) * ENTSIZ + HDRSIZ - ENTSIZ call prwf$$ (KREAD+KPREA, f, loc (qbuf (pos - HDRSIZ + 1)), (t1 - f1 + 1) * ENTSIZ, pos, junk, code) if (code ~= 0) finish if (t1 ~= MAXENTRIES) # only one valid area finish t2 = hbuf (4) - 1 # end of second valid area if (t2 <= 0) # no entries in the second area finish f2 = 1 # second area always begins at first entry call prwf$$ (KREAD+KPREA, f, loc (qbuf), t2 * ENTSIZ, intl (HDRSIZ), junk, code) finish # finish --- close queue file, enable breaks and return procedure finish { call srch$$ (KCLOS, 0, 0, f, 0, junk) call break$ (ENABLE) return } end # q$offc --- open file fight contention subroutine q$offc(fd, name, len, key, code) integer fd, name(16), len, key, code integer i, junk for (i = 1; i <= 30; i += 1) { call break$(DISABLE) call srch$$(key, name, len, fd, junk, code) if (code ~= EFIUS) break call break$(ENABLE) call sleep$(intl(1000)) } if (code ~= 0 && i <= 30) call break$(ENABLE) return end