/******************************************************************************* * * * printUtils.c -- Fermilab Nirvana library Printer Menu & Printing Routines * * * * Copyright (c) 1991 Universities Research Association, Inc. * * All rights reserved. * * * * This material resulted from work developed under a Government Contract and * * is subject to the following license: The Government retains a paid-up, * * nonexclusive, irrevocable worldwide license to reproduce, prepare derivative * * works, perform publicly and display publicly by or for the Government, * * including the right to distribute to other Government contractors. Neither * * the United States nor the United States Department of Energy, nor any of * * their employees, makes any warranty, express or implied, or assumes any * * legal liability or responsibility for the accuracy, completeness, or * * usefulness of any information, apparatus, product, or process disclosed, or * * represents that its use would not infringe privately owned rights. * * * * April 20, 1992 * * * * Written by Arnulfo Zepeda-Navratil * * Centro de Investigacion y Estudio Avanzados ( CINVESTAV ) * * Dept. Fisica - Mexico * * BITNET: ZEPEDA@CINVESMX * * * * Modified by Donna Reid and Joy Kyriakopulos 4/8/93 - VMS port * * * *******************************************************************************/ static char SCCSID[] = "@(#)printUtils.c 1.19 9/26/94"; #include #include #include #include #include #ifdef VMS #include "vmsparam.h" #include #include #include #include #include #include #include #else #ifdef USE_DIRENT #include #else #include #endif /* USE_DIRENT */ #include #endif /*VMS*/ #include #include #include #include #include #include #include #include #include #include #include "DialogF.h" #include "misc.h" #include "prefFile.h" #include "printUtils.h" /* Separator between directory references in PATH environmental variable */ #define SEPARATOR ':' /* Number of extra pixels down to place a label even with a text widget */ #define LABEL_TEXT_DIFF 6 /* Maximum text string lengths */ #define MAX_OPT_STR 20 #define MAX_QUEUE_STR 60 #define MAX_INT_STR 13 #define MAX_HOST_STR 100 #define MAX_PCMD_STR 100 #define MAX_NAME_STR 100 #define MAX_CMD_STR 256 #define VMS_MAX_JOB_NAME_STR 39 #define N_PRINT_PREFS 7 /* must agree with number of preferences below */ struct printPrefDescrip { PrefDescripRec printCommand; PrefDescripRec copiesOption; PrefDescripRec queueOption; PrefDescripRec nameOption; PrefDescripRec hostOption; PrefDescripRec defaultQueue; PrefDescripRec defaultHost; }; /* Function Prototypes */ static Widget createForm(Widget parent); static void allowOnlyNumInput(Widget widget, caddr_t client_data, XmTextVerifyCallbackStruct *call_data); static void noSpaceOrPunct(Widget widget, caddr_t client_data, XmTextVerifyCallbackStruct *call_data); static void updatePrintCmd(Widget w, caddr_t client_data, caddr_t call_data); static void printButtonCB(Widget widget, caddr_t client_data, caddr_t call_data); static void cancelButtonCB(Widget widget, caddr_t client_data, caddr_t call_data); static void setQueueLabelText(); static int fileInDir(char *filename,char *dirpath,unsigned short mode_flags); static int fileInPath(char *filename,unsigned short mode_flags); static int flprPresent(); static void getLprQueueDefault(char *defqueue); static void getLpQueueDefault(char *defqueue); static void setHostLabelText(); #ifdef VMS static void getVmsQueueDefault(char *defqueue); #else static void getFlprHostDefault(char *defhost); static void getFlprQueueDefault(char *defqueue); #endif /* Module Global Variables */ static Boolean DoneWithDialog; static Boolean PreferencesLoaded = False; static Widget Form; static Widget Label2; static Widget Label3; static Widget Text1; static Widget Text2; static Widget Text3; static Widget Text4; static char *PrintFileName; static char *PrintJobName; static char PrintCommand[MAX_PCMD_STR]; /* print command string */ static char CopiesOption[MAX_OPT_STR]; /* # of copies argument string */ static char QueueOption[MAX_OPT_STR]; /* queue name argument string */ static char NameOption[MAX_OPT_STR]; /* print job name argument string */ static char HostOption[MAX_OPT_STR]; /* host name argument string */ static char DefaultQueue[MAX_QUEUE_STR];/* default print queue */ static char DefaultHost[MAX_HOST_STR]; /* default host name */ static char Copies[MAX_INT_STR] = ""; /* # of copies last entered by user */ static char Queue[MAX_QUEUE_STR] = ""; /* queue name last entered by user */ static char Host[MAX_HOST_STR] = ""; /* host name last entered by user */ static char CmdText[MAX_CMD_STR] = ""; /* print command last entered by user */ #ifdef VMS static int DeleteFile; /* append /DELETE to VMS print command*/ #endif /*VMS*/ static struct printPrefDescrip PrintPrefDescrip = { {"printCommand", "PrintCommand", PREF_STRING, NULL, PrintCommand, (void *)MAX_PCMD_STR, False}, {"printCopiesOption", "PrintCopiesOption", PREF_STRING, NULL, CopiesOption, (void *)MAX_OPT_STR, False}, {"printQueueOption", "PrintQueueOption", PREF_STRING, NULL, QueueOption, (void *)MAX_OPT_STR, False}, {"printNameOption", "PrintNameOption", PREF_STRING, NULL, NameOption, (void *)MAX_OPT_STR, False}, {"printHostOption", "PrintHostOption", PREF_STRING, NULL, HostOption, (void *)MAX_OPT_STR, False}, {"printDefaultQueue", "PrintDefaultQueue", PREF_STRING, NULL, DefaultQueue, (void *)MAX_QUEUE_STR, False}, {"printDefaultHost", "PrintDefaultHost", PREF_STRING, NULL, DefaultHost, (void *)MAX_HOST_STR, False}, }; /* ** PrintFile(Widget parent, char *printFile, char *jobName); ** ** function to put up an application-modal style Print Panel dialog ** box. ** ** parent Parent widget for displaying dialog ** printFile File to print (assumed to be a temporary file ** and not revealed to the user) ** jobName Title for the print banner page */ #ifdef VMS void PrintFile(Widget parent, char *printFile, char *jobName, int delete) #else void PrintFile(Widget parent, char *printFile, char *jobName) #endif /*VMS*/ { /* In case the program hasn't called LoadPrintPreferences, set up the default values for the print preferences */ if (!PreferencesLoaded) LoadPrintPreferences(NULL, "", "", True); /* Make the PrintFile information available to the callback routines */ PrintFileName = printFile; PrintJobName = jobName; #ifdef VMS DeleteFile = delete; #endif /*VMS*/ /* Create and display the print dialog */ DoneWithDialog = False; Form = createForm(parent); ManageDialogCenteredOnPointer(Form); /* Process events until the user is done with the print dialog */ while (!DoneWithDialog) XtAppProcessEvent(XtWidgetToApplicationContext(Form), XtIMAll); /* Destroy the dialog. Print dialogs are not preserved across calls to PrintFile so that it may be called with different parents and to generally simplify the call (this, of course, makes it slower) */ XtDestroyWidget(Form); } /* ** LoadPrintPreferences ** ** Read an X database to obtain print dialog preferences. ** ** prefDB X database potentially containing print preferences ** appName Application name which can be used to qualify ** resource names for database lookup. ** appClass Application class which can be used to qualify ** resource names for database lookup. ** lookForFlpr Check if the flpr print command is installed ** and use that for the default if it's found. ** (flpr is a Fermilab utility for printing on ** arbitrary systems that support the lpr protocol) */ void LoadPrintPreferences(XrmDatabase prefDB, char *appName, char *appClass, int lookForFlpr) { static char defaultQueue[MAX_QUEUE_STR], defaultHost[MAX_HOST_STR]; #ifdef VMS /* VMS built-in print command */ getVmsQueueDefault(defaultQueue); PrintPrefDescrip.printCommand.defaultString = "print"; PrintPrefDescrip.copiesOption.defaultString = "/copies="; PrintPrefDescrip.queueOption.defaultString = "/queue="; PrintPrefDescrip.nameOption.defaultString = "/name="; PrintPrefDescrip.hostOption.defaultString = ""; PrintPrefDescrip.defaultQueue.defaultString = defaultQueue; PrintPrefDescrip.defaultHost.defaultString = ""; #else /* check if flpr is installed, and otherwise choose appropriate printer per system type */ if (lookForFlpr && flprPresent()) { getFlprQueueDefault(defaultQueue); getFlprHostDefault(defaultHost); PrintPrefDescrip.printCommand.defaultString = "flpr"; PrintPrefDescrip.copiesOption.defaultString = ""; PrintPrefDescrip.queueOption.defaultString = "-q"; PrintPrefDescrip.nameOption.defaultString = "-j "; PrintPrefDescrip.hostOption.defaultString = "-h"; PrintPrefDescrip.defaultQueue.defaultString = defaultQueue; PrintPrefDescrip.defaultHost.defaultString = defaultHost; } else { #ifdef USE_LPR_PRINT_CMD getLprQueueDefault(defaultQueue); PrintPrefDescrip.printCommand.defaultString = "lpr"; PrintPrefDescrip.copiesOption.defaultString = "-# "; PrintPrefDescrip.queueOption.defaultString = "-P "; PrintPrefDescrip.nameOption.defaultString = "-J "; PrintPrefDescrip.hostOption.defaultString = ""; PrintPrefDescrip.defaultQueue.defaultString = defaultQueue; PrintPrefDescrip.defaultHost.defaultString = ""; #else getLpQueueDefault(defaultQueue); PrintPrefDescrip.printCommand.defaultString = "lp"; /* was lp -c */ PrintPrefDescrip.copiesOption.defaultString = "-n"; PrintPrefDescrip.queueOption.defaultString = "-d"; PrintPrefDescrip.nameOption.defaultString = "-t"; PrintPrefDescrip.hostOption.defaultString = ""; PrintPrefDescrip.defaultQueue.defaultString = defaultQueue; PrintPrefDescrip.defaultHost.defaultString = ""; #endif } #endif /* Read in the preferences from the X database using the mechanism from prefFile.c (this allows LoadPrintPreferences to work before any widgets are created, which is more convenient than XtGetApplication- Resources for applications which have no main window) */ RestorePreferences(NULL, prefDB, appName, appClass, (PrefDescripRec *)&PrintPrefDescrip, N_PRINT_PREFS); PreferencesLoaded = True; } static Widget createForm(Widget parent) { Widget form, printOk, printCancel, label1, separator; Widget topWidget = NULL; XmString st0; Arg args[65]; int argcnt; Widget bwidgetarray [30]; int bwidgetcnt = 0; /************************ FORM ***************************/ argcnt = 0; XtSetArg(args[argcnt], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); argcnt++; XtSetArg(args[argcnt], XmNdialogTitle, (st0=XmStringCreateLtoR( "Printer Options", XmSTRING_DEFAULT_CHARSET))); argcnt++; XtSetArg(args[argcnt], XmNautoUnmanage, False); argcnt++; form = XmCreateFormDialog(parent, "printForm", args, argcnt); XtVaSetValues(form, XmNshadowThickness, 0, 0); XmStringFree( st0 ); /*********************** LABEL 1 and TEXT BOX 1 *********************/ if (CopiesOption[0] != '\0') { argcnt = 0; XtSetArg(args[argcnt], XmNlabelString, (st0=XmStringCreateLtoR( "Number of copies (1)", XmSTRING_DEFAULT_CHARSET))); argcnt++; XtSetArg(args[argcnt], XmNmnemonic, 'N'); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++; XtSetArg(args[argcnt], XmNtopOffset, LABEL_TEXT_DIFF+5); argcnt++; XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++; XtSetArg(args[argcnt], XmNleftOffset, 8); argcnt++; label1 = XmCreateLabelGadget(form, "label1", args, argcnt); XmStringFree( st0 ); bwidgetarray[bwidgetcnt] = label1; bwidgetcnt++; argcnt = 0; XtSetArg(args[argcnt], XmNshadowThickness, (short)2); argcnt++; XtSetArg(args[argcnt], XmNcolumns, 3); argcnt++; XtSetArg(args[argcnt], XmNrows, 1); argcnt++; XtSetArg(args[argcnt], XmNvalue , Copies); argcnt++; XtSetArg(args[argcnt], XmNmaxLength, 3); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++; XtSetArg(args[argcnt], XmNtopOffset, 5); argcnt++; XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_WIDGET); argcnt++; XtSetArg(args[argcnt], XmNleftWidget, label1); argcnt++; Text1 = XmCreateText(form, "text1", args, argcnt); bwidgetarray[bwidgetcnt] = Text1; bwidgetcnt++; XtAddCallback(Text1, XmNmodifyVerifyCallback, (XtCallbackProc)allowOnlyNumInput, NULL); XtAddCallback(Text1, XmNvalueChangedCallback, (XtCallbackProc)updatePrintCmd, NULL); RemapDeleteKey(Text1); topWidget = Text1; XtVaSetValues(label1, XmNuserData, Text1, 0); /* mnemonic procesing */ } /************************ LABEL 2 and TEXT 2 ************************/ if (QueueOption[0] != '\0') { argcnt = 0; XtSetArg(args[argcnt], XmNlabelString, (st0=XmStringCreateLtoR( " ", XmSTRING_DEFAULT_CHARSET))); argcnt++; XtSetArg(args[argcnt], XmNmnemonic, 'Q'); argcnt++; XtSetArg(args[argcnt], XmNrecomputeSize, True); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, topWidget==NULL?XmATTACH_FORM:XmATTACH_WIDGET); argcnt++; XtSetArg(args[argcnt], XmNtopWidget, topWidget); argcnt++; XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++; XtSetArg(args[argcnt], XmNtopOffset, LABEL_TEXT_DIFF+4); argcnt++; XtSetArg(args[argcnt], XmNleftOffset, 8); argcnt++; Label2 = XmCreateLabelGadget(form, "label2", args, argcnt); XmStringFree(st0); bwidgetarray[bwidgetcnt] = Label2; bwidgetcnt++; setQueueLabelText(); argcnt = 0; XtSetArg(args[argcnt], XmNshadowThickness, (short)2); argcnt++; XtSetArg(args[argcnt], XmNcolumns, (short)17); argcnt++; XtSetArg(args[argcnt], XmNmaxLength, MAX_QUEUE_STR); argcnt++; XtSetArg(args[argcnt], XmNvalue, Queue); argcnt++; XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++; XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_WIDGET); argcnt++; XtSetArg(args[argcnt], XmNleftWidget, Label2 ); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, topWidget==NULL?XmATTACH_FORM:XmATTACH_WIDGET); argcnt++; XtSetArg(args[argcnt], XmNtopWidget, topWidget ); argcnt++; XtSetArg(args[argcnt], XmNrightOffset, 8); argcnt++; XtSetArg(args[argcnt], XmNtopOffset, 4); argcnt++; Text2 = XmCreateText(form, "text2", args, argcnt); XtAddCallback(Text2, XmNmodifyVerifyCallback, (XtCallbackProc)noSpaceOrPunct, NULL); XtAddCallback(Text2, XmNvalueChangedCallback, (XtCallbackProc)updatePrintCmd, NULL); bwidgetarray[bwidgetcnt] = Text2; bwidgetcnt++; RemapDeleteKey(Text2); XtVaSetValues(Label2, XmNuserData, Text2, 0); /* mnemonic procesing */ topWidget = Text2; } /****************** LABEL 3 and TEXT 3 *********************/ if (HostOption[0] != '\0') { argcnt = 0; XtSetArg(args[argcnt], XmNlabelString, (st0=XmStringCreateLtoR( " ", XmSTRING_DEFAULT_CHARSET))); argcnt++; XtSetArg(args[argcnt], XmNmnemonic, 'H'); argcnt++; XtSetArg(args[argcnt], XmNrecomputeSize, True); argcnt++; XtSetArg(args[argcnt], XmNvalue , ""); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, topWidget==NULL?XmATTACH_FORM:XmATTACH_WIDGET); argcnt++; XtSetArg(args[argcnt], XmNtopWidget, topWidget ); argcnt++; XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++; XtSetArg(args[argcnt], XmNleftOffset, 8); argcnt++; XtSetArg(args[argcnt], XmNtopOffset, LABEL_TEXT_DIFF+4); argcnt++; Label3 = XmCreateLabelGadget(form, "label3", args, argcnt); XmStringFree(st0); bwidgetarray[bwidgetcnt] = Label3; bwidgetcnt++; setHostLabelText(); argcnt = 0; XtSetArg(args[argcnt], XmNcolumns, 17); argcnt++; XtSetArg(args[argcnt], XmNrows, 1); argcnt++; XtSetArg(args[argcnt], XmNvalue, Host); argcnt++; XtSetArg(args[argcnt], XmNmaxLength, MAX_HOST_STR); argcnt++; XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++; XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_WIDGET); argcnt++; XtSetArg(args[argcnt], XmNleftWidget, Label3 ); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, topWidget==NULL?XmATTACH_FORM:XmATTACH_WIDGET); argcnt++; XtSetArg(args[argcnt], XmNtopWidget, topWidget ); argcnt++; XtSetArg(args[argcnt], XmNrightOffset, 8); argcnt++; XtSetArg(args[argcnt], XmNtopOffset, 4); argcnt++; Text3 = XmCreateText(form, "Text3", args, argcnt); XtAddCallback(Text3, XmNmodifyVerifyCallback, (XtCallbackProc)noSpaceOrPunct, NULL); XtAddCallback(Text3, XmNvalueChangedCallback, (XtCallbackProc)updatePrintCmd, NULL); bwidgetarray[bwidgetcnt] = Text3; bwidgetcnt++; RemapDeleteKey(Text3); XtVaSetValues(Label3, XmNuserData, Text3, 0); /* mnemonic procesing */ topWidget = Text3; } /************************** TEXT 4 ***************************/ argcnt = 0; XtSetArg(args[argcnt], XmNvalue, CmdText); argcnt++; XtSetArg(args[argcnt], XmNcolumns, 50); argcnt++; XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++; XtSetArg(args[argcnt], XmNleftOffset, 8); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++; XtSetArg(args[argcnt], XmNtopOffset, 8); argcnt++; XtSetArg(args[argcnt], XmNtopWidget, topWidget ); argcnt++; XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++; XtSetArg(args[argcnt], XmNrightOffset, 8); argcnt++; Text4 = XmCreateText(form, "Text4", args, argcnt); bwidgetarray[bwidgetcnt] = Text4; bwidgetcnt++; RemapDeleteKey(Text4); topWidget = Text4; if (CmdText[0] == '\0') updatePrintCmd(NULL, NULL, NULL); /*********************** SEPARATOR **************************/ argcnt = 0; XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++; XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++; XtSetArg(args[argcnt], XmNtopOffset, 8); argcnt++; XtSetArg(args[argcnt], XmNtopWidget, topWidget ); argcnt++; separator = XmCreateSeparatorGadget(form, "separator", args, argcnt); bwidgetarray[bwidgetcnt] = separator; bwidgetcnt++; topWidget = separator; /********************** CANCEL BUTTON *************************/ argcnt = 0; XtSetArg(args[argcnt], XmNlabelString, (st0=XmStringCreateLtoR( "Cancel", XmSTRING_DEFAULT_CHARSET))); argcnt++; XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_POSITION); argcnt++; XtSetArg(args[argcnt], XmNleftPosition, 60); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++; XtSetArg(args[argcnt], XmNtopWidget, topWidget ); argcnt++; XtSetArg(args[argcnt], XmNtopOffset, 7); argcnt++; printCancel = XmCreatePushButton(form, "printCancel", args, argcnt); XmStringFree( st0 ); bwidgetarray[bwidgetcnt] = printCancel; bwidgetcnt++; XtAddCallback (printCancel, XmNactivateCallback, (XtCallbackProc)cancelButtonCB, NULL); /*********************** PRINT BUTTON **************************/ argcnt = 0; XtSetArg(args[argcnt], XmNlabelString, (st0=XmStringCreateLtoR( "Print", XmSTRING_DEFAULT_CHARSET))); argcnt++; XtSetArg(args[argcnt], XmNshowAsDefault, True); argcnt++; XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_POSITION); argcnt++; XtSetArg(args[argcnt], XmNrightPosition, 40); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++; XtSetArg(args[argcnt], XmNtopWidget, topWidget ); argcnt++; XtSetArg(args[argcnt], XmNtopOffset, 7); argcnt++; printOk = XmCreatePushButton(form, "printOk", args, argcnt); XmStringFree( st0 ); bwidgetarray[bwidgetcnt] = printOk; bwidgetcnt++; XtAddCallback (printOk, XmNactivateCallback, (XtCallbackProc)printButtonCB, NULL); argcnt = 0; XtSetArg(args[argcnt], XmNcancelButton, printCancel); argcnt++; XtSetArg(args[argcnt], XmNdefaultButton, printOk); argcnt++; XtSetValues(form, args, argcnt); XtManageChildren(bwidgetarray, bwidgetcnt); AddDialogMnemonicHandler(form); return form; } static void setQueueLabelText() { Arg args[15]; int argcnt; XmString st0; char tmp_buf[MAX_QUEUE_STR+8]; if (DefaultQueue[0] != '\0') sprintf(tmp_buf, "Queue (%s)", DefaultQueue); else sprintf(tmp_buf, "Queue"); argcnt = 0; XtSetArg(args[argcnt], XmNlabelString, (st0=XmStringCreateLtoR( tmp_buf, XmSTRING_DEFAULT_CHARSET))); argcnt++; XtSetValues (Label2, args, argcnt); XmStringFree( st0 ); } static void setHostLabelText() { Arg args[15]; int argcnt; XmString st0; char tmp_buf[MAX_HOST_STR+7]; if (strcmp(DefaultHost, "")) sprintf(tmp_buf, "Host (%s)", DefaultHost); else sprintf(tmp_buf, "Host"); argcnt = 0; XtSetArg(args[argcnt], XmNlabelString, (st0=XmStringCreateLtoR( tmp_buf, XmSTRING_DEFAULT_CHARSET))); argcnt++; XtSetValues (Label3, args, argcnt); XmStringFree( st0 ); } static void allowOnlyNumInput(Widget widget, caddr_t client_data, XmTextVerifyCallbackStruct *call_data) { int i, textInserted, nInserted; nInserted = call_data->text->length; textInserted = (nInserted > 0); if ((call_data->reason == XmCR_MODIFYING_TEXT_VALUE) && textInserted) { for (i=0; itext->ptr[i])) { call_data->doit = False; return; } } } call_data->doit = True; } /* ** Prohibit a relatively random sampling of characters that will cause ** problems on command lines */ static void noSpaceOrPunct(Widget widget, caddr_t client_data, XmTextVerifyCallbackStruct *call_data) { int i, j, textInserted, nInserted; #ifndef VMS static char prohibited[] = " \t,;|<>()[]{}!@?"; #else static char prohibited[] = " \t,;|@+"; #endif nInserted = call_data->text->length; textInserted = (nInserted > 0); if ((call_data->reason == XmCR_MODIFYING_TEXT_VALUE) && textInserted) { for (i=0; itext->ptr[i] == prohibited[j]) { call_data->doit = False; return; } } } } call_data->doit = True; } static void updatePrintCmd(Widget w, caddr_t client_data, caddr_t call_data) { char command[MAX_CMD_STR], copiesArg[MAX_OPT_STR+MAX_INT_STR]; char jobArg[MAX_NAME_STR], hostArg[MAX_OPT_STR+MAX_HOST_STR]; char queueArg[MAX_OPT_STR+MAX_QUEUE_STR]; char *str; int nCopies; #ifdef VMS char printJobName[VMS_MAX_JOB_NAME_STR+1]; #endif /*VMS*/ /* read each text field in the dialog and generate the corresponding command argument */ if (CopiesOption[0] == '\0') { copiesArg[0] = '\0'; } else { str = XmTextGetString(Text1); if (str[0] == '\0') { copiesArg[0] = '\0'; } else { if (sscanf(str, "%d", &nCopies) != 1) { copiesArg[0] = '\0'; } else { sprintf(copiesArg, " %s%s", CopiesOption, str); } } XtFree(str); } if (QueueOption[0] == '\0') { queueArg[0] = '\0'; } else { str = XmTextGetString(Text2); if (str[0] == '\0') queueArg[0] = '\0'; else sprintf(queueArg, " %s%s", QueueOption, str); XtFree(str); } if (HostOption[0] == '\0') { hostArg[0] = '\0'; } else { str = XmTextGetString(Text3); if (str[0] == '\0') hostArg[0] = '\0'; else sprintf(hostArg, " %s%s", HostOption, str); XtFree(str); } if (NameOption[0] == '\0') jobArg[0] = '\0'; else { #ifdef VMS /* truncate job name on VMS systems or it will cause problems */ strncpy(printJobName,PrintJobName,VMS_MAX_JOB_NAME_STR); printJobName[VMS_MAX_JOB_NAME_STR] = '\0'; sprintf(jobArg, " %s\"%s\"", NameOption, printJobName); #else sprintf(jobArg, " %s\"%s\"", NameOption, PrintJobName); #endif } /* Compose the command from the options determined above */ sprintf(command, "%s%s%s%s%s", PrintCommand, copiesArg, queueArg, hostArg, jobArg); /* display it in the command text area */ XmTextSetString(Text4, command); } static void printButtonCB(Widget widget, caddr_t client_data, caddr_t call_data) { char *str, command[MAX_CMD_STR]; #ifdef VMS int spawn_sts; int spawnFlags=CLI$M_NOCLISYM; struct dsc$descriptor cmdDesc; /* get the print command from the command text area */ str = XmTextGetString(Text4); /* add the file name to the print command */ sprintf(command, "%s %s", str, PrintFileName); XtFree(str); /* append /DELETE to print command if requested */ if (DeleteFile) strcat(command, "/DELETE"); /* spawn the print command */ cmdDesc.dsc$w_length = strlen(command); cmdDesc.dsc$b_dtype = DSC$K_DTYPE_T; cmdDesc.dsc$b_class = DSC$K_CLASS_S; cmdDesc.dsc$a_pointer = command; spawn_sts = lib$spawn(&cmdDesc,0,0,&spawnFlags,0,0,0,0,0,0,0,0); if (spawn_sts != SS$_NORMAL) { DialogF(DF_WARN, widget, 1, "Unable to Print:\n%d - %s\n spawnFlags = %d\n", "Acknowledged", spawn_sts, strerror(EVMSERR, spawn_sts), spawnFlags); return; } #else int nRead; FILE *pipe; char errorString[MAX_PRINT_ERROR_LENGTH]; /* get the print command from the command text area */ str = XmTextGetString(Text4); /* add the file name and output redirection to the print command */ sprintf(command, "cat %s | %s 2>&1", PrintFileName, str); XtFree(str); /* Issue the print command using a popen call and recover error messages from the output stream of the command. */ pipe = popen(command,"r"); if (pipe == NULL) { DialogF(DF_WARN, widget, 1, "Unable to Print:\n%s", "Acknowledged", strerror(errno)); return; } errorString[0] = 0; nRead = fread(errorString, sizeof(char), MAX_PRINT_ERROR_LENGTH-1, pipe); if (!ferror(pipe)) errorString[nRead] = '\0'; if (pclose(pipe)) { DialogF(DF_WARN, widget, 1, "Unable to Print:\n%s", "Acknowledged", errorString); return; } #endif /*(VMS)*/ /* Print command succeeded, so retain the current print parameters */ if (CopiesOption[0] != '\0') { str = XmTextGetString(Text1); strcpy(Copies, str); XtFree(str); } if (QueueOption[0] != '\0') { str = XmTextGetString(Text2); strcpy(Queue, str); XtFree(str); } if (HostOption[0] != '\0') { str = XmTextGetString(Text3); strcpy(Host, str); XtFree(str); } str = XmTextGetString(Text4); strcpy(CmdText, str); XtFree(str); /* Pop down the dialog */ DoneWithDialog = True; } static void cancelButtonCB(Widget widget, caddr_t client_data, caddr_t call_data) { DoneWithDialog = True; } #ifndef VMS /* ** Is the filename file in the directory dirpath ** and does it have at least some of the mode_flags enabled ? */ static int fileInDir(char *filename, char *dirpath, unsigned short mode_flags) { DIR *dfile; #ifdef USE_DIRENT struct dirent *DirEntryPtr; #else struct direct *DirEntryPtr; #endif struct stat statbuf; char fullname[MAXPATHLEN]; dfile = opendir(dirpath); if (dfile != NULL) { while ((DirEntryPtr=readdir(dfile)) != NULL) { if (!strcmp(DirEntryPtr->d_name, filename)) { strcpy(fullname,dirpath); strcat(fullname,"/"); strcat(fullname,filename); stat(fullname,&statbuf); closedir(dfile); return statbuf.st_mode & mode_flags; } } closedir(dfile); } return False; } /* ** Is the filename file in the environment path directories ** and does it have at least some of the mode_flags enabled ? */ static int fileInPath(char *filename,unsigned short mode_flags) { char path[MAXPATHLEN]; char *pathstring,*lastchar; /* Get environmental value of PATH */ pathstring = getenv("PATH"); if (pathstring == NULL) return False; /* parse the pathstring and search on each directory found */ do { /* if final path in list is empty, don't search it */ if (!strcmp(pathstring, "")) return False; /* locate address of next : character */ lastchar = strchr(pathstring, SEPARATOR); if (lastchar != NULL) { /* if more directories remain in pathstring, copy up to : */ strncpy(path, pathstring, lastchar-pathstring); path[lastchar-pathstring] = '\0'; } else { /* if it's the last directory, just copy it */ strcpy(path, pathstring); } /* search for the file in this path */ if(fileInDir(filename, path, mode_flags)) return True; /* found it !! */ /* point pathstring to start of new dir string */ pathstring = lastchar + 1; } while( lastchar != NULL ); return False; } /* ** Is flpr present in the search path and is it executable ? */ static int flprPresent() { /* Is flpr present in the search path and is it executable ? */ return fileInPath("flpr",0111); } static int foundTag(char *tagfilename,char *tagname,char *result) { FILE *tfile; char tagformat[512],line[512]; strcpy(tagformat, tagname); strcat(tagformat, " %s"); tfile = fopen(tagfilename,"r"); if (tfile != NULL) { while (!feof(tfile)) { fgets(line,sizeof(line),tfile); if (sscanf(line,tagformat,result) != 0) return True; } } return False; } static int foundEnv(char *EnvVarName,char *result) { char *dqstr; dqstr = getenv(EnvVarName); if (dqstr != NULL) { strcpy(result,dqstr); return True; } return False; } static void getFlprHostDefault(char *defhost) { if (!foundEnv("FLPHOST",defhost)) if(!foundTag("/usr/local/etc/flp.defaults", "host", defhost)) strcpy(defhost,""); } static void getFlprQueueDefault(char *defqueue) { if (!foundEnv("FLPQUE",defqueue)) if (!foundTag("/usr/local/etc/flp.defaults", "queue", defqueue)) strcpy(defqueue,""); } static void getLprQueueDefault(char *defqueue) { if (!foundEnv("PRINTER",defqueue)) strcpy(defqueue,""); } static void getLpQueueDefault(char *defqueue) { if (!foundEnv("LPDEST",defqueue)) defqueue[0] = '\0'; } #endif #ifdef VMS static void getVmsQueueDefault(char *defqueue) { int translate_sts; short ret_len; char logicl[12], tabl[15]; struct itemList { short bufL; short itemCode; char *queName; short *lngth; int end_entry; } translStruct; struct dsc$descriptor tabName; struct dsc$descriptor logName; sprintf(tabl, "LNM$FILE_DEV"); tabName.dsc$w_length = strlen(tabl); tabName.dsc$b_dtype = DSC$K_DTYPE_T; tabName.dsc$b_class = DSC$K_CLASS_S; tabName.dsc$a_pointer = tabl; sprintf(logicl, "SYS$PRINT"); logName.dsc$w_length = strlen(logicl); logName.dsc$b_dtype = DSC$K_DTYPE_T; logName.dsc$b_class = DSC$K_CLASS_S; logName.dsc$a_pointer = logicl; translStruct.itemCode = LNM$_STRING; translStruct.lngth = &ret_len; translStruct.bufL = 99; translStruct.end_entry = 0; translStruct.queName = defqueue; translate_sts = sys$trnlnm(0,&tabName,&logName,0,&translStruct); if (translate_sts != SS$_NORMAL && translate_sts != SS$_NOLOGNAM){ fprintf(stderr,"Error return from sys$trnlnm: %d\n", translate_sts); DialogF(DF_WARN,Label2,1,"Error translating SYS$PRINT","Acknowledged"); defqueue[0] = '\0'; } else /* printf("return status from sys$trnlnm = %d\n", translate_sts); */ if (translate_sts == SS$_NOLOGNAM) defqueue[0] = '\0'; else { strncpy(defqueue, translStruct.queName, ret_len); defqueue[ret_len] = '\0'; /* printf("defqueue = %s, length = %d\n", defqueue, ret_len); */ } } #endif