* remotegps.c *
* Remote print to CTOS GPS via FTP for an IBM RS6000 running AIX. *
* This C program is roughly equivalent to the remotegps.sh shell script *
* supplied by Sirius software *
* It uses absolute file names (e.g. usrfredbill) not just bill *
* as remotegps.sh does.  This is done up to a max. of 50 chars *
* (ctos max. file length)  including printer_job.  This should *
* avoid any unpleasant surprises if you print, say, usrfredjack *
* and usrbilljack.  remotegps.sh will overwrite the file *
* and works in harness with the CTOS remotegps server provided *
* by Sirius software. *
* Written by Andy Savige, Convergent Solutions (Australia) Sep 1990 *

* Add a queue called, say, 'ctos' to etcqconfig and service the queue *
* with this program. *
* For example, add the following lines to the end of etcqconfig *
*     ctos:                                        *
*         device = ctosdev                         *
*         discipline = fcfs                        *
*     ctosdev:                                     *
*         backend = usrconsolsiriusremotegps   *
* Here, usrconsolsiriusremotegps is the executable got from *
* compiling this program with the command: *
*     cc O o remotegps remotegps.c *

* to print a file to the default ctos gps printer *
* use: qprt Pctos filelist *
*  or: lp dctos filelist *
* or you could use *
*     qprt Pctos o'2 hplaser' *
* to print to the gps device called hplaser in mode 2 (image mode) *
* see also the comments in Sirius' remotegps.sh script *

include <stdio.h>
include <stdlib.h>
include <string.h>
include <ctype.h>
include <errno.h>
include <sysutsname.h>  * uname *
include <pwd.h>          * getpwuid *

define NIL_PTR  ((char *)0)
define MAX_CTOS_FILE_LEN	50
define FTP_FILE_MODE		0777

static const char progname[] = remotegps;

static char temp[256];
static char line[256];

*===========================================================================*
* stuff that needs to be edited (and program recompiled) are here *
* tcpip name of ctos host (edit this) *
static const char remotehost[] = consol;

* name of AIX print queue (edit to match the queue defined *
* in etcqconfig) *
static char printer[] = ctos;

* ctos ftp login name and password (normally gps with no password) *
static char ctosftplogin[] = gps;
* next line currently not implemented (i.e. you can't password gps login) *
* (will fix later) *
static char ctosftppasswd[] = ;
*===========================================================================*

static char host[64];	* tcpip name of Unix host *


static char job[10];
static char owner[64];
static char title[] = ;
static int copies = 1;
static char mode = '0';		* GPS mode (0 = normal) *
static char device[64];		* GPS device name *

static const char ftpscript[] = tmpgps_ftp;
static const char paramsfile[] = tmpgps_params;

* print error message and die *

static void MyError(const char *s1, const char *s2)
{
	fprintf(stderr, s: , progname);
	if (s1) fputs(s1, stderr);
	if (s2) fputs(s2, stderr);
	if (errno = 0)
		fprintf(stderr, \ns\n, strerror(errno));
	else
		fputc('\n', stderr);
	exit(EXIT_FAILURE);
}

* input full path, return pointer to relname *
* e.g. input usrconsolfred, return pointer to fred *
ifdef OLD
static char *GetRelName(const char *fname)
{
	char *p;
	for (p = fname + strlen(fname); p >= fname  *p = ''; p) ;
	return p+1;
}
endif
* input fname and maxlen and truncate fname by putting '\0' *
* at index [maxlen] if too long. return ptr to fname *
static char *TruncName(char *fname, int maxlen)
{
	if (strlen(fname) > maxlen) *(fname+maxlen) = '\0';
	return fname;
}

main(int argc, char *argv[])
{
	register int i;
	FILE *fpscript, *fpparams;
	int ind;
	char *p;
	int fstart;   * index into argv[] where filenames start *
	struct utsname name;
	unsigned short euid;  * 'effective' uid *
	int pid;
	int maxlen;

	*Get Basic Stuff*
	* get host name *

	if ((ind = uname(name)) < 0) MyError(error getting uname, NIL_PTR);
	strcpy(host, name.nodename);

	* get 'job' which must be unique for each job to avoid *
	* files getting overwritten on CTOS (use process id) *

	pid = getpid();
	sprintf(job, d, pid);

	* get 'effective' user name (owner) *

	euid = geteuid();
	strcpy(owner, getpwuid(euid)>pw_name);

	* argv[0] is program name, then come *
	* flags e.g. A (but not N2) *
	* then come options e.g. o'2 hplaser', argv[1] = 2 hplaser *
	* then (absolute) file list (e.g. usrandyfred) *
	* the following code is a little flaky  sorry *

	device[0] = '\0';
	for (i = 1; i < argc  *argv[i] = ''; i++) {
		if (*argv[i] == '')
			;  * ignore 'weird' options to qprt *
		else {  * we have input from e.g. o'2 hplaser' *
			strcpy(temp, argv[i]);
			if ((p = strtok(temp,  )) == NULL)
				MyError(No token, NIL_PTR);
			if (isdigit(*p)) {  * mode *
				mode = *p;
				if ((p = strtok(NULL,  )) = NULL)
					strcpy(device, p);
			}
			else {
				strcpy(device, p);
			}
		}
	}
	fstart = i;
	**
	* write ftp script file *

	if ((fpscript = fopen(ftpscript, w)) == NULL)
		MyError(Couldn't open , ftpscript);
	fprintf(fpscript, open s\n, remotehost);
	fprintf(fpscript, s\n, ctosftplogin);
	fprintf(fpscript, type image\n);
	maxlen = MAX_CTOS_FILE_LEN  strlen(printer)  strlen(job)  2;
	for (i = fstart; i < argc; i++) {
		fprintf(fpscript, put s s_s_,
		argv[i], printer, job);
		fprintf(fpscript, s\n, TruncName(argv[i], maxlen));
	}
	fprintf(fpscript, put s s_s_params\n,
	paramsfile, printer, job);
	fprintf(fpscript, bye\n);
	if (fclose(fpscript) == EOF)
		MyError(Error closing , ftpscript);
	if (chmod(ftpscript, FTP_FILE_MODE) == 1)
		MyError(Error changing mode, ftpscript);

	* write params file (overwrite existing one) *

	if ((fpparams = fopen(paramsfile, w)) == NULL)
		MyError(Couldn't open , paramsfile);

	* put initial guff in params file *

	fprintf(fpparams, :Host:s\n, host);
	fprintf(fpparams, :Printer:s\n, printer);
	fprintf(fpparams, :Job:s\n, job);
	fprintf(fpparams, :Owner:s\n, owner);
	fprintf(fpparams, :Title:s\n, title);
	fprintf(fpparams, :Copies:d\n, copies);

ifdef DEBUG
for (i = 0; i < argc; i++)
 fprintf(fpparams, :Params:d:s\n, i, argv[i]);
endif

	fprintf(fpparams, :Mode:c\n, mode);
	if (*device = '\0') fprintf(fpparams, :Device:s\n, device);
	for (i = fstart; i < argc; i++)
		fprintf(fpparams, :File:s\n, argv[i]);

	if (fclose(fpparams) == EOF)
		MyError(Error closing , paramsfile);
	if (chmod(paramsfile, FTP_FILE_MODE) == 1)
		MyError(Error changing mode, paramsfile);

	* send the script off via ftp *

ifndef DEBUG
	sprintf(line, usrucbftp <s >devnull, ftpscript);
	if ((ind = system(line)) = 0) {
		sprintf(temp, d, ind);
		MyError(System error , temp);
	}
	if (remove(paramsfile) = 0)
		MyError(error deleting params file, NIL_PTR);
	if (remove(ftpscript) = 0)
		MyError(error deleting ftpscript file, NIL_PTR);
endif

	return EXIT_SUCCESS;
}
