home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 February
/
CHIP_2_98.iso
/
misc
/
src
/
install
/
.#printercfg.c.1.12
< prev
next >
Wrap
Text File
|
1997-10-09
|
52KB
|
2,013 lines
/* Text based printer configuration for the RHS install program */
/* Michael Fulbright - 1997 */
/* */
/* Mon Apr 14 1997 - fixed up for inclusion into 4.2 install */
/* Mon Apr 14 1997 - Erik broke everything -- blame him */
/* */
/* Last editted by msf - 11:10 Mon Apr 22 1997 */
#include <alloca.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <ctype.h>
#include <fcntl.h>
#include <grp.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <newt.h>
#include "devices.h"
#include "install.h"
#include "log.h"
#include "printercfg.h"
/* db of all entries in the printerdb file */
/* we reallocate as we read entries, so we keep numread and numallocated */
DBEntry **thedb;
int numdb, numdb_alloc;
/* root_path is the base of any path we use. During install the actual */
/* system is mounted under something like /mnt, so we have to take this */
/* into account when creating system files for the final, installed sys */
char *root_path;
/* keep up with whether we actually accomplished anything or not */
int install_return_code;
#define NUM_PAPERSIZES 5
static char *PaperSizes[NUM_PAPERSIZES] = {
"letter", "legal", "ledger", "a3", "a4" };
/* not sure what we're calling these yet */
#define NEXT_LABEL "Next"
#define PREV_LABEL "Previous"
/*******************************************/
/* Some useful utility routines come first */
/*******************************************/
/* convert the character sequence '\' \n' into a true '\n' */
/* handy for treating a string which contains the continuation char '\' */
static void insert_newlines( char *s ) {
char *p, *q;
char *tmp;
if (strlen(s)<2)
return;
tmp = strdup( s );
for (p=tmp, q=s; *(p+1); p++, q++)
if (*p == '\\' && *(p+1)=='n') {
*q = '\n';
p++;
} else
*q = *p;
*q = '\000';
free(tmp);
}
/* clean up that string */
static void trim_whitespace( char *s ) {
char *f, *l, *p, *q;
if (!(*s))
return;
for (f=s; *f && isspace(*f); f++) ;
if (!*f) {
*s = '\0';
return;
}
for (l=f+strlen(f)-1; isspace(*l) ; l--)
*l = '\0';
q = s, p = f;
while (*p)
*q++ = *p++;
*q = '\0';
}
/* set all values of a PCEntry to sane values */
void initialize_PCEntry( PCEntry *pcentry ) {
pcentry->Queue=NULL;
pcentry->SpoolDir=NULL;
pcentry->Device=NULL;
pcentry->IF=NULL;
pcentry->AF=NULL;
pcentry->Type=NULL;
pcentry->db=NULL;
pcentry->Resolution=NULL;
pcentry->PaperSize=NULL;
pcentry->AutoEOF=NULL;
pcentry->BitsPerPixel=NULL;
pcentry->CRLF=NULL;
pcentry->RevPages=NULL;
pcentry->RemoteHost=NULL;
pcentry->RemoteQueue=NULL;
pcentry->SMBHost=NULL;
pcentry->SMBHostIP=NULL;
pcentry->SMBShare=NULL;
pcentry->SMBUser=NULL;
pcentry->SMBPasswd=NULL;
}
/* allocate a new PrintCap Entry */
static PCEntry *new_PCEntry() {
PCEntry *pcentry;
pcentry = (PCEntry *) malloc(sizeof(PCEntry));
initialize_PCEntry( pcentry );
return pcentry;
}
/* duplicate an existing PrintCap Entry */
/* all strings are REALLOCATED, so new PCEntry is not dependent on original */
static PCEntry *dup_PCEntry( PCEntry *orig ) {
PCEntry *pcentry;
pcentry = new_PCEntry();
if (orig->Queue)
pcentry->Queue=strdup(orig->Queue);
if (orig->SpoolDir)
pcentry->SpoolDir=strdup(orig->SpoolDir);
if (orig->Device)
pcentry->Device=strdup(orig->Device);
if (orig->IF)
pcentry->IF=strdup(orig->IF);
if (orig->AF)
pcentry->AF=strdup(orig->AF);
if (orig->Type)
pcentry->Type=strdup(orig->Type);
pcentry->db=orig->db;
if (orig->Resolution)
pcentry->Resolution=strdup(orig->Resolution);
if (orig->PaperSize)
pcentry->PaperSize=strdup(orig->PaperSize);
if (orig->AutoEOF)
pcentry->AutoEOF=strdup(orig->AutoEOF);
if (orig->BitsPerPixel)
pcentry->BitsPerPixel=strdup(orig->BitsPerPixel);
if (orig->CRLF)
pcentry->CRLF=strdup(orig->CRLF);
if (orig->RevPages)
pcentry->RevPages=strdup(orig->RevPages);
if (orig->RemoteHost)
pcentry->RemoteHost=strdup(orig->RemoteHost);
if (orig->RemoteQueue)
pcentry->RemoteQueue=strdup(orig->RemoteQueue);
if (orig->SMBHost)
pcentry->SMBHost=strdup(orig->SMBHost);
if (orig->SMBHostIP)
pcentry->SMBHostIP=strdup(orig->SMBHostIP);
if (orig->SMBShare)
pcentry->SMBShare=strdup(orig->SMBShare);
if (orig->SMBUser)
pcentry->SMBUser=strdup(orig->SMBUser);
if (orig->SMBPasswd)
pcentry->SMBPasswd=strdup(orig->SMBPasswd);
return pcentry;
}
/* Free an existing PrintCap Entry */
static void free_PCEntry( PCEntry *pcentry) {
free(pcentry->Queue);
free(pcentry->SpoolDir);
free(pcentry->Device);
free(pcentry->IF);
free(pcentry->AF);
free(pcentry->Type);
free(pcentry->Resolution);
free(pcentry->PaperSize);
free(pcentry->AutoEOF);
free(pcentry->BitsPerPixel);
free(pcentry->CRLF);
free(pcentry->RevPages);
free(pcentry->RemoteHost);
free(pcentry->RemoteQueue);
free(pcentry->SMBHost);
free(pcentry->SMBHostIP);
free(pcentry->SMBShare);
free(pcentry->SMBUser);
free(pcentry->SMBPasswd);
free(pcentry);
}
/* Read lines from file, ignoring lines starting with a '#' and */
/* observing continuation lines (lines which end with a '\') */
/* All leading and trailing spaces are removed, as well as \n */
/* Returns zero if no more input available */
static char *pc_getline(FILE *file) {
int done;
char buf[256];
char *fresult;
char *line;
int len;
line = NULL;
done=0;
while (!done) {
fresult=fgets( buf, 256, file );
if (!fresult)
return NULL;
trim_whitespace( buf );
if (! (*buf) )
continue;
if (*buf == '#')
continue;
len = strlen( buf );
if ( *(buf+len-1) != '\\' )
done = 1;
else {
/* silly rule - make sure line ends with a space */
if ( len > 2 && *(buf+len-2) != ' ' ) {
*(buf+len-1) = ' ';
*(buf+len) = '\000';
} else
*(buf+len-1) = '\000';
}
if (!line)
line = strdup(buf);
else {
line = (char *) realloc( line, strlen(line) + strlen (buf) + 1 );
strcpy( line+strlen(line), buf );
}
}
return line;
}
/* strips out the value of a Parameter in the printer db file */
static char *getfield( char *s ) {
char *f, *p;
f = strchr(s, ':');
if (!f)
return NULL;
p = strdup(f+1);
trim_whitespace(p);
if (! (*p))
return NULL;
else
return p;
}
/* looks for exactly flds fields, with each field enclosed in a {} pair. */
static int parsefields( char *s, char **flds) {
char *f, *l;
char *p;
int n;
int i;
flds[0] = NULL;
flds[1] = NULL;
flds[2] = NULL;
n = 0;
p = s;
for (i=0; i<3; i++) {
f = strchr(p, '{');
if (!f)
return n;
l = strchr(f, '}');
if (!l)
return n;
flds[n] = (char *) malloc( l-f+2 );
strncpy( flds[n], f+1, l-f-1 );
*((flds[n])+(l-f)-1) = '\000';
p = l+1;
n++;
}
return n;
}
static int dbCompare(const void * a, const void * b) {
const DBEntry * const *first = a;
const DBEntry * const *second = b;
return strcmp((*first)->Descr, (*second)->Descr);
}
/* Read the printer database dbpath into memory */
/* returns non-zero on error */
static int read_printer_db( char *dbpath ) {
FILE *dbfile;
char *line;
char *tmpstr;
char *fields[3];
int nfield;
DBEntry *entry;
int nbpp, nres;
int nbpp_alloc, nres_alloc;
tmpstr=malloc(strlen(dbpath)+strlen(root_path)+2);
strcpy(tmpstr,root_path);
strcat(tmpstr,dbpath);
if ((dbfile=fopen(tmpstr, "r")) == NULL) {
free(tmpstr);
return -1;
}
free(tmpstr);
/* loop till we find the start of an entry */
/* we obviously want to ignore any comments on the way */
numdb = numdb_alloc = 0;
while ((line=pc_getline(dbfile))) {
if (!strncmp(line, "StartEntry:", 11)) {
entry = (DBEntry *) malloc( sizeof(DBEntry) );
entry->Entry = getfield(line);
entry->GSDriver = NULL;
entry->Descr = NULL;
entry->About = NULL;
entry->Resolution = NULL;
entry->ResDescr = NULL;
entry->BitsPerPixel = NULL;
entry->BppDescr = NULL;
nres = nres_alloc = 0;
nbpp = nbpp_alloc = 0;
free(line);
if (!entry->Entry) {
free(entry);
continue;
}
numdb++;
if (numdb >= numdb_alloc ) {
numdb_alloc += 25;
thedb=(DBEntry **)realloc(thedb,
sizeof(DBEntry *)*(numdb_alloc));
}
thedb[numdb - 1] = entry;
while ((line=pc_getline(dbfile))) {
if (!strncmp(line, "EndEntry", 8))
break;
if (!strncmp(line, "GSDriver:", 9)) {
if (entry->GSDriver)
break;
entry->GSDriver=getfield(line);
}
if (!strncmp(line, "Description:", 12)) {
if (entry->Descr)
break;
tmpstr=getfield(line);
nfield = parsefields(tmpstr, fields);
free(tmpstr);
if (nfield == 1 )
entry->Descr=fields[0];
else
break;
}
if (!strncmp(line, "About:", 6)) {
if (entry->About)
break;
tmpstr=getfield(line);
nfield = parsefields(tmpstr, fields);
free(tmpstr);
if (nfield == 1) {
trim_whitespace(fields[0]);
insert_newlines(fields[0]);
entry->About=fields[0];
} else
break;
}
if (!strncmp(line, "Resolution:", 11)) {
tmpstr=getfield(line);
nfield = parsefields(tmpstr, fields);
free(tmpstr);
if (nfield == 3) {
nres++;
if (nres >= nres_alloc) {
nres_alloc += 10;
entry->Resolution=
(char **)realloc(entry->Resolution,
nres_alloc*sizeof(char*));
entry->ResDescr=
(char **)realloc(entry->ResDescr,
nres_alloc*sizeof(char*));
}
entry->Resolution[nres-1]=
(char *)malloc(strlen(fields[0])+strlen(fields[1])+10);
sprintf(entry->Resolution[nres-1],
"%sx%s", fields[0],fields[1]);
if (fields[2])
entry->ResDescr[nres-1]=strdup(fields[2]);
else
entry->ResDescr[nres-1]=NULL;
} else
break;
}
if (!strncmp(line, "BitsPerPixel:", 13)) {
tmpstr=getfield(line);
nfield = parsefields(tmpstr, fields);
free(tmpstr);
if (nfield == 2) {
nbpp++;
if (nbpp >= nbpp_alloc) {
nbpp_alloc += 10;
entry->BitsPerPixel=
(char **)realloc(entry->BitsPerPixel,
nbpp_alloc*sizeof(char*));
entry->BppDescr=
(char **)realloc(entry->BppDescr,
nbpp_alloc*sizeof(char*));
}
entry->BitsPerPixel[nbpp-1]=strdup(fields[0]);
if (fields[1])
entry->BppDescr[nbpp-1]=strdup(fields[1]);
else
entry->BppDescr[nbpp-1]=NULL;
} else
break;
}
free(line);
}
entry->NumRes = nres;
entry->NumBpp = nbpp;
} else {
free(line);
}
}
fclose(dbfile);
qsort(thedb, numdb, sizeof(*thedb), dbCompare);
return 0;
}
/* used by below routines - assumes everything is malloc'd */
/* updates old to new if new is non-NULL */
/* frees the old value and points it at the new */
/* if new is NULL, means it wasnt updated and old remains unchanged */
static void update_changed( void *new, void **old ) {
if (new) {
if (*old)
free(*old);
*old = new;
}
}
/* display summary line given by char * arg */
void show_printer_about( char *about ) {
newtComponent infoform, infook, infobox, answer;
newtCenteredWindow(56, 15, "Printer Info");
infoform = newtForm(NULL, NULL, 0);
infobox=newtTextbox(3, 2, 50, 8,
NEWT_TEXTBOX_WRAP|NEWT_TEXTBOX_SCROLL);
newtTextboxSetText( infobox, about );
infook = newtButton( 23, 11, "Ok");
newtFormAddComponents(infoform, infobox, infook, NULL);
answer = newtRunForm( infoform );
newtPopWindow();
newtFormDestroy(infoform);
}
/* select the printer type you have */
/* return < 0 if user aborted */
/* returns index into thedb[] of the selected entry otherwise*/
static int select_printer_type( PCEntry *changes) {
newtComponent ok, cancel, form, listbox, answer;
struct newtExitStruct event;
long i, sel;
int formdone;
char *origtype;
if (changes->db && changes->db->Descr) {
origtype = alloca(strlen(changes->db->Descr)+2);
strcpy(origtype, changes->db->Descr);
} else
origtype = NULL;
newtCenteredWindow(60, 18, "Configure Printer");
newtPushHelpLine("<F1> will give you information on a particular "
"printer type");
form = newtForm(NULL, NULL, 0);
newtFormAddComponent(form, newtLabel(3, 1, "What type of printer "
"do you have?"));
listbox = newtListbox(6, 3, 10, NEWT_FLAG_RETURNEXIT);
for (i = 0; i < numdb; i++) {
newtListboxAddEntry(listbox, thedb[i]->Descr, (void *)i);
if (changes->db && changes->db->Entry &&
!strcmp(changes->db->Entry,thedb[i]->Entry)) {
newtListboxSetCurrent(listbox, i);
}
}
/* if no selection yet, default to PostScript if it exists */
if (changes->db==NULL || changes->db->Entry==NULL ) {
/* set this just in case we find nothing that matches */
newtListboxSetCurrent(listbox, 0);
for (i = 0; i < numdb; i++)
if (!strcmp(thedb[i]->Descr,"PostScript printer")) {
newtListboxSetCurrent(listbox, i);
break;
}
}
ok = newtButton( 15, 14, NEXT_LABEL);
cancel = newtButton( 31, 14, PREV_LABEL);
newtFormAddComponents( form, listbox, ok, cancel, NULL);
newtFormAddHotKey(form, NEWT_KEY_F1);
formdone = 0;
answer = NULL;
while (!formdone) {
newtFormRun(form, &event);
if (event.reason == NEWT_EXIT_HOTKEY) {
if (event.u.key == NEWT_KEY_F12)
formdone = 1;
else if (event.u.key == NEWT_KEY_F1) {
show_printer_about(
thedb[(long)newtListboxGetCurrent(listbox)]->About);
}
} else if (event.reason == NEWT_EXIT_COMPONENT) {
formdone = 1;
if (event.u.co == cancel)
answer = cancel;
}
}
sel = (long) newtListboxGetCurrent(listbox);
newtPopWindow();
newtPopHelpLine();
newtFormDestroy(form);
if ( answer == cancel )
return -1;
/* store new values */
changes->db = thedb[sel];
/* MAJOR HACK */
/* if the printer is an HP, lets do stairstep correction */
if (!strncmp(changes->db->Descr,"HP",2)) {
if (changes->CRLF)
free(changes->CRLF);
changes->CRLF=strdup("YES");
} else {
if (origtype) {
if (strcmp(origtype, changes->db->Descr)) {
if (changes->CRLF)
free(changes->CRLF);
changes->CRLF=strdup("NO");
}
} else {
if (changes->CRLF)
free(changes->CRLF);
changes->CRLF=strdup("NO");
}
}
return sel;
}
/* select the paper size and printer resolution you want */
/* return < 0 if user aborted */
/* returns 0 otherwise */
static int select_paper_size_and_res( PCEntry *changes ) {
newtComponent ok, cancel, form, text, papersz, res, answer, crlf;
struct newtExitStruct event;
long i;
int j;
int formdone;
int xpos;
int maxlen;
char **reslines;
char crlfret;
/* there has to be a current selection for this to work! */
if (changes->db == NULL)
return -1;
newtCenteredWindow(54, 18, changes->db->Descr);
newtPushHelpLine("<F1> will give you information on this "
"printer driver.");
form = newtForm(NULL, NULL, 0);
text = newtTextbox(1, 1, 52, 2, NEWT_TEXTBOX_WRAP);
newtTextboxSetText(text,
"You may now configure the paper size and resolution "
"for this printer.");
newtFormAddComponent(form, text);
/* Paper size listbox */
newtFormAddComponent(form, newtLabel(7, 4, "Paper Size"));
papersz = newtListbox( 8, 5, 5, NEWT_FLAG_NOSCROLL );
for (i=0; i < NUM_PAPERSIZES; i++) {
newtListboxAddEntry( papersz, PaperSizes[i], (void *)i );
if (changes->PaperSize &&
!strcmp(changes->PaperSize, PaperSizes[i]))
newtListboxSetCurrent(papersz, i);
}
/* make sure something is picked */
if (changes->PaperSize==NULL)
newtListboxSetCurrent(papersz, 0);
/* Resolution */
if ( changes->db->NumRes > 0) {
maxlen = 0;
reslines = (char **) alloca( changes->db->NumRes * sizeof(char *));
for (i=0; i < changes->db->NumRes; i++) {
if (changes->db->ResDescr && changes->db->ResDescr[i]) {
reslines[i]=alloca(strlen(changes->db->Resolution[i])+
strlen(changes->db->ResDescr[i])+15);
/* we want the 'x' in the 5th column */
xpos = (strchr(changes->db->Resolution[i],'x')-
changes->db->Resolution[i]);
for (j=0; j<5-xpos; j++)
reslines[i][j]=' ';
reslines[i][j]='\000';
strcat(reslines[i],changes->db->Resolution[i]);
/* pad to 13 spaces */
for (j=strlen(reslines[i]); j < 13; j++)
strcat(reslines[i], " ");
strcat(reslines[i],changes->db->ResDescr[i]);
} else {
reslines[i]=alloca(strlen(changes->db->Resolution[i])+2);
strcat(reslines[i],changes->db->Resolution[i]);
}
if (strlen(reslines[i]) > maxlen)
maxlen = strlen(reslines[i]);
}
newtFormAddComponent(form, newtLabel(34, 4, "Resolution"));
res = newtListbox( 37-maxlen/2, 5, 5, 0 );
for (i=0; i < changes->db->NumRes; i++) {
newtListboxAddEntry( res, reslines[i], (void *)i );
if (changes->Resolution &&
!strcmp(changes->Resolution, changes->db->Resolution[i]))
newtListboxSetCurrent(res, i);
}
} else {
newtFormAddComponent(form, newtLabel(34, 4, "Resolution"));
res = newtListbox( 32, 5, 4, 0 );
newtListboxAddEntry( res, "Default", (void *)0 );
newtListboxSetCurrent(res, 0);
reslines=NULL;
}
/* make sure something is picked */
if (changes->Resolution==NULL)
newtListboxSetCurrent(res, 0);
/* add stair-step correction toggle */
if (!strcmp("YES", changes->CRLF))
crlf = newtCheckbox(11, 11, "Fix stair-stepping of text?", '*', NULL,&crlfret);
else
crlf = newtCheckbox(11, 11, "Fix stair-stepping of text?", ' ', NULL,&crlfret);
ok = newtButton( 11, 13, NEXT_LABEL);
cancel = newtButton( 31, 13, PREV_LABEL);
newtFormAddComponents(form,papersz,res,crlf,ok,cancel,NULL);
newtFormAddHotKey(form, NEWT_KEY_F1);
formdone = 0;
answer = NULL;
while (!formdone) {
newtFormRun(form, &event);
if (event.reason == NEWT_EXIT_HOTKEY) {
if (event.u.key == NEWT_KEY_F12)
formdone = 1;
else if (event.u.key == NEWT_KEY_F1) {
show_printer_about( changes->db->About );
}
} else if (event.reason == NEWT_EXIT_COMPONENT) {
formdone = 1;
if (event.u.co == cancel)
answer = cancel;
}
}
if ( answer == cancel ) {
newtPopHelpLine();
newtPopWindow();
newtFormDestroy(form);
return -1;
}
i = (long) newtListboxGetCurrent(papersz);
free(changes->PaperSize);
changes->PaperSize=strdup(PaperSizes[i]);
free(changes->Resolution);
if (changes->db->NumRes > 0) {
i = (long) newtListboxGetCurrent(res);
changes->Resolution=strdup(changes->db->Resolution[i]);
} else
changes->Resolution=strdup("Default");
if (changes->CRLF)
free(changes->CRLF);
if (crlfret == ' ')
changes->CRLF=strdup("NO");
else
changes->CRLF=strdup("YES");
newtPopHelpLine();
newtPopWindow();
newtFormDestroy(form);
return 0;
}
/* pick the color depth, returns < 0 on cancel, 0 otherwise */
static int select_color_depth( PCEntry *changes ) {
newtComponent ok, cancel, form, bpp, answer, text;
struct newtExitStruct event;
long i;
int formdone, maxlen;
char **bpplines;
/* have to have a selection to work */
if (changes->db == NULL)
return -1;
/* if only one color depth choice, do nothing */
if ( changes->db->NumBpp == 0) {
changes->BitsPerPixel=strdup("Default");
return 0;
}
newtCenteredWindow(60, 15, "Configure Color Depth");
newtPushHelpLine("<F1> will give you information on this printer driver.");
form = newtForm(NULL, NULL, 0);
text = newtTextbox(1, 1, 58, 2, NEWT_TEXTBOX_WRAP);
newtTextboxSetText(text,
"You may now configure the color options "
"for this printer.");
newtFormAddComponent(form, text);
newtFormAddComponent(form, newtLabel(22, 3, "Bits Per Pixel"));
if ( changes->db->NumBpp > 0) {
maxlen = 0;
bpplines = (char **) alloca(changes->db->NumBpp*sizeof(char *));
for (i=0; i < changes->db->NumBpp; i++) {
if (changes->db->BppDescr && changes->db->BppDescr[i]) {
bpplines[i]=alloca(strlen(changes->db->BitsPerPixel[i])+
strlen(changes->db->BppDescr[i])+15);
bpplines[i][0]='\000';
strcat(bpplines[i],changes->db->BitsPerPixel[i]);
if (bpplines[i][1] == '\000') {
bpplines[i][1] = bpplines[i][0];
bpplines[i][0] = ' ';
bpplines[i][2] = '\000';
}
strcat(bpplines[i]," ");
strcat(bpplines[i],changes->db->BppDescr[i]);
} else {
bpplines[i]=alloca(strlen(changes->db->BitsPerPixel[i])+2);
strcpy(bpplines[i], changes->db->BitsPerPixel[i]);
}
/* limit the length of the line */
if (strlen(bpplines[i]) > 54)
bpplines[i][50] = '\000';
if (strlen(bpplines[i]) > maxlen)
maxlen = strlen(bpplines[i]);
}
bpp = newtListbox( 29-maxlen/2, 4, 5, NEWT_FLAG_RETURNEXIT );
for (i=0; i < changes->db->NumBpp; i++) {
newtListboxAddEntry(bpp,bpplines[i], (void *)i );
if (changes->BitsPerPixel &&
!strcmp(changes->BitsPerPixel,changes->db->BitsPerPixel[i]))
newtListboxSetCurrent(bpp, i);
}
} else {
fprintf(stderr, "How did we get here, numbpp = 0!\n");
return -1;
#if 0
bpp = newtListbox( 29-strlen("Default")/2, 5, 4,NEWT_FLAG_RETURNEXIT );
newtListboxAddEntry( bpp, "Default", (void *)0 );
newtListboxSetCurrent(bpp, 0);
bpplines=NULL;
#endif
}
/* make sure something is set */
if (changes->BitsPerPixel==NULL)
newtListboxSetCurrent(bpp,0);
ok = newtButton( 11, 10, NEXT_LABEL);
cancel = newtButton( 36, 10, PREV_LABEL);
newtFormAddComponents(form,bpp,ok,cancel,NULL);
newtFormAddHotKey(form, NEWT_KEY_F1);
formdone = 0;
answer = NULL;
while (!formdone) {
newtFormRun(form, &event);
if (event.reason == NEWT_EXIT_HOTKEY) {
if (event.u.key == NEWT_KEY_F12)
formdone = 1;
else if (event.u.key == NEWT_KEY_F1) {
show_printer_about( changes->db->About );
}
} else if (event.reason == NEWT_EXIT_COMPONENT) {
formdone = 1;
if (event.u.co == cancel)
answer = cancel;
}
}
if ( answer == cancel ) {
newtPopHelpLine();
newtPopWindow();
newtFormDestroy(form);
return -1;
}
free(changes->BitsPerPixel);
if (changes->db->NumBpp > 0) {
i = (long) newtListboxGetCurrent(bpp);
changes->BitsPerPixel=strdup(changes->db->BitsPerPixel[i]);
} else {
fprintf(stderr, "How did we get here, numbpp = 0!\n");
return -1;
#if 0
changes->BitsPerPixel=strdup("Default");
#endif
}
newtPopHelpLine();
newtPopWindow();
newtFormDestroy(form);
return 0;
}
/* returns the full attribute of the selected printer filter */
/* returns < 0 if user cancelled selected */
static int select_filter( PCEntry *changes ) {
int done;
int stage;
int abort;
done = 0;
stage = 1;
abort = 0;
while (!done) {
switch (stage) {
/* select printer model/driver */
case 1:
if (select_printer_type(changes) < 0) {
done = 1;
abort = 1;
break;
} else
stage++;
break;
/* select paper size and resolution */
case 2:
if (select_paper_size_and_res( changes ) < 0) {
stage--;
break;
} else
stage++;
break;
/* select color depth */
case 3:
if (select_color_depth( changes ) < 0) {
stage--;
break;
} else
stage++;
break;
/* we made it and we're done */
case 4:
done = 1;
}
}
if (abort)
return -1;
return 0;
}
/* return < 0 for user cancel */
static int get_local_info( PCEntry *changes ) {
newtComponent answer, cancel, form, ok, device, text;
char *device_result;
char *devname;
int detected[3];
int i, result;
int npos;
#if defined(__i386__) && !defined(TESTING)
if (loadModule("lp", DRIVER_OTHER, DRIVER_MINOR_NONE, NULL))
return INST_ERROR;
#endif
#if 0
/* old way Erik did this */
devMakeInode("lp0", "/tmp/lp0");
devMakeInode("lp1", "/tmp/lp1");
devMakeInode("lp2", "/tmp/lp2");
/* do auto-detect of lp ports */
detected[0] = ((result=open("/tmp/lp0", O_WRONLY|O_NONBLOCK)) != -1);
if (result >= 0) close(result);
detected[1] = ((result=open("/tmp/lp1", O_WRONLY|O_NONBLOCK)) != -1);
if (result >= 0) close(result);
detected[2] = ((result=open("/tmp/lp2", O_WRONLY|O_NONBLOCK)) != -1);
if (result >= 0) close(result);
unlink("/tmp/lp0");
unlink("/tmp/lp1");
unlink("/tmp/lp2");
#else
/* different approach */
/* do auto-detect of lp ports */
devname=alloca(strlen(root_path)+strlen("/dev/lpX")+2);
strcpy(devname,root_path);
strcat(devname,"/dev/lpX");
npos=strlen(devname)-1;
devname[npos]='0';
detected[0] = ((result=open(devname, O_WRONLY|O_NONBLOCK)) != -1);
if (result >= 0) close(result);
devname[npos]='1';
detected[1] = ((result=open(devname, O_WRONLY|O_NONBLOCK)) != -1);
if (result >= 0) close(result);
devname[npos]='2';
detected[2] = ((result=open(devname, O_WRONLY|O_NONBLOCK)) != -1);
if (result >= 0) close(result);
#endif
#if defined(__i386__) && !defined(TESTING)
removeModule("lp");
#endif
newtCenteredWindow(44, 16, "Local Printer Device");
form = newtForm(NULL, NULL, 0);
text = newtTextbox(1, 1, 40, 3, NEWT_TEXTBOX_WRAP);
newtTextboxSetText(text,
"What device is your printer connected to (note that /dev/lp0 is "
"equivalent to LPT1:)?");
newtFormAddComponent(form, text);
newtFormAddComponent(form, newtLabel(3, 7, "Auto-detected ports:"));
newtFormAddComponent(form, newtLabel(6, 8, "/dev/lp0:"));
newtFormAddComponent(form, newtLabel(6, 9, "/dev/lp1:"));
newtFormAddComponent(form, newtLabel(6, 10, "/dev/lp2:"));
for (i=0; i<3; i++) {
if (detected[i])
newtFormAddComponent(form, newtLabel(18,8+i, "Detected"));
else
newtFormAddComponent(form, newtLabel(18,8+i, "Not Detected"));
}
newtFormAddComponent(form, newtLabel(3, 5, "Printer Device:"));
if (changes->Device)
device=newtEntry(19, 5, changes->Device, 15, &device_result,
NEWT_FLAG_RETURNEXIT);
else
device=newtEntry(19, 5, "/dev/lp1", 15, &device_result,
NEWT_FLAG_RETURNEXIT);
ok = newtButton( 7, 12, NEXT_LABEL);
cancel = newtButton( 24, 12, PREV_LABEL);
newtFormAddComponents( form, device, ok, cancel, NULL);
answer = newtRunForm(form);
if ( answer != cancel ) {
free(changes->Device);
changes->Device = strdup(device_result);
result = 0;
} else
result = -1;
newtPopWindow();
newtFormDestroy(form);
return result;
}
/* return < 0 for user cancel */
static int get_remote_info( PCEntry *changes ) {
newtComponent answer, cancel, form, ok, rhost, rqueue, text;
char *queue_result;
char *host_result;
int result;
newtCenteredWindow(42, 14, "Remote lpd Printer Options");
form = newtForm(NULL, NULL, 0);
text = newtTextbox(1, 1, 40, 5, NEWT_TEXTBOX_WRAP);
newtTextboxSetText(text,
"To use a remote lpd print queue, you need to supply the "
"hostname of the printer server and the queue name on that "
"server which jobs should be placed in.");
newtFormAddComponent(form, text);
newtFormAddComponent(form, newtLabel(2, 7, "Remote hostname:"));
newtFormAddComponent(form, newtLabel(2, 8, "Remote queue:"));
if (changes->RemoteHost)
rhost =newtEntry(19, 7, changes->RemoteHost, 20, &host_result, 0);
else
rhost =newtEntry(19, 7, "", 20, &host_result, 0);
if (changes->RemoteQueue)
rqueue =newtEntry(19, 8, changes->RemoteQueue, 20, &queue_result, 0);
else
rqueue =newtEntry(19, 8, "lp", 20, &queue_result, 0);
ok = newtButton( 7, 10, NEXT_LABEL);
cancel = newtButton( 24, 10, PREV_LABEL);
newtFormAddComponents( form, rhost, rqueue, ok, cancel, NULL);
answer = newtRunForm(form);
if ( answer != cancel ) {
free(changes->RemoteHost);
changes->RemoteHost = strdup(host_result);
free(changes->RemoteQueue);
changes->RemoteQueue = strdup(queue_result);
result = 0;
} else
result = -1;
newtPopWindow();
newtFormDestroy(form);
return result;
}
/* return < 0 for user cancel */
static int get_smb_info( PCEntry *changes ) {
newtComponent answer, cancel, form, ok, text;
newtComponent host, hostip, share, user, passwd;
int result;
char *host_result;
char *hostip_result;
char *share_result;
char *user_result;
char *passwd_result;
newtCenteredWindow(60, 18, "LAN Manager Printer Options");
form = newtForm(NULL, NULL, 0);
text = newtTextbox(1, 1, 58, 6, NEWT_TEXTBOX_WRAP);
newtTextboxSetText(text,
"To print to a LAN manager printer, you need to provide the "
"LAN manager host name (this is not always the same as the machines "
"TCP/IP hostname) and possibly the IP address of the print server, as "
"well as the share name for the printer you wish to access and any "
"applicable user name and password.");
newtFormAddComponent(form, text);
newtFormAddComponent(form, newtLabel(10, 8, "LAN Manager Host:"));
newtFormAddComponent(form, newtLabel(10, 9, "LAN Manager IP:"));
newtFormAddComponent(form, newtLabel(10, 10, "Share Name:"));
newtFormAddComponent(form, newtLabel(10, 11, "Username:"));
newtFormAddComponent(form, newtLabel(10, 12, "Password:"));
if (changes->SMBHost)
host = newtEntry(28, 8, changes->SMBHost, 15, &host_result, 0);
else
host = newtEntry(28, 8, "", 15, &host_result, 0);
if (changes->SMBHostIP)
hostip = newtEntry(28, 9, changes->SMBHostIP, 15, &hostip_result, 0);
else
hostip = newtEntry(28, 9, "", 15, &hostip_result, 0);
if (changes->SMBShare)
share = newtEntry(28, 10, changes->SMBShare, 15, &share_result, 0);
else
share = newtEntry(28, 10, "", 15, &share_result, 0);
if (changes->SMBUser)
user = newtEntry(28, 11, changes->SMBUser, 15, &user_result, 0);
else
user = newtEntry(28, 11, "", 15, &user_result, 0);
if (changes->SMBPasswd)
passwd = newtEntry(28, 12, changes->SMBPasswd, 15,
&passwd_result, NEWT_ENTRY_HIDDEN);
else
passwd = newtEntry(28, 12, "", 15, &passwd_result, NEWT_ENTRY_HIDDEN);
ok = newtButton( 15, 14, NEXT_LABEL);
cancel = newtButton( 35, 14, PREV_LABEL);
newtFormAddComponents( form, host, hostip,
share, user, passwd, ok, cancel, NULL);
answer = newtRunForm(form);
if ( answer != cancel ) {
free(changes->SMBHost);
changes->SMBHost = strdup(host_result);
free(changes->SMBHostIP);
changes->SMBHostIP = strdup(hostip_result);
free(changes->SMBShare);
changes->SMBShare = strdup(share_result);
free(changes->SMBUser);
changes->SMBUser = strdup(user_result);
free(changes->SMBPasswd);
changes->SMBPasswd = strdup(passwd_result);
result = 0;
} else
result = -1;
newtPopWindow();
newtFormDestroy(form);
return result;
}
/* return < 0 for user cancel */
static int get_std_info( PCEntry *changes ) {
newtComponent answer, cancel, form, ok, queue, spool, text;
char *queue_result;
char *spool_result;
int result;
newtCenteredWindow(52, 14, "Standard Printer Options");
form = newtForm(NULL, NULL, 0);
text = newtTextbox(1, 1, 50, 5, NEWT_TEXTBOX_WRAP);
newtTextboxSetText(text,
"Every print queue (which print jobs are directed to) needs a "
"name (often lp) and a spool directory associated with it. What "
"name and directory should be used for this queue? ");
newtFormAddComponent(form, newtLabel(2, 7, "Name of queue:"));
newtFormAddComponent(form, newtLabel(2, 8, "Spool directory:"));
if (changes->Queue)
queue =newtEntry(20, 7, changes->Queue, 30, &queue_result, 0);
else
queue =newtEntry(20, 7, "lp", 30, &queue_result, 0);
if (changes->SpoolDir)
spool =newtEntry(20, 8, changes->SpoolDir, 30, &spool_result, 0);
else
spool =newtEntry(20, 8, "/var/spool/lpd/lp", 30, &spool_result, 0);
ok = newtButton( 11, 10, NEXT_LABEL);
cancel = newtButton( 27, 10, PREV_LABEL);
newtFormAddComponents(form, text, queue, spool, ok, cancel, NULL);
answer = newtRunForm(form);
if ( answer != cancel ) {
free(changes->Queue);
changes->Queue = strdup(queue_result);
free(changes->SpoolDir);
changes->SpoolDir = strdup(spool_result);
result = 0;
} else {
result = -1;
}
newtPopWindow();
newtFormDestroy(form);
return result;
}
static int query_config(void) {
int result;
result = newtWinChoice("Configure Printer", "Yes", "No",
"Would you like to configure a printer?");
if (result == 1)
return -1;
return 0;
}
static int query_add_more() {
int result;
result = newtWinChoice("Add Printer", "Yes", "No",
"Would you like to add another printer?");
if (result == 1)
return -1;
return 0;
}
/* returns 1 if they want to quit, 0 otherwise */
static int you_are_sure(void) {
int result;
result = newtWinChoice("Confirm Termination", "Exit", "Continue",
"If you choose 'Exit', you will return to the main "
"installation without a printer being configured.\n\n"
"Choose 'Continue' to return to configuring "
"your printer.");
if (result == 1) return 0;
return 1;
}
/* returns < 0 for user cancel, otherwise uses #defines in printercfg.h */
static int get_prn_connx( char *Type ) {
newtComponent answer, cancel, form, ok, listbox;
int sel;
newtCenteredWindow(33, 12, "Select Printer Connection");
form = newtForm(NULL, NULL, 0);
newtFormAddComponent(form,
newtLabel(1, 1, "How is this printer connected?"));
listbox = newtListbox(9, 3, 0, NEWT_FLAG_NOSCROLL | NEWT_FLAG_RETURNEXIT);
newtListboxAddEntry(listbox, "Local", (void *)LOCAL_CONNX);
newtListboxAddEntry(listbox, "Remote lpd", (void *)REMOTE_LPD_CONNX);
newtListboxAddEntry(listbox, "LAN Manager", (void *)SMB_CONNX);
if (Type)
if (!strcmp(Type,"LOCAL"))
newtListboxSetCurrent(listbox, 0);
else if (!strcmp(Type,"REMOTE"))
newtListboxSetCurrent(listbox, 1);
else if (!strcmp(Type,"SMB"))
newtListboxSetCurrent(listbox, 2);
ok = newtButton( 4, 7, NEXT_LABEL);
cancel = newtButton( 17, 7, "Cancel");
newtFormAddComponents(form, listbox, ok, cancel, NULL);
answer = newtRunForm(form);
if ( answer == cancel ) {
newtPopWindow();
newtFormDestroy(form);
return -1;
} else {
sel = (long) newtListboxGetCurrent(listbox);
newtPopWindow();
newtFormDestroy(form);
return sel;
}
}
/* edit the PrintCap Entry pcentry */
/* return < 0 if user aborts or error occurs */
static int edit_pcentry( PCEntry **pcentry ) {
int result;
int stage;
int done;
int abort;
PCEntry *changes;
/* copy current into temporary */
changes = dup_PCEntry( *pcentry );
done = 0;
abort = 0;
stage = 0;
while (!done) {
switch (stage) {
case 0:
switch (get_prn_connx(changes->Type)) {
case -1:
if (you_are_sure()) {
done = 1;
abort = 1;
}
break;
case LOCAL_CONNX:
free(changes->Type);
changes->Type = strdup("LOCAL");
stage++;
break;
case REMOTE_LPD_CONNX:
free(changes->Type);
changes->Type = strdup("REMOTE");
stage++;
break;
case SMB_CONNX:
free(changes->Type);
changes->Type = strdup("SMB");
stage++;
break;
default:
break;
}
break;
case 1:
result=get_std_info(changes);
if (result < 0)
stage--;
else
stage++;
break;
case 2:
if (!strcmp(changes->Type, "SMB"))
result=get_smb_info(changes);
else if (!strcmp(changes->Type, "REMOTE"))
result=get_remote_info(changes);
else if (!strcmp(changes->Type, "LOCAL"))
result=get_local_info(changes);
else
return -1;
if (result < 0)
stage--;
else
stage++;
break;
case 3:
result=select_filter(changes);
if (result < 0)
stage--;
else
stage++;
break;
case 4:
done = 1;
break;
}
}
if (!abort) {
free_PCEntry(*pcentry);
*pcentry = changes;
return 0;
} else {
free_PCEntry(changes);
return -1;
}
}
/* returns 0 on success, -1 on abort, and -2 if user wishes to re-edit */
static int verify_pcentry( PCEntry *pcentry ) {
newtComponent form, ok, edit, cancel, answer;
char tmpstr[256];
int row;
int done;
int result;
newtCenteredWindow(60, 18, "Verify Printer Configuration");
form = newtForm(NULL, NULL, 0);
newtFormAddComponent(form, newtLabel(3, 1,
"Please verify that this printer information is correct:"));
row=3;
sprintf(tmpstr, "Printer Type : %s\n",pcentry->Type);
newtFormAddComponent(form, newtLabel(5, row++, tmpstr));
sprintf(tmpstr, "Queue : %s\n",pcentry->Queue);
newtFormAddComponent(form, newtLabel(5, row++, tmpstr));
sprintf(tmpstr, "Spool directory : %s\n",pcentry->SpoolDir);
newtFormAddComponent(form, newtLabel(5, row++, tmpstr));
if (!strcmp(pcentry->Type, "LOCAL")) {
sprintf(tmpstr, "Printer device : %s\n",pcentry->Device);
newtFormAddComponent(form, newtLabel(5, row++, tmpstr));
} else if (!strcmp(pcentry->Type, "REMOTE")) {
sprintf(tmpstr, "Remote Host : %s\n",pcentry->RemoteHost);
newtFormAddComponent(form, newtLabel(5, row++, tmpstr));
sprintf(tmpstr, "Remote Queue : %s\n",pcentry->RemoteQueue);
newtFormAddComponent(form, newtLabel(5, row++, tmpstr));
} else if (!strcmp(pcentry->Type, "SMB")) {
if (pcentry->SMBHostIP && pcentry->SMBHostIP[0])
sprintf(tmpstr, "Server : %s [%s]\n",
pcentry->SMBHost, pcentry->SMBHostIP);
else
sprintf(tmpstr, "Server : %s\n",pcentry->SMBHost);
newtFormAddComponent(form, newtLabel(5, row++, tmpstr));
sprintf(tmpstr, "Share : %s\n",pcentry->SMBShare);
newtFormAddComponent(form, newtLabel(5, row++, tmpstr));
sprintf(tmpstr, "User : %s <Password hidden>\n",
pcentry->SMBUser);
newtFormAddComponent(form, newtLabel(5, row++, tmpstr));
}
sprintf(tmpstr, "Printer Driver : %s\n",pcentry->db->Descr);
newtFormAddComponent(form, newtLabel(5, row++, tmpstr));
sprintf(tmpstr, "Paper Size : %s\n",pcentry->PaperSize);
newtFormAddComponent(form, newtLabel(5, row++, tmpstr));
sprintf(tmpstr, "Resolution : %s\n",pcentry->Resolution);
newtFormAddComponent(form, newtLabel(5, row++, tmpstr));
sprintf(tmpstr, "Bits Per Pixel : %s\n",pcentry->BitsPerPixel);
newtFormAddComponent(form, newtLabel(5, row++, tmpstr));
ok = newtButton( 11, 14, "Done");
edit = newtButton( 26, 14, "Edit");
cancel = newtButton( 41, 14, "Cancel");
newtFormAddComponents( form, ok, edit, cancel, NULL);
done = 0;
result = 0;
while (!done) {
answer = newtRunForm(form);
if ( answer == cancel ) {
if (you_are_sure()) {
done = 1;
result = -1;
}
} else if (answer == edit) {
done = 1;
result = -2;
} else {
done = 1;
result = 0;
}
}
newtPopWindow();
newtFormDestroy(form);
return result;
}
/* given the path queue_path, we create all the required spool directory */
static int create_spool_dir( char *queue_path ) {
int result, done;
int oldmask;
struct group *grent;
gid_t lpgid = 0;
FILE *groupfile;
char groupfilename[80];
oldmask=umask(0);
result=mkdir(queue_path, 0755);
if ( result < 0)
if (errno != EEXIST)
return -1;
umask(oldmask);
strcpy(groupfilename, root_path);
strcat(groupfilename, "/etc/group");
if ((groupfile=fopen(groupfilename, "r"))==NULL)
return -1;
done=0;
while (!done) {
grent=fgetgrent(groupfile);
if (grent==NULL)
return -1;
if (!strcmp(grent->gr_name, "lp")) {
lpgid=grent->gr_gid;
done |= 2;
}
}
fclose(groupfile);
if (!done)
return -1;
result=chown(queue_path, 0, lpgid );
if ( result < 0)
return -1;
return 0;
}
/* given the input spec file 'input', and the target output file 'output' */
/* we set the fields specified by fieldname to the values in fieldval */
/* nval is the number of fields to set */
/* Doesnt currently catch error exec'ing sed yet */
static int create_config_file( char *input, char *output,
char **fieldname, char **fieldval,
int nval ) {
int status;
int infd, outfd;
int childpid;
int i, j;
int oldmask;
char **sedargs;
char *sedcmd;
oldmask = umask(0);
outfd=creat(output, 0755 );
umask(oldmask);
if (outfd == -1)
return -1;
infd=open(input, O_RDONLY);
if (infd == -1)
return -1;
/* we have to setup the args to sed */
/* need the name to exec, plus 2 args per field, plus NULL at end */
sedargs = (char **) malloc( (nval + 2) * sizeof( char * ) );
if (!sedargs)
return -1;
sedargs[0] = "/bin/sed";
sedargs[nval+1] = NULL;
for (i=0; i<nval; i++) {
sedargs[i+1] = (char *) malloc(25 + strlen(fieldname[i]) +
strlen(fieldval[i]));
/* if we get an error, try to cleanup */
if (!sedargs[i+1]) {
for (j=0; j<i; j++)
if (sedargs[j+1])
free(sedargs[j+1]);
if (sedargs)
free(sedargs);
return -1;
}
sprintf(sedargs[i+1], "-e s/@@@%s@@@/%s/g", fieldname[i], fieldval[i]);
}
sedcmd = malloc(strlen(root_path)+15);
if (!sedcmd)
return -1;
strcpy(sedcmd, root_path);
strcat(sedcmd, "/bin/sed");
if (!(childpid = fork())) {
close(0);
close(1);
dup2(infd, 0);
dup2(outfd, 1);
close(infd);
close(outfd);
execv(sedcmd, sedargs);
exit(-1);
}
close(infd);
close(outfd);
waitpid(childpid, &status, 0);
if (sedcmd)
free(sedcmd);
for (i=0; i<nval; i++)
if (sedargs[i+1])
free(sedargs[i+1]);
if (sedargs)
free(sedargs);
return 0;
}
/* copy master filter to the spool dir */
static int copy_master_filter( char *queue_path ) {
int childpid, status;
char *masterfilter, *cpcmd, *dest;
masterfilter=malloc(strlen(PRINTER_FILTER_DIR)+strlen(root_path)+20);
strcpy(masterfilter,root_path);
strcat(masterfilter,PRINTER_FILTER_DIR);
strcat(masterfilter,"master-filter");
dest=malloc(strlen(queue_path)+20);
strcpy(dest,queue_path);
strcat(dest,"filter");
cpcmd = malloc(strlen(root_path)+15);
if (!cpcmd)
return -1;
strcpy(cpcmd, root_path);
strcat(cpcmd, "/bin/cp");
if (!(childpid = fork()))
execl(cpcmd, cpcmd, masterfilter, dest, NULL);
waitpid(childpid, &status, 0);
free(masterfilter);
free(cpcmd);
free(dest);
return 0;
}
/* given a PrintCap Entry, create the spool dir and special */
/* rhs-printfilters related config files which are required */
static int configure_queue( PCEntry *pcentry ) {
char *queue_path;
char *output;
char *input;
char colorstr[80]; /* holds the '-dBitsPerPixel=nn' */
char **fieldname;
char **fieldval;
int nfield;
FILE *printcap, *smbconfig;
if (testing) return 0;
if (pcentry->SpoolDir) {
/* create the spooldir and set to root.lp ownership */
queue_path=malloc(strlen(root_path)+strlen(pcentry->SpoolDir)+5);
strcpy(queue_path, root_path);
strcat(queue_path, pcentry->SpoolDir);
strcat(queue_path, "/");
if (create_spool_dir(queue_path) < 0)
return -1;
/* make the cfg files we need */
output=malloc(strlen(queue_path)+strlen("general.cfg")+2);
strcpy(output,queue_path);
strcat(output,"general.cfg");
input=malloc(strlen(root_path)+strlen(PRINTER_FILTER_DIR)+
strlen("general.cfg.in")+2);
strcpy(input,root_path);
strcat(input,PRINTER_FILTER_DIR);
strcat(input,"general.cfg.in");
/* setup the field arrays */
nfield = 4;
fieldname = (char **) malloc( nfield * sizeof(char *) );
fieldname[0] = "desiredto";
fieldname[1] = "papersize";
fieldname[2] = "printertype";
fieldname[3] = "ascps_trans";
fieldval = (char **) malloc( nfield * sizeof(char *) );
if (strcmp(pcentry->db->GSDriver, "TEXT"))
fieldval[0] = "ps";
else
fieldval[0] = "asc";
if (!pcentry->PaperSize)
fieldval[1] = "letter";
else
fieldval[1] = pcentry->PaperSize;
fieldval[2] = pcentry->Type;
if (strcmp(pcentry->db->GSDriver, "POSTSCRIPT"))
fieldval[3] = "NO";
else
fieldval[3] = "YES";
if (create_config_file(input, output, fieldname, fieldval, nfield) < 0)
return -1;
/* successfully created general.cfg, now do postscript.cfg */
free(fieldname);
free(fieldval);
free(output);
free(input);
output=malloc(strlen(queue_path)+strlen("postscript.cfg")+2);
strcpy(output,queue_path);
strcat(output,"postscript.cfg");
input=malloc(strlen(root_path)+strlen(PRINTER_FILTER_DIR)+
strlen("postscript.cfg.in")+2);
strcpy(input,root_path);
strcat(input,PRINTER_FILTER_DIR);
strcat(input,"postscript.cfg.in");
/* setup the field arrays */
nfield = 10;
fieldname = (char **) malloc( nfield * sizeof(char *) );
fieldname[0] = "gsdevice";
fieldname[1] = "papersize";
fieldname[2] = "resolution";
fieldname[3] = "color";
fieldname[4] = "reversepages";
fieldname[5] = "extragsoptions";
fieldname[6] = "pssendeof";
fieldname[7] = "nup";
fieldname[8] = "rtlftmar";
fieldname[9] = "topbotmar";
fieldval = (char **) malloc( nfield * sizeof(char *) );
/* gsdriver */
fieldval[0] = pcentry->db->GSDriver;
/* papersize */
if (!pcentry->PaperSize)
fieldval[1] = "letter";
else
fieldval[1] = pcentry->PaperSize;
/* resolution */
if (!pcentry->Resolution)
fieldval[2] = "";
else
if (strcmp(pcentry->Resolution,"Default"))
fieldval[2] = pcentry->Resolution;
else
fieldval[2] = "";
/* color depth */
if (!pcentry->BitsPerPixel)
fieldval[3] = "";
else
if (strcmp(pcentry->BitsPerPixel,"Default")) {
strcpy(colorstr,"-dBitsPerPixel=");
strcat(colorstr,pcentry->BitsPerPixel);
fieldval[3] = colorstr;
} else
fieldval[3] = "";
/* reverse pages? */
if (!pcentry->RevPages)
fieldval[4] = "";
else
fieldval[4] = pcentry->RevPages;
/* extra gs options */
fieldval[5] = "";
/* ps send eof */
if (strcmp(pcentry->db->GSDriver, "POSTSCRIPT"))
fieldval[6] = "NO";
else
fieldval[6] = "YES";
/* nup */
fieldval[7] = "1";
/* rtlftmar */
fieldval[8] = "18";
/* topbotmar */
fieldval[9] = "18";
if (create_config_file(input, output, fieldname, fieldval, nfield) < 0)
return -1;
/* finally, make textonly.cfg */
free(fieldval);
free(fieldname);
free(output);
free(input);
output=malloc(strlen(queue_path)+strlen("textonly.cfg")+2);
strcpy(output,queue_path);
strcat(output,"textonly.cfg");
input=malloc(strlen(root_path)+strlen(PRINTER_FILTER_DIR)+
strlen("textonly.cfg.in")+2);
strcpy(input,root_path);
strcat(input,PRINTER_FILTER_DIR);
strcat(input,"textonly.cfg.in");
/* setup the field arrays */
nfield = 3;
fieldname = (char **) malloc( nfield * sizeof(char *) );
fieldname[0] = "textonlyoptions";
fieldname[1] = "crlftrans";
fieldname[2] = "textsendeof";
fieldval = (char **) malloc( nfield * sizeof(char *) );
fieldval[0] = "";
if (!pcentry->CRLF)
fieldval[1] = "";
else
fieldval[1] = pcentry->CRLF;
fieldval[2] = "YES";
if (create_config_file(input, output, fieldname, fieldval, nfield) < 0)
return -1;
/* simple config file required if SMB printer */
if (!strcmp(pcentry->Type, "SMB")) {
output=malloc(strlen(queue_path)+15);
strcpy(output,queue_path);
strcat(output,".config");
smbconfig = fopen(output, "w");
fprintf(smbconfig,"share='\\\\%s\\%s'\n",
pcentry->SMBHost, pcentry->SMBShare);
fprintf(smbconfig,"hostip=%s\n",pcentry->SMBHostIP);
fprintf(smbconfig,"user=%s\n",pcentry->SMBUser);
fprintf(smbconfig,"password=%s\n",pcentry->SMBPasswd);
fclose(smbconfig);
}
/* we're done with config files - need to copy filter over now */
free(fieldval);
free(fieldname);
free(output);
free(input);
if ( copy_master_filter(queue_path) < 0 )
return -1;
} else
return -1; /* we have to have a spool dir! */
/* assume that spool dir got setup ok, now add printcap entry */
output=alloca(strlen("/etc/printcap")+strlen(root_path)+2);
strcpy(output,root_path);
strcat(output,"/etc/printcap");
if (access(output, F_OK)) {
printcap=fopen(output, "w");
if (printcap == NULL)
return -1;
fputs("#\n", printcap);
fputs("# Please don't edit this file directly unless you know what "
"you are doing!\n", printcap);
fputs("# Be warned that the control-panel printtool requires a very "
"strict format!\n", printcap);
fputs("# Look at the printcap(5) man page for more info.\n", printcap);
fputs("#\n", printcap);
fputs("# This file can be edited with the printtool in the "
"control-panel.\n", printcap);
fputs("\n", printcap);
fclose(printcap);
}
printcap = fopen(output, "a");
fputs("\n",printcap);
fprintf(printcap, "##PRINTTOOL3## %s %s %s %s %s %s %s %s \n",
pcentry->Type,
pcentry->db->GSDriver,
pcentry->Resolution,
pcentry->PaperSize,
"{}",
pcentry->db->Entry,
pcentry->BitsPerPixel,
"{}");
fprintf(printcap, "%s:\\\n",pcentry->Queue);
fprintf(printcap, "\t:sd=%s:\\\n",pcentry->SpoolDir);
fprintf(printcap, "\t:mx#0:\\\n\t:sh:\\\n");
if (!strcmp(pcentry->Type, "LOCAL")) {
fprintf(printcap,"\t:lp=%s:\\\n",pcentry->Device);
} else if (!strcmp(pcentry->Type, "REMOTE")) {
fprintf(printcap,"\t:rm=%s:\\\n",pcentry->RemoteHost);
fprintf(printcap,"\t:rp=%s:\\\n",pcentry->RemoteQueue);
} else if (!strcmp(pcentry->Type, "SMB")) {
fprintf(printcap,"\t:lp=/dev/null:\\\n");
fprintf(printcap,"\t:af=%s/%s\\\n",pcentry->SpoolDir,"acct");
}
/* cheating to get the input filter! */
fprintf(printcap,"\t:if=%s/%s:\n",pcentry->SpoolDir,"filter");
fclose(printcap);
return 0;
}
int doConfigurePrinters (char *theroot) {
int done, result;
PCEntry *pcentry = NULL;
/* root under which the installed system lives */
root_path = theroot;
/* read the printer database into memory -- ignore these errors as they
probably indicate missing packages */
if (read_printer_db(PRINTER_DB_FILE)) return INST_NOP;
install_return_code = 0;
done = 0;
if (!query_config()) {
pcentry = new_PCEntry();
/* setup some defaults needed for all printer types */
pcentry->AutoEOF = strdup("NO");
pcentry->CRLF = strdup("NO");
pcentry->RevPages = strdup("NO");
result = edit_pcentry( &pcentry );
while ((result != -1) && (result=verify_pcentry( pcentry ))==-2)
result = edit_pcentry( &pcentry );
if (result == -1)
free_PCEntry( pcentry );
else {
configure_queue( pcentry );
free_PCEntry( pcentry );
install_return_code=0;
}
}
return install_return_code;
}
#ifdef TESTING
int testing = 1;
int main() {
int result;
/* get the type of connection we want */
newtInit();
newtCls();
newtPushHelpLine(NULL);
newtDrawRootText(0, 0, "Printer Config - (C) 1997 Red Hat Software");
result = doConfigurePrinters( "/" );
newtFinished();
printf("The result code is %d\n",result);
return result;
}
#endif