mcgrew@dartagnan.rutgers.edu (Charles Mcgrew) (07/21/89)
Submitted-by: chuck@trantor.harris-atd.com (Chuck Musciano) Posting-number: Volume 1, Issue 51 Archive-name: lpqtool Lpqtool provides a convenient way to monitor the printer queue from your desktop. It will automatically track your jobs, and open and close as the jobs enter and exit the queue. Chuck Musciano ARPA : chuck@trantor.harris-atd.com Harris Corporation Usenet: ...!uunet!x102a!trantor!chuck PO Box 37, MS 3A/1912 AT&T : (407) 727-6131 Melbourne, FL 32902 FAX : (407) 727-{5118,5227,4004} #! /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 shell archive." # Contents: Makefile lpqtool.c laserwriter.icon misc.c README # lpqtool.man # Wrapped by chuck@melmac on Mon Oct 10 08:02:50 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(416 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X# where you keep local executables XBINDIR = /usr/local/bin X X# man directory for local man pages (usually /usr/man/manl) XMANDIR = /usr/man/manl XMANEXT = l X XOFILES = lpqtool.o misc.o X XWINDOW_LIB = -lsuntool -lsunwindow -lpixrect X X.c.o: X cc -c $< X Xlpqtool: $(OFILES) X cc -o lpqtool $(OFILES) $(WINDOW_LIB) X Xinstall: lpqtool X cp lpqtool $(BINDIR) X cp lpqtool.man $(MANDIR)/lpqtool.$(MANEXT) X Xclean: X rm *.o core X X END_OF_FILE if test 416 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'lpqtool.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'lpqtool.c'\" else echo shar: Extracting \"'lpqtool.c'\" \(13641 characters\) sed "s/^X//" >'lpqtool.c' <<'END_OF_FILE' X/************************************************************************/ X/* Copyright 1988 by Chuck Musciano and Harris Corporation */ X/* */ X/* Permission to use, copy, modify, and distribute this software */ X/* and its documentation for any purpose and without fee is */ X/* hereby granted, provided that the above copyright notice */ X/* appear in all copies and that both that copyright notice and */ X/* this permission notice appear in supporting documentation, and */ X/* that the name of Chuck Musciano and Harris Corporation not be */ X/* used in advertising or publicity pertaining to distribution */ X/* of the software without specific, written prior permission. */ X/* Chuck Musciano and Harris Corporation make no representations */ X/* about the suitability of this software for any purpose. It is */ X/* provided "as is" without express or implied warranty. */ X/************************************************************************/ X X X#include <suntool/sunview.h> X#include <suntool/panel.h> X#include <suntool/canvas.h> X X#include <stdio.h> X X#define LPQ "/usr/ucb/lpq" X X#define ICON_PATH "laserwriter.icon" X X#define NORMAL_FONT "/usr/lib/fonts/fixedwidthfonts/screen.r.14" X#define BOLD_FONT "/usr/lib/fonts/fixedwidthfonts/screen.b.14" X X#define NO_STATE 0 X#define IDLE_STATE 1 X#define ACTIVE_STATE 2 X#define CHECK_STATE 3 X Xstatic char *lp_usage = "usage: lpqtool [-a <interval>] [-c] [-i <interval>] [-o] [-r <rows>] [-t <idle threshold>] [ <printer> ]\n"; X Xstatic short lp_icon_image[] = { X#include ICON_PATH X}; Xmpr_static(lp_icon_pixrect, 64, 30, 1, lp_icon_image); X Xstruct itimerval active = {{10, 0}, {10, 0}}; Xstruct itimerval idle = {{60, 0}, {60, 0}}; Xint active_open = FALSE; Xint idle_closed = FALSE; Xint idle_threshold = 6; Xint queue_rows = 5; Xint idle_count, stay_idle; Xint state = NO_STATE; Xchar user[30]; Xchar *printer_name; X XIcon icon; XFrame frame; XCanvas status, queue; XPanel panel; XPixwin *spw, *qpw; Xstruct pixfont *normal_font, *bold_font; XPanel_item a_item, i_item, a_light, i_light, c_light, a_button, i_button, c_button; X X/************************************************************************/ Xstatic char *right_str(val, width) X Xint val; Xint width; X X{ static char buf[20]; X X sprintf(buf, "%*d", width, val); X return(buf); X} X X/************************************************************************/ Xstatic set_status(st) X Xint st; X X{ X panel_set(a_light, PANEL_SHOW_ITEM, FALSE, 0); X panel_set(i_light, PANEL_SHOW_ITEM, FALSE, 0); X panel_set(c_light, PANEL_SHOW_ITEM, FALSE, 0); X if (st == IDLE_STATE) X panel_set(i_light, PANEL_SHOW_ITEM, TRUE, 0); X else if (st == ACTIVE_STATE) X panel_set(a_light, PANEL_SHOW_ITEM, TRUE, 0); X else if (st == CHECK_STATE) X panel_set(c_light, PANEL_SHOW_ITEM, TRUE, 0); X} X/************************************************************************/ Xstatic update_queue() X X{ FILE *f; X char buf[256]; X int line = 2, new_state = NO_STATE; X X set_status(CHECK_STATE); X sprintf(buf, "%s%s%s", LPQ, *printer_name? " -P" : "", printer_name); X if ((f = popen(buf, "r")) == NULL) { X pw_output(spw, 2, 5, TRUE, "Unable to obtain queue information"); X pw_rop(qpw, 0, 0, window_get(queue, WIN_WIDTH), window_get(queue, WIN_HEIGHT), PIX_SRC | PIX_COLOR(0), NULL, 0, 0); X pclose(f); X return; X } X if (fgets(buf, 256, f) != NULL) { X buf[strlen(buf) - 1] = '\0'; X pw_output(spw, 1, 1, TRUE, "Status:"); X pw_output(spw, 2, 5, TRUE, buf); X pw_rop(qpw, 0, 0, window_get(queue, WIN_WIDTH), window_get(queue, WIN_HEIGHT), PIX_SRC | PIX_COLOR(0), NULL, 0, 0); X if (strcmp(buf, "no entries") == 0) X new_state = IDLE_STATE; X else X new_state = ACTIVE_STATE; X } X while (fgets(buf, 256, f) != NULL) { X buf[strlen(buf) - 1] = '\0'; X if (strncmp(buf, "Rank", 4) == 0) { X if (new_state == IDLE_STATE) X new_state = ACTIVE_STATE; X continue; X } X else if (verify(buf, " \t\n\r")) X continue; X else { X if (line == 2) X pw_output(qpw, 1, 1, TRUE, "Rank Owner Job Files Total Size"); X pw_output(qpw, line++, 1, strindex(buf, user), buf); X } X } X pclose(f); X if (new_state == IDLE_STATE) { X stay_idle = FALSE; X if (state == ACTIVE_STATE && --idle_count <= 0) X go_idle(); X } X else if (new_state == ACTIVE_STATE && !stay_idle) X go_active(); X set_status(state); X} X X/************************************************************************/ Xstatic Panel_setting number_proc(item, event) X XPanel_item item; XEvent *event; X X{ char buf[80]; X int val; X X strcpy(buf, panel_get_value(item)); X val = atoi(buf); X if (event_id(event) >= '1' && event_id(event) <= '9') { X val = val * 10 + event_id(event) - '0'; X panel_set(item, PANEL_VALUE, right_str(val, 5), 0); X return(PANEL_NONE); X } X else if (event_id(event) == '0') X if (item == a_item && val == 0) X return(PANEL_NONE); X else { X val = val * 10 + event_id(event) - '0'; X panel_set(item, PANEL_VALUE, right_str(val, 5), 0); X return(PANEL_NONE); X } X else if (event_id(event) == '\010') { X val /= 10; X panel_set(item, PANEL_VALUE, right_str(val, 5), 0); X return(PANEL_NONE); X } X else if (event_id(event) == '\177') { X panel_set(item, PANEL_VALUE, " ", 0); X return(PANEL_NONE); X } X else if (event_id(event) == '\n' || event_id(event) == '\r') { X if (item == a_item) { X active.it_value.tv_sec = active.it_interval.tv_sec = val; X if (state == ACTIVE_STATE) X notify_set_itimer_func(frame, update_queue, ITIMER_REAL, &active, NULL); X } X else { X idle.it_value.tv_sec = idle.it_interval.tv_sec = val; X if (state == IDLE_STATE) X notify_set_itimer_func(frame, update_queue, ITIMER_REAL, &idle, NULL); X } X return(PANEL_NONE); X } X else X return(PANEL_NONE); X} X X/************************************************************************/ Xstatic go_idle() X X{ X if (state == IDLE_STATE) X return; X state = IDLE_STATE; X if (idle_closed) X window_set(frame, FRAME_CLOSED, TRUE, 0); X if (idle.it_value.tv_sec != 0) X notify_set_itimer_func(frame, update_queue, ITIMER_REAL, &idle, NULL); X else X notify_set_itimer_func(frame, update_queue, ITIMER_REAL, NULL, NULL); X set_status(IDLE_STATE); X} X X/************************************************************************/ Xstatic go_active() X X{ X idle_count = idle_threshold; X if (state == ACTIVE_STATE) X return; X state = ACTIVE_STATE; X if (active_open) X window_set(frame, FRAME_CLOSED, FALSE, 0); X update_queue(); X notify_set_itimer_func(frame, update_queue, ITIMER_REAL, &active, NULL); X set_status(ACTIVE_STATE); X} X X/************************************************************************/ Xstatic pw_output(pw, row, col, bold, str) X XPixwin *pw; Xint row; Xint col; Xint bold; Xchar *str; X X{ X row = (row - 1) * normal_font->pf_defaultsize.y; X col = (col - 1) * normal_font->pf_defaultsize.x + 4; X pw_text(pw, col, row - normal_font->pf_char['0'].pc_home.y, PIX_SRC, normal_font, str); X if (bold) X pw_text(pw, col + 1, row - normal_font->pf_char['0'].pc_home.y, PIX_SRC | PIX_DST, normal_font, str); X col += strlen(str) * normal_font->pf_defaultsize.x; X pw_rop(pw, col, row, pw->pw_pixrect->pr_size.x - col, normal_font->pf_defaultsize.y, PIX_SRC | PIX_COLOR(0), NULL, 0, 0); X} X X/************************************************************************/ Xstatic Notify_value close_proc(frame, event, arg, type) X XFrame frame; XEvent *event; XNotify_arg arg; XNotify_event_type type; X X{ int init_closed, curr_closed, is_resize; X Notify_value value; X Rect *temp; X X init_closed = (int) window_get(frame, FRAME_CLOSED); X value = notify_next_event_func(frame, event, arg, type); X curr_closed = (int) window_get(frame, FRAME_CLOSED); X if (init_closed != curr_closed) X if (curr_closed) { X stay_idle = (state == ACTIVE_STATE); X go_idle(); X } X else X go_active(); X return(value); X} X X/************************************************************************/ Xmain(argc, argv) X Xint argc; Xchar **argv; X X{ char c, *s, **saveargs(); X int i, interval = 10; X Rect *r; X X normal_font = pf_open(NORMAL_FONT); X bold_font = pf_open(BOLD_FONT); X icon = icon_create(ICON_IMAGE, &lp_icon_pixrect, X ICON_LABEL, NULL, X ICON_WIDTH, lp_icon_pixrect.pr_size.x, X ICON_HEIGHT, lp_icon_pixrect.pr_size.y, X 0); X frame = window_create(NULL, FRAME, X FRAME_ICON, icon, X FRAME_LABEL, "<< LaserWriter Queue Status >>", X FRAME_ARGC_PTR_ARGV, &argc, argv, X 0); X X argv = saveargs(argc, argv); X while ((c = getopt(&argc, argv, "a:ci:or:t:", &s)) != EOF) X switch (c) { X case 'a' : if (verify(s, "0123456789")) { X active.it_value.tv_sec = active.it_interval.tv_sec = atoi(s); X if (active.it_value.tv_sec <= 0) X abend("invalid active interval: %s\n", s); X } X else X abend("invalid active interval: %s\n", s); X break; X case 'c' : idle_closed = TRUE; X break; X case 'i' : if (verify(s, "0123456789")) { X idle.it_value.tv_sec = idle.it_interval.tv_sec = atoi(s); X if (idle.it_value.tv_sec < 0) X abend("invalid idle interval: %s\n", s); X } X else X abend("invalid idle interval: %s\n", s); X break; X case 'o' : active_open = TRUE; X break; X case 'r' : if (verify(s, "0123456789")) { X queue_rows = atoi(s); X if (queue_rows <= 0) X abend("invalid number of queue lines: %s\n", s); X } X else X abend("invalid number of queue lines: %s\n", s); X break; X case 't' : if (verify(s, "0123456789")) { X idle_threshold = atoi(s); X if (idle_threshold <= 0) X abend("invalid idle thresold: %s\n", s); X } X else X abend("invalid idle threshold: %s\n", s); X break; X case '?' : fprintf(stderr, lp_usage); X break; X default : abend(lp_usage); X break; X } X X panel = window_create(frame, PANEL, X PANEL_FONT, normal_font, X WIN_COLUMNS, 75, X 0); X a_item = panel_create_item(panel, PANEL_TEXT, X PANEL_LABEL_STRING, "Active Interval:", X PANEL_LABEL_BOLD, TRUE, X PANEL_ITEM_Y, ATTR_ROW(0) + 1, X PANEL_VALUE_DISPLAY_LENGTH, 5, X PANEL_VALUE, right_str(active.it_value.tv_sec, 5), X PANEL_NOTIFY_PROC, number_proc, X PANEL_NOTIFY_LEVEL, PANEL_ALL, X 0); X a_light = panel_create_item(panel, PANEL_MESSAGE, X PANEL_LABEL_STRING, "Active", X PANEL_LABEL_BOLD, TRUE, X 0); X i_light = panel_create_item(panel, PANEL_MESSAGE, X PANEL_LABEL_STRING, "Idle", X PANEL_LABEL_BOLD, TRUE, X 0); X c_light = panel_create_item(panel, PANEL_MESSAGE, X PANEL_LABEL_STRING, "Checking", X PANEL_LABEL_BOLD, TRUE, X 0); X i_item = panel_create_item(panel, PANEL_TEXT, X PANEL_LABEL_STRING, "Idle Interval: ", X PANEL_LABEL_BOLD, TRUE, X PANEL_VALUE_DISPLAY_LENGTH, 5, X PANEL_ITEM_X, ATTR_COL(0), X PANEL_ITEM_Y, ATTR_ROW(1) + 4, X PANEL_VALUE, right_str(idle.it_value.tv_sec, 5), X PANEL_NOTIFY_PROC, number_proc, X PANEL_NOTIFY_LEVEL, PANEL_ALL, X 0); X a_button = panel_create_item(panel, PANEL_BUTTON, X PANEL_ITEM_Y, ATTR_ROW(1), X PANEL_ITEM_X, ATTR_COL(26), X PANEL_LABEL_IMAGE, better_button_image(panel, "Go Active", 12, 5, bold_font), X PANEL_NOTIFY_PROC, go_active, X 0); X i_button = panel_create_item(panel, PANEL_BUTTON, X PANEL_ITEM_Y, ATTR_ROW(1), X PANEL_LABEL_IMAGE, better_button_image(panel, "Go Idle", 12, 5, bold_font), X PANEL_NOTIFY_PROC, go_idle, X 0); X c_button = panel_create_item(panel, PANEL_BUTTON, X PANEL_ITEM_Y, ATTR_ROW(1), X PANEL_LABEL_IMAGE, better_button_image(panel, "Check Queue", 12, 5, bold_font), X PANEL_NOTIFY_PROC, update_queue, X 0); X r = (Rect *) panel_get(a_button, PANEL_ITEM_RECT); X i = r->r_left + r->r_width / 2; X r = (Rect *) panel_get(a_light, PANEL_ITEM_RECT); X panel_set(a_light, PANEL_ITEM_X, i - r->r_width / 2, 0); X r = (Rect *) panel_get(i_button, PANEL_ITEM_RECT); X i = r->r_left + r->r_width / 2; X r = (Rect *) panel_get(i_light, PANEL_ITEM_RECT); X panel_set(i_light, PANEL_ITEM_X, i - r->r_width / 2, 0); X r = (Rect *) panel_get(c_button, PANEL_ITEM_RECT); X i = r->r_left + r->r_width / 2; X r = (Rect *) panel_get(c_light, PANEL_ITEM_RECT); X panel_set(c_light, PANEL_ITEM_X, i - r->r_width / 2, 0); X window_fit_height(panel); X X status = window_create(frame, CANVAS, X WIN_HEIGHT, normal_font->pf_defaultsize.y * 2, X WIN_WIDTH, normal_font->pf_defaultsize.x * 75, X WIN_X, 0, X WIN_BELOW, panel, X 0); X spw = canvas_pixwin(status); X queue = window_create(frame, CANVAS, X WIN_HEIGHT, normal_font->pf_defaultsize.y * (queue_rows + 1), X WIN_WIDTH, normal_font->pf_defaultsize.x * 75, X WIN_X, 0, X WIN_BELOW, status, X 0); X qpw = canvas_pixwin(queue); X window_set(panel, WIN_WIDTH, window_get(queue, WIN_WIDTH), 0); X window_fit(frame); X X if (argc == 1) X printer_name = ""; X else if (argc == 2) X printer_name = argv[1]; X else X abend(lp_usage); X X strcpy(user, user_name()); X set_status(NO_STATE); X if (window_get(frame, FRAME_CLOSED)) X go_idle(); X else X go_active(); X notify_interpose_event_func(frame, close_proc, NOTIFY_SAFE); X window_main_loop(frame); X pf_close(normal_font); X pf_close(bold_font); X} END_OF_FILE if test 13641 -ne `wc -c <'lpqtool.c'`; then echo shar: \"'lpqtool.c'\" unpacked with wrong size! fi # end of 'lpqtool.c' fi if test -f 'laserwriter.icon' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'laserwriter.icon'\" else echo shar: Extracting \"'laserwriter.icon'\" \(947 characters\) sed "s/^X//" >'laserwriter.icon' <<'END_OF_FILE' X/* Format_version=1, Width=64, Height=30, Depth=1, Valid_bits_per_item=16 X */ X 0x888F,0xFFFF,0xFFFF,0xFFFC,0x2228,0x0000,0x0000,0x0006, X 0x2228,0x0000,0x0000,0x0006,0x8888,0x0000,0x0000,0x0004, X 0x8888,0x0000,0x0000,0x0004,0x222F,0xFFFF,0xFFFF,0xFFFE, X 0x2229,0x0100,0x0000,0x0806,0x8889,0x0100,0x0000,0x0804, X 0x8889,0x0100,0x0000,0x0804,0x2229,0x3D00,0x0000,0x0806, X 0x2229,0x2500,0x0F00,0x0806,0x8889,0x3D00,0x0900,0x0804, X 0x8889,0x3D00,0x0F00,0x0804,0x2229,0x3D00,0x0000,0x0806, X 0x2229,0x0100,0x0000,0x0806,0x8889,0x0100,0x0000,0x0804, X 0x8889,0x0100,0x0000,0x0808,0xE22F,0xFFFF,0xFFFF,0xF812, X 0xFE2F,0x8000,0x0000,0x07E2,0x9FFF,0x8000,0x0000,0x0028, X 0x8BFF,0x80FF,0xFFFF,0xF028,0x2222,0x8000,0x0000,0x0022, X 0x2222,0x80FF,0xFFFF,0xF022,0x8888,0x8000,0x0000,0x0028, X 0x8888,0x80FF,0xFFFF,0xF028,0x2222,0x8000,0x0000,0x0022, X 0x2222,0x80FF,0xFFFF,0xF022,0x8888,0x8000,0x0000,0x0028, X 0x8888,0xFFFF,0xFFFF,0xFFE8,0x2222,0x2FA2,0x2222,0x3E22 END_OF_FILE if test 947 -ne `wc -c <'laserwriter.icon'`; then echo shar: \"'laserwriter.icon'\" unpacked with wrong size! fi # end of 'laserwriter.icon' fi if test -f 'misc.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'misc.c'\" else echo shar: Extracting \"'misc.c'\" \(4418 characters\) sed "s/^X//" >'misc.c' <<'END_OF_FILE' X/************************************************************************/ X/* Copyright 1988 by Chuck Musciano and Harris Corporation */ X/* */ X/* Permission to use, copy, modify, and distribute this software */ X/* and its documentation for any purpose and without fee is */ X/* hereby granted, provided that the above copyright notice */ X/* appear in all copies and that both that copyright notice and */ X/* this permission notice appear in supporting documentation, and */ X/* that the name of Chuck Musciano and Harris Corporation not be */ X/* used in advertising or publicity pertaining to distribution */ X/* of the software without specific, written prior permission. */ X/* Chuck Musciano and Harris Corporation make no representations */ X/* about the suitability of this software for any purpose. It is */ X/* provided "as is" without express or implied warranty. */ X/************************************************************************/ X X X/************************************************************************/ X/* Some miscellaneous support routines */ X/************************************************************************/ X X#include <stdio.h> X#include <pwd.h> X X#include <suntool/sunview.h> X#include <suntool/panel.h> X Xstatic short cross_bits[] = {0x4000, 0xe000, 0x4000}; Xmpr_static(better_button_cross, 3, 3, 1, cross_bits); X Xextern char *strcpy(); X Xtext_width(text, font) X Xchar *text; Xstruct pixfont *font; X X{ int width; X X for (width = 0; *text; text++) X width += font->pf_char[*text].pc_adv.x; X return(width); X} X Xstruct pixrect *better_button_image(panel, text, chars, pixels, font) X XPanel panel; Xchar *text; Xint chars; Xint pixels; Xstruct pixfont *font; X X{ struct pixrect *pr; X struct pr_prpos pos; X int width, true_width, height; X X if (font == NULL) X font = (struct pixfont *) window_get(panel, WIN_FONT); X width = chars * font->pf_char['0'].pc_adv.x + pixels; X true_width = text_width(text, font); X if (width < true_width) X width = true_width; X pr = mem_create(width + 8, height = font->pf_defaultsize.y + 6, 1); X pr_rop(pr, 3, 0, width + 2, 2, PIX_SRC | PIX_COLOR(1), NULL, 0, 0); X pr_rop(pr, 3, height - 2, width + 2, 2, PIX_SRC | PIX_COLOR(1), NULL, 0, 0); X pr_rop(pr, 0, 3, 2, height - 6, PIX_SRC | PIX_COLOR(1), NULL, 0, 0); X pr_rop(pr, width + 6, 3, 2, height - 6, PIX_SRC | PIX_COLOR(1), NULL, 0, 0); X pr_rop(pr, 1, 1, 3, 3, PIX_SRC | PIX_DST, &better_button_cross, 0, 0); X pr_rop(pr, width + 4, 1, 3, 3, PIX_SRC | PIX_DST, &better_button_cross, 0, 0); X pr_rop(pr, width + 4, height - 4, 3, 3, PIX_SRC | PIX_DST, &better_button_cross, 0, 0); X pr_rop(pr, 1, height - 4, 3, 3, PIX_SRC | PIX_DST, &better_button_cross, 0, 0); X pos.pr = pr; X pos.pos.x = 4 + (width - true_width) / 2; X pos.pos.y = 4 - font->pf_char['T'].pc_home.y; X pf_ttext(pos, PIX_SRC | PIX_COLOR(1), font, text); X return(pr); X} X Xchar *user_name() X X{ struct passwd *pp; X X pp = getpwuid(getuid()); X return(pp? pp->pw_name : NULL); X} X Xabend(s1, s2, s3, s4, s5, s6, s7, s8) X Xchar *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8; X X{ X fprintf(stderr, s1, s2, s3, s4, s5, s6, s7, s8); X exit(1); X} X Xchar *strindex(source, target) X Xchar *source; Xchar *target; X X{ register int len; X X len = strlen(target); X for (; *source; source++) X if (strncmp(source, target, len) == 0) X return(source); X return(0); X} X Xverify(source, valid) X Xchar *source; Xchar *valid; X X{ register char *s; X X for ( ; *source; source++) { X for (s = valid; *s && *s != *source; s++) X ; X if (*s == '\0') X return(0); X } X return(1); X} X Xchar **saveargs(argc, argv) X Xint argc; Xchar **argv; X X{ int i; X char **copy; X X copy = (char **) malloc((argc + 1) * sizeof(char *)); X for (i = 0; i < argc; i++) X strcpy(copy[i] = (char *) malloc(strlen(argv[i]) + 1), argv[i]); X copy[i] = (char *) 0; X return(copy); X} X Xstatic delarg(argc, argv) X Xint *argc; Xchar **argv; X X{ char *p; X X while (*argv = *(argv+1)) X argv++; X (*argc)--; X} X Xchar getopt(argc, argv, opts, parm) X Xint *argc; Xchar **argv; Xchar *opts; Xchar **parm; X X{ char c, *p, *index(); X int killed; X X *parm = NULL; X while (*argv && ((**argv != '-') || (*(*argv+1) == '\0'))) X argv++; X if (*argv == NULL) X return(EOF); X c = *(*argv+1); X *++(*argv) = '-'; X if (killed = (*(*argv+1) == '\0')) X delarg(argc, argv); X if ((p = index(opts, c)) == NULL) X c = '\0'; X else if (*(p+1) == ':') { X *parm = killed ? *argv : *argv+1; X delarg(argc, argv); X } X return(c); X} END_OF_FILE if test 4418 -ne `wc -c <'misc.c'`; then echo shar: \"'misc.c'\" unpacked with wrong size! fi # end of 'misc.c' fi if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(3612 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' X/************************************************************************/ X/* Copyright 1988 by Chuck Musciano and Harris Corporation */ X/* */ X/* Permission to use, copy, modify, and distribute this software */ X/* and its documentation for any purpose and without fee is */ X/* hereby granted, provided that the above copyright notice */ X/* appear in all copies and that both that copyright notice and */ X/* this permission notice appear in supporting documentation, and */ X/* that the name of Chuck Musciano and Harris Corporation not be */ X/* used in advertising or publicity pertaining to distribution */ X/* of the software without specific, written prior permission. */ X/* Chuck Musciano and Harris Corporation make no representations */ X/* about the suitability of this software for any purpose. It is */ X/* provided "as is" without express or implied warranty. */ X/************************************************************************/ X X X Lpqtool is a windowed version of lpq. It will periodically poll the Xprint queue (using lpq) and display the results in a little window. You can Xadjust the polling rate to suit yourself. Lpqtool has two rates: one for an Xactive queue (with jobs in it) and another for an idle (empty) queue. XNormally, it polls an active queue more rapidly than an idle queue, to deliver Xup to the minute information about the state of the queue. Lpqtool can also Xbe configured (via command line options) to close when the queue is idle, Xand pop open when it becomes active. This is handy, because you can pop it Xopen when you submit a job, and it will watch the queue until it becomes Xempty, and then it will go away. See the man page for all the details. X X Installing lpqtool is easy. You'll need to check the Makefile and Xlpqtool.c to make sure some pathnames and such are correct. These items Xare: X X In Makefile: X BINDIR Where the executable will go, normally X /usr/local/bin X MANDIR Where the man page will go, normally X /usr/man/manl X MANEXT The man page extension, usually 'l', X for local man pages. You may want to X make MANDIR /usr/man/man1, in which case X MANEXT should be '1'. X X In lpqtool.c X LPQ The full pathname of the lpq command on X your system. Normally, this is X /usr/ucb/lpq. You may have it in a X different place, or might use a different X queue display command. Be warned: lpqtool X depends on the format of the output of lpq, X so other commands may not work right. X ICON_PATH Where the laserwriter icon can be found. X Normally, it is in the directory that you X created lpqtool in, but you might want to move X it to a more global place. We keep all our X icons in /usr/local/images, for example. X Fix this path to match where you put the icon. X NORMAL_FONT X BOLD_FONT Point to the fonts used by lpqtool, which should X be in the standard Sun font place, X /usr/lib/fonts/fixedwidthfonts. If you have moved X them, fix up these paths. You should always use X screen.r.14 and screen.b.14, since lpqtool depends X on the font widths to make its windows look good. X XEverything else is system independent. Just type "make lpqtool" or "make install" Xand give it a whirl! X X Comments, bugs, to me, please. I would be very interested in your impressions Xof lpqtool and any suggestions you might have to make it better. By the way, Xthere are a few convenient untility routines in misc.c you might find useful in Xother programs you are writing. X XChuck Musciano XAdvanced Technology Department XHarris Corporation X(407) 727-6131 XARPA: chuck@trantor.harris-atd.com END_OF_FILE if test 3612 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'lpqtool.man' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'lpqtool.man'\" else echo shar: Extracting \"'lpqtool.man'\" \(3225 characters\) sed "s/^X//" >'lpqtool.man' <<'END_OF_FILE' X.TH LPQTOOL 1 "29 April 1987" X.SH NAME Xlpqtool \- monitor the LaserWriter queue X.SH SYNOPSIS X\fBlpqtool\fP [ \fIoptions\fP ] [ \fIprinter\fP ] X.SH DESCRIPTION X.LP X\fILpqtool\fP is a window-based tool that allows the user to monitor a Xprint queue. The tool periodically uses the \fIlpq\fP(1) Xcommand to inspect the state of the queue, and displays that information Xin a window. Jobs associated with the invoking user are shown in boldface. XIf a \fIprinter\fP is specified, \fIlpqtool\fP will monitor that printer. XOtherwise, the default printer, as determined by \fIlpq\fP, is used. X.LP X\fILpqtool\fP switches between the \fIactive\fP and the \fIidle\fP modes Xwhile watching the queue. In active mode, the queue is inspected more Xfrequently, as determined by the \fB-a\fP option, below. During idle mode, Xthe queue is inspected less frequently, as determined by the \fB-i\fP Xoption, below. If the queue is found to be empty a certain number of Xsuccessive times while in active mode (see \fB-t\fP), \fIlpqtool\fP Xswitches into idle mode. Conversely, if the queue is found to be not empty while in Xidle mode, \fIlpqtool\fP switches to active mode. X.LP XIn addition to this, \fIlpqtool\fP can be made to automatically open itself Xwhen the queue becomes active, and to automatically close itself when the Xqueue is empty. Finally, the user can control the size of the displayed Xqueue. X.LP X\fILpqtool\fP provides three buttons when it is open, which allow the user Xto force it into either mode, and to force an inspection of the queue. XThere are also type-in areas where the user can change the active and idle Xpolling intervals. X.SH OPTIONS X\fILpqtool\fP runs only under SunWindows, and honors all of the window Xcommand line options. The various options that control \fIlpqtool\fP are: X.IP "\fB\-a\fP \fIinterval\fP" 14 XThis option determines the time, in seconds, between inspections of the Xqueue while in active mode. The default value is 10 seconds. X.IP "\fB\-c\fP" 14 XThis option causes \fIlpqtool\fP to automatically close when in idle mode. X.IP "\fB\-i\fP \fIinterval\fP" 14 XThis option determines the time, in seconds, between inspections of the Xqueue while in idle mode. The default value is 60 seconds. If this value is Xset to 0, no polling occurs during idle mode, and the only way to enter Xactive mode is to either open the tool, or to click the \*(lqGo Active\*(rq Xbutton. X.IP "\fB\-o\fP" 14 XThis option causes \fIlpqtool\fP to automatically open when in active mode. X.IP "\fB\-r\fP \fIrows\fP" 14 XThis option determines the number of rows in the queue display. XThe default value is 5 rows. X.IP "\fB\-t\fP \fIthreshold\fP" 14 XThis option determines the number of consecutive times an empty queue must Xbe encountered before switching from active mode to idle mode. The default is 6. X.SH SEE ALSO Xlpq(1), lpr(1), suntools(1) X.SH AUTHOR X.LP XChuck Musciano X.br XAdvanced Technology Department X.br XHarris Corporation X.br X(407) 727-6131 X.br XARPA: chuck@trantor.harris-atd.com X.SH BUGS X.LP X\fILpqtool\fP was really designed to watch the LaserWriter, although it Xallows other printers to be specified. Thus, references to the LaserWriter, Xand the \fIlpqtool\fP icon, may not be correct for the desired printer. END_OF_FILE if test 3225 -ne `wc -c <'lpqtool.man'`; then echo shar: \"'lpqtool.man'\" unpacked with wrong size! fi # end of 'lpqtool.man' fi echo shar: End of shell archive. exit 0 Chuck Musciano ARPA : chuck@trantor.harris-atd.com Harris Corporation Usenet: ...!uunet!x102a!trantor!chuck PO Box 37, MS 3A/1912 AT&T : (407) 727-6131 Melbourne, FL 32902 FAX : (407) 727-{5118,5227,4004}