home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- *
- * Program Name:jserver - Generic Job Server Front-End
- *
- * Filename:jserver.c
- *
- * Date Created: November 21, 1988
- *
- * Version: 1.0
- *
- * Programmers:Tom Brough, Milt Anderson, Cliff Ross, Greg Peto
- *
- * Files used:..\genjob.obj
- *
- * Date Modified: Jan. 28, 1989
- *
- * Modifications: Reformated by Gregory J. Peto
- *
- * Comments:
- *
- * This command line utility works in conjucntion with the generic job
- * server utilities JSUPER, and JSERVER. It is designed to let the
- * user submit a dos command line to the job queue for remote
- * execution on a job server machine.
- * See the function of badUsage for summary of possible command line arguments
- * to this utility. All command line arguments are expected in the
- * form:
- * /<command keyword>=<command argument>
- * To locate where global variables are initialized or set, look at
- * ComAndInit for command line settings or for the variables as
- * output variables passed to a function call.
- * BUGS: A TSR utility should be designed that can catch the acknowledge
- * signal from the server machine to the client that displays the
- * message when sitting idol at command.com (similar to UNIX)
- * instead of forcing user to respond.
- ****************************************************************************/
-
- /* functions in this file:
- */
- #include "..\genjob.h"
- /* #include<nitipx.h> */
- #include<sys\types.h>
- #include<sys\stat.h>
- #include<signal.h>
- #include<process.h>
- #include<ctype.h>
-
- /* constants definitions */
- #defineVERB_TEST1 /* want verbose test messages */
-
-
- /* global variables and data types */
- COMMAND_ARGS command_args[] =
- /* token, keyword num sig,req. string,req. int */
- {
- # defineCOM_DELAY1
- { COM_DELAY, "DELAY", 1,FALSE,TRUE},
- # defineCOM_SERVERCOM_DELAY + 1
- { COM_SERVER, "SERVER", 1,TRUE,FALSE}
- };
-
- int secWaitForCheckJob= 10;/* number seconds wait to check for job */
-
- JobStruct job; /* QMS job struct to be used in calls */
- WORD jobType = 0xffff;/* job type number, default is any */
- JOBFILE jobFile; /* buffer of job file */
- CLIENT_REC_AREAjobClientArea;/* buffer of job client record area */
- JOBFILE serverEnviron;/* server workstation environ for
- restoration after job finishes */
-
- /* module specific varables and data types */
- /* macro definitions */
-
- /*****************************************************************************/
-
- main(argc,argv,envp)
- /* Descrip:
- This program supports the generic job server. This utility
- allow the user ot submit DOS command lines to be executed
- remotely.
- Algorithm://
- Parse and handle command line arguments, initialize defaults
- Initialize queue server status.
- Catch signals so server removed from queue if ends abnormally.
- while server is running
- if console input, handle it.
- if still running and time to check
- reset wait count
- if job to service
- service it
- wait minimum time and decrement wait count
- */
- /* Input: */
- int argc;
- char *argv[];
- char *envp[];
-
- { /* main // */
- BOOLEANserverRunning= TRUE;
- int waitCount= 0; /* check immediate for job */
- BOOLEANserverWasActive = TRUE;/* get unactive message first time
- through */
- int shandler(); /* signal handler */
- /*--------------------------------------------------main body */
- #if 0
- if (argc == 1)
- BadUsage(NULL);/* missing command line arguments */
- #endif
-
- ComAndInit(--argc,++argv);/* skip past program name */
- InitServer(jobServerConID,jobQueueID);
- /* catch any abnormal temination signals so can disconnect from queue */
- signal(SIGINT,shandler);
- signal(SIGFPE,shandler);
- signal(SIGABRT,shandler);
- /* save server environment so can restore later */
- GetJobEnviron(NULL,&serverEnviron);
-
- while (serverRunning)
- {
- if (kbhit())
- serverRunning= HandleConsoleInput();
-
- if (serverRunning AND waitCount <= 0)
- { /* check for job to service */
- waitCount= secWaitForCheckJob;
- if (CheckForJob())
- { /* found job to execute, and did it */
- serverWasActive= TRUE;
- waitCount = 0;/* check immediate again */
- } else if (serverWasActive)
- {
- printf("\nJob Server: idle, no jobs to service.\n");
- serverWasActive= FALSE;
- }
- } /* if waitCount */
-
- WaitIPX(18);/* wait 18 clock ticks, approx. 1 second */
- --waitCount;
- } /* while serverRunning */
-
- JobServerExit(0);
- } /* of main */
-
- /********************************************************************/
-
- int shandler(ecode)
- /* Descrip:
- This function catches interrupts from OS, terminates gracefully.
- Algorithm://
- */
- /* Input: */
- intecode;
-
- { /* // */
- /*--------------------------------------------------main body */
- JobServerExit(1);
- } /* end of shandler */
-
- /********************************************************************/
-
- BadUsage(message)
- /* Descrip:
- This function is called when a fatal error is detected in the
- command line. It displays the command format and options
- and then exits the program.
- Algorithm://
- */
- /* Input: */
- char*message;/* optional explanatory message */
- /* Output: */
-
- { /* BadUsage // */
- /*--------------------------------------------------main body */
- if (message)
- printf("Error: %s\n\n",message);
- printf("usage: jserver [<command parameters>]\n\n");
- printf(" /Server=<target server with job queue>\n");
- printf(" /Delay=<number seconds wait to query for job>\n");
-
- exit(1);
- } /* end of BadUsage */
-
- /********************************************************************/
-
- ComAndInit(argc,argv)
- /* Descrip:
- This function parses command line input and sets default values.
- Several global variables may be changed from their default values
- by command line arguments.
- Algorithm://
- Scans command line arguments, overiding defaults as needed.
- See top of this file for notes on expected form of command
- line option and badUsage for specific form of commands.
- Saves remote execution command line in jobClientArea.
- Find server of target queue and save in global variable.
- BUGS:
- Not all command line options implemented yet.
- */
- /* Input: */
- int argc;
- char *argv[];
- /* Output: */
-
- { /* ComAndInit // */
- /* name of server with job queue */
- char queueServerName[MAX_FSERVER_NAME];
- char argString[MAX_ARG_VAR];/* command parameter variable buffer */
- long argInt; /* numeric parameter variable */
- JOB_TIMEargTime; /* time parameter */
- JOB_DATEargDate; /* date parameter */
- /*--------------------------------------------------main body */
- queueServerName[0]= '\0';
-
- for (;argc; --argc, ++argv)
- {
- if (*argv[0] NOT= '/')
- badUsage("Unrecognized command line arguement");
- switch (ScanArg((*argv) + 1,command_args,
- sizeof(command_args)/sizeof(COMMAND_ARGS),
- argString,&argInt,&argTime,&argDate))
- {
- caseCOM_DELAY:
- printf("Seconds to wait to check for job set to %d\n",
- secWaitForCheckJob = argInt);
- break;
- caseCOM_SERVER:
- if (strlen(argString) > (MAX_FSERVER_NAME - 1))
- {
- printf("Server name length must be less than %d, aborting\n",
- MAX_FSERVER_NAME - 1);
- exit(1);
- }
- strcpy(queueServerName,argString);
- break;
- default:
- printf("Internal error: ComAndInit");
- exit(1);
- } /* end of switch on ScanArg */
-
- } /* end of for argc loop */
-
- FindJobServer(queueServerName,TRUE);
- if (jobQueueID == NULL)
- {
- printf("Could not find any server with job queue.\n");
- exit(1);
- }
-
- # if VERB_TEST
- printf("Found server %s, connection ID %x\n",
- queueServerName ? "(default)" : queueServerName,
- jobServerConID);
- # endif
- } /* end of ComAndInit */
-
- /********************************************************************/
-
- InitServer(conID,queueID)
- /* Descrip:
- This function attempts register this program as a job server
- at the server conID for queue queueID.
- Algorithm://
- */
- /* Input: */
- BYTE conID; /* connection ID to server with queue */
- long queueID;/* queue bindery ID for queue on server */
-
- /* Output: */
-
- { /* InitServer // */
- intccode;
- /*--------------------------------------------------main body */
- SetPreferredConnectionID(conID);
- if (ccode = AttachQueueServerToQueue(queueID))
- {
- switch (ccode)
- {
- case NO_Q_RIGHTS:
- printf("Insufficient rights to be server for job queue.\n");
- break;
- case NO_SUCH_MEMBER:
- printf("Not member of queue server list.\n");
- break;
- case Q_HALTED:
- printf("Job queue is halted, unable to serve it.\n");
- break;
- case SERVER_BINDERY_LOCKED:
- case BINDERY_FAILURE:
- printf("Server bindery locked or broken, unable to service.\n");
- break;
- default:
- printf("Unable to attach to queue as server.\n");
- } /* end of switch ccode */
- exit(1);
- } /* end of if */
- } /* end of InitServer */
-
- /********************************************************************/
-
- BOOLEAN HandleConsoleInput()
- /* Descrip:
- This function is called when user keyboard interraction
- detected. Gets user input, and executes user request.
- Returns TRUE if user wished to continue as server, else FALSE.
- Algorithm://
- Stubbed for now.
- */
-
- { /* HandleConsoleInput // */
- /*--------------------------------------------------main body */
- return(TRUE);
- } /* end of HandleConsoleInput */
-
- /********************************************************************/
-
- BOOLEAN CheckForJob()
- /* Descrip:
- This function checks to see if there is a job in the queue it
- can service. If one is found and executed then it returns
- TRUE, else FALSE.
- Algorithm://
- */
-
- { /* CheckForJob // */
- int ccode;
- int assocFile;/* associated file for job
- /*--------------------------------------------------main body */
- SetPreferredConnectionID(jobServerConID);
- if ((ccode = ServiceQueueJobAndOpenFile(jobQueueID,jobType,
- &job,&assocFile)) == SUCCESSFUL)
- {
- DoJob(assocFile);
- return(TRUE);
- } else
- switch (ccode)
- {
- case Q_ERROR:
- printf("Server getting queue error on request to service job.\n");
- break;
- case Q_HALTED:
- printf("Job queue is halted\n.");
- break;
- case NO_Q_JOB:/* OK, normal operation, just no jobs */
- break;
- case SERVER_BINDERY_LOCKED:
- case BINDERY_FAILURE:
- printf("Job server experiencing problems with bindery.\n");
- break;
- default:
- printf("Job server detected abnormal problem requesting job to service,\n");
- printf("aborting job server program.\n");
- JobServerExit(1);
- }
-
- return(FALSE);
- } /* end of CheckForJob */
-
- /********************************************************************/
-
- DoJob(assocFile)
- /* Descrip:
- This fucntion uses global variables and assocFile to execute
- job attached to from job queue.
- Algorithm://
- BUGS:
- It should detach itself from all file servers but one with queue
- so all 8 slots are available for the job. Would then have
- to be restored later.
- It should attempt to strip memory of any TSR's that may have been
- started and are hanging in memory that could get control with
- a different job's security rights. Maybe moot question if
- implement Reboot option in server.
- This routine should check the monitor mode and reset it to text
- if necessary.
- */
- /* Input: */
- int assocFile;
-
- { /* DoJob // */
- intcommandStatus;
- /*--------------------------------------------------main body */
- printf("Setting up job #%d\n",job.jobNumber);
- ClearServerEnviron();
- ChangeToClientRights(jobQueueID,job.jobNumber);
- read(assocFile,(char *) &jobFile,sizeof(jobFile));
- if (SetJobEnviron(&jobFile))
- /* environment setup successful, proceed */
- commandStatus= SpawnJob();
- else
- commandStatus= 1;/* mark as unsuccessful */
-
- /* signal done, no charge for doing job */
- RestoreQueueServerRights();
-
- /* restore server environment */
- ClearServerEnviron();/* strip any attachments gained by job */
- SetJobEnviron(&serverEnviron);
- if (FinishServicingQueueJobAndFile(jobQueueID,job.jobNumber,(long) 0,
- assocFile))
- printf("Job server received error when signaling done with job.\n");
- if (jobFile.flags & DO_ACK_MESS)
- AcknowledgeClient(commandStatus);
- } /* end of DoJob */
-
- /********************************************************************/
-
- ClearServerEnviron()
- /* Descrip:
- This function clears the workstation internal tables so that
- they can be rebuilt for the job.
- Algorithm://
- */
- /* Input: */
- /* Output: */
-
- { /* // */
- int drive; /* drive number checking */
- WORD conID; /* connection ID for drive (1-8) */
- /*--------------------------------------------------main body */
- for (conID = 1; conID <= MAX_SERVER_ATTACHES; ++conID)
- if (conID NOT= jobServerConID AND IsConnectionIDInUse(conID))
- {
- LogoutFromFileServer(conID);
- DetachFromFileServer(conID);
- }
- } /* end of ClearServerEnviron */
-
- /********************************************************************/
-
- int SpawnJob()
- /* Descrip:
- Spawn job command using command.com
- Returns termination code of spawned process.
- Algorithm://
- Construct spawn execute variables. envp is array of pointer
- to environment variable sets. execbuf contains fullpath
- with command.com. paramsbuf is array of ptrs to command.com
- arguments.
- Disable End Of Job (so command.com doesn't generate one)
- Spawn command.com command
- Reset End OF Job Status to old value.
- Return job completion code.
- */
- /* Input: */
- /* Output: */
-
- { /* SpawnJob // */
- int i;
- char *envp[MAX_ENV_ENTRIES + 2];
- char *comspec;
- char *path;
- # defineMAXCOMPARAMS50
- char *argv[MAXCOMPARAMS];
- char *comptr; /* ptr into command string */
- int ccode;
- # defineJOBCOMMAND (((CLIENT_REC_AREA *) &job.clientRecordArea[0])->jobCommand)
- /*--------------------------------------------------main body */
- for (i = 0; i < jobFile.numEntries; ++i)
- envp[i]= jobFile.envEntries[i];
- #if 0
- /* try to figure out why getting garbage at end of envp vector in spawned job */
- envp[i]= "DUMMY=DUMMY";
- envp[i+1]= NULL;
- #else
- envp[i]= NULL;
- envp[i+1]= NULL;
- #endif
-
- if ((comspec = getenv("COMSPEC")) == NULL)
- {
- printf("COMSPEC missing from server environment.\n");
- JobServerExit(1);
- }
-
- argv[0]= comspec;
- argv[1]= "/c";/* tell command.com only execute one command */
- i = 2; /* start at third entry in argv */
- /* skip leading "space" characters */
- while (isspace(*comptr))
- ++comptr;
- for (comptr = JOBCOMMAND; *comptr; ++i)
- {
- if (i == MAXCOMPARAMS)
- {
- printf("Too many command line parameters to setup job.\n");
- return(1);/* return error code */
- }
- argv[i]= comptr;
- /* skip past parameter */
- while (isspace(*comptr) == FALSE)
- ++comptr;
- if (*comptr == '\0')
- break; /* nothing left */
- *comptr++ = '\0'; /* mark end of parameter */
- /* skip to beginning of next parameter */
- while (isspace(*comptr))
- ++comptr;
- }
- argv[i]= NULL;
-
- printf("Spawning command: %s\n",JOBCOMMAND);
- if ((ccode = spawnve(P_WAIT,comspec,argv,envp)) < 0)
- {
- printf("Job server could not execute command:\n %s\n\n",
- JOBCOMMAND);
- perror("Spawn failed");
- return(1);
- }
- return(ccode);
- } /* end of SpawnJob */
-
- /********************************************************************/
-
- AcknowledgeClient(commandStatus)
- /* Descrip:
- This function sends the client (the job submitter)
- a broadcast message that job finished.
- Algorithm://
- */
- /* Input: */
- /* Output: */
-
- { /* AcknowledgeClient // */
- char mesBuffer[128];/* client braodcast message buffer */
- WORD clientStation;/* buffer for WORD value needed for
- broadcast */
- BYTE resultList;
- /*--------------------------------------------------main body */
- sprintf(mesBuffer,"Job %d %s.",job.jobNumber,(commandStatus == 0) ?
- "finished with successful completion code" :
- "failed");
-
- clientStation= job.clientStation;/* convert to WORD */
- if (SendBroadcastMessage(mesBuffer,&clientStation,&resultList,(WORD) 1))
- printf("Unable to broadcast messages to client.\n");
- switch (resultList)
- {
- case0:
- break; /* broadcast successful */
- case0xFC:
- printf("Job client broadcast pipe full, acknowledgement failed.\n");
- break;
- case0xFE:
- printf("Job client task does not exist, acknowledgement failed.\n");
- break;
- case 0xFF:
- printf("Job client acknowlegement braodcast failed.\n");
- }
-
- } /* end of AcknowledgeClient */
-
- /********************************************************************/
-
- WaitIPX(ticks)
- /* Descrip:
- This function will loop waiting for ticks number of ticks to
- expire using IPX interface calls.
- Algorithm://
- */
- /* Input: */
- unsigned intticks;
-
- { /* WaitIPX // */
- static intfirsttime= 1;
- unsigned intfinishTime;
- /*--------------------------------------------------main body */
- if (firsttime)
- {
- firsttime = 0;
- IPXInitialize();/* need to initialize internal variables */
- }
-
- finishTime = IPXGetIntervalMarker() + ticks;
- while (finishTime > IPXGetIntervalMarker())
- ;
- } /* end of WaitIPX */
-
- /********************************************************************/
-
- JobServerExit(ecode)
- /* Descrip:
- Exit job server program.
- Algorithm://
- */
- /* Input: */
- intecode; /* exit code to return to DOS */
-
- { /* JobServerExit // */
- /*--------------------------------------------------main body */
- if (DetachQueueServerFromQueue(jobQueueID))
- printf("Job server received error code back when detaching from queue.\n");
- exit(ecode);
- } /* end of JobServerExit */
-
- /********************************************************************/
-