#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <signal.h>
#include <setjmp.h>
#include <string.h>
#include <stdlib.h>
#include <libintl.h>
#include "lp.h"
#include "msgs.h"
#include "printers.h"
#include "requests.h"
#include "form.h"
#define WHO_AM_I I_AM_LPADMIN
#include "oam.h"
#include "lpadmin.h"
extern void mount_unmount();
extern short printer_status;
extern char *cur_pwheel,
*disable_reason,
*reject_reason;
extern FORM formbuf;
static int again();
static void disable(),
enable(),
accept(),
reject(),
cancel(),
sigpipe(),
sigother();
static jmp_buf cleanup_env,
pipe_env;
int do_align (printer, form, pwheel)
char *printer,
*form,
*pwheel;
{
short status;
char *req_id = 0,
*file_prefix,
*rfile,
*fifo,
buffer[MSGMAX];
long printer_chk;
int try;
FILE *align_fp,
*fifo_fp;
REQUEST req;
void (*old_sighup)(),
(*old_sigint)(),
(*old_sigquit)(),
(*old_sigterm)();
if (getform(form, (FORM *)0, (FALERT *)0, &align_fp) == -1) {
LP_ERRMSG2 (ERROR, E_LP_GETFORM, form, PERROR);
done (1);
}
if (!align_fp) {
LP_ERRMSG1 (WARNING, E_ADM_NOALIGN, form);
return (0);
}
req.copies = 1;
req.destination = printer;
req.form = form;
req.actions = ACT_IMMEDIATE | ACT_FAST;
req.alert = 0;
req.options = "nobanner";
req.priority = 20;
sprintf ((req.pages = "1-999999")+2, "%d", formbuf.np);
req.charset = NAME_ANY;
req.modes = 0;
req.title = "Aligning Form";
req.input_type = formbuf.conttype;
req.user = getname();
if (setjmp(cleanup_env) != 0)
done (1);
trap_signals ();
old_sighup = signal(SIGHUP, sigother);
old_sigint = signal(SIGINT, sigother);
old_sigquit = signal(SIGQUIT, sigother);
old_sigterm = signal(SIGTERM, sigother);
try = 0;
Again: try++;
BEGIN_CRITICAL
send_message (S_ALLOC_FILES, 2);
if (mrecv(buffer, MSGMAX) != R_ALLOC_FILES) {
LP_ERRMSG (ERROR, E_LP_MRECV);
done (1);
}
END_CRITICAL
(void)getmessage (buffer, R_ALLOC_FILES, &status, &file_prefix);
switch (status) {
case MOK:
break;
case MNOMEM:
LP_ERRMSG (ERROR, E_LP_MNOMEM);
done (1);
}
if (!(rfile = malloc((unsigned int)strlen(file_prefix) + 2 + 1))) {
LP_ERRMSG (ERROR, E_LP_MALLOC);
done (1);
}
sprintf (rfile, "%s-1", file_prefix);
if (!(fifo = makepath(Lp_Temp, rfile, (char *)0))) {
LP_ERRMSG (ERROR, E_LP_MALLOC);
done (1);
}
req.file_list = 0;
addlist (&req.file_list, fifo);
if (
Unlink(fifo) == -1
|| Mknod(fifo, S_IFIFO | 0600, 0) == -1
) {
LP_ERRMSG1 (ERROR, E_ADM_NFIFO, PERROR);
done (1);
}
if (try == 1) {
mount_unmount (S_MOUNT, printer, NB(form), NB(pwheel));
if (!(printer_status & PS_DISABLED))
disable (printer, CUZ_MOUNTING, 0);
if (printer_status & PS_REJECTED)
accept (printer);
if (setjmp(cleanup_env) != 0) {
if (printer_status & PS_DISABLED)
disable (printer, disable_reason, 1);
if (printer_status & PS_REJECTED)
reject (printer, reject_reason);
if (req_id && *req_id)
cancel (req_id);
done (1);
}
}
sprintf (rfile, "%s-0", file_prefix);
if (putrequest(rfile, &req) == -1) {
LP_ERRMSG1 (ERROR, E_LP_PUTREQUEST, PERROR);
goto Done;
}
BEGIN_CRITICAL
send_message (S_PRINT_REQUEST, rfile);
if (mrecv(buffer, MSGMAX) != R_PRINT_REQUEST) {
LP_ERRMSG (ERROR, E_LP_MRECV);
done (1);
}
END_CRITICAL
(void)getmessage (buffer, R_PRINT_REQUEST, &status, &req_id, &printer_chk);
switch (status) {
case MNOFILTER:
if (try == 1) {
req.pages = 0;
goto Again;
}
LP_ERRMSG (ERROR, E_ADM_NFILTER);
goto Done;
case MOK:
#if defined(WARN_OF_TOO_MANY_LINES)
if (!req.pages)
LP_ERRMSG1 (WARNING, E_ADM_NPAGES, formbuf.np);
#endif
break;
case MERRDEST:
accept (printer);
goto Again;
case MNOMEM:
LP_ERRMSG (ERROR, E_LP_MNOMEM);
goto Done;
case MNODEST:
LP_ERRMSG1 (ERROR, E_LP_PGONE, printer);
goto Done;
case MNOOPEN:
LP_ERRMSG (ERROR, E_ADM_ERRDEST);
goto Done;
case MDENYDEST:
if (printer_chk) {
char reason[1024],
*cp = reason;
if (printer_chk & PCK_TYPE)
cp += sprintf(cp, "printer type, ");
if (printer_chk & PCK_CHARSET)
cp += sprintf(cp, "character set, ");
if (printer_chk & PCK_CPI)
cp += sprintf(cp, "character pitch, ");
if (printer_chk & PCK_LPI)
cp += sprintf(cp, "line pitch, ");
if (printer_chk & PCK_WIDTH)
cp += sprintf(cp, "page width, ");
if (printer_chk & PCK_LENGTH)
cp += sprintf(cp, "page length, ");
if (printer_chk & PCK_BANNER)
cp += sprintf(cp, "nobanner, ");
cp[-2] = 0;
LP_ERRMSG1 (ERROR, E_LP_PTRCHK, reason);
goto Done;
}
case MUNKNOWN:
case MNOMEDIA:
case MDENYMEDIA:
case MNOMOUNT:
case MNOSPACE:
case MNOPERM:
LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status);
Done: if (!(printer_status & PS_DISABLED))
enable (printer);
if (printer_status & PS_REJECTED)
reject (printer, reject_reason);
done (1);
}
if (printer_status & PS_REJECTED)
reject (printer, reject_reason);
enable (printer);
if (!(fifo_fp = fopen(fifo, "w"))) {
LP_ERRMSG1 (ERROR, E_ADM_NFIFO, PERROR);
done (1);
}
if (setjmp(pipe_env) == 0) {
char * ff = 0;
char * ff_before = 0;
if (filebreak) {
if (
formbuf.conttype
&& searchlist_with_terminfo(
formbuf.conttype,
T
)
)
tidbit (formbuf.conttype, "ff", &ff);
else
tidbit (*T, "ff", &ff);
}
signal (SIGPIPE, sigpipe);
do {
register int n;
char buf[BUFSIZ];
if (ff_before && *ff_before)
fputs (ff_before, fifo_fp);
ff_before = ff;
rewind (align_fp);
while ((n = fread(buf, 1, BUFSIZ, align_fp)) > 0)
fwrite (buf, 1, n, fifo_fp);
fflush (fifo_fp);
} while (again());
fclose (align_fp);
signal (SIGPIPE, SIG_DFL);
} else {
cancel (req_id);
#define P(X) printf (X)
P("We were interrupted while printing the alignment pattern;\n");
P("check the printer. The form is mounted, so you will have to\n");
P("unmount it if you need to print more alignment patterns later.\n");
}
if (printer_status & PS_DISABLED)
disable (printer, disable_reason, 1);
fclose (fifo_fp);
signal (SIGHUP, old_sighup);
signal (SIGINT, old_sigint);
signal (SIGQUIT, old_sigquit);
signal (SIGTERM, old_sigterm);
return (1);
}
static void accept (printer)
char *printer;
{
int rc;
BEGIN_CRITICAL
send_message (S_ACCEPT_DEST, printer);
rc = output(R_ACCEPT_DEST);
END_CRITICAL
switch (rc) {
case MOK:
case MERRDEST:
break;
case MNODEST:
case MNOPERM:
default:
LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, rc);
done (1);
}
return;
}
static void reject (printer, reason)
char *printer,
*reason;
{
int rc;
BEGIN_CRITICAL
send_message (S_REJECT_DEST, printer, reason);
rc = output(R_REJECT_DEST);
END_CRITICAL
switch (rc) {
case MOK:
case MERRDEST:
break;
case MNODEST:
case MNOPERM:
default:
LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, rc);
done (1);
}
return;
}
static void enable (printer)
char *printer;
{
int rc;
BEGIN_CRITICAL
send_message (S_ENABLE_DEST, printer);
rc = output(R_ENABLE_DEST);
END_CRITICAL
switch (rc) {
case MOK:
case MERRDEST:
break;
case MNODEST:
case MNOPERM:
default:
LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, rc);
done (1);
}
return;
}
static void disable (printer, reason, when)
char *printer,
*reason;
int when;
{
int rc;
BEGIN_CRITICAL
send_message (S_DISABLE_DEST, printer, reason, when);
rc = output(R_DISABLE_DEST);
END_CRITICAL
switch (rc) {
case MOK:
case MERRDEST:
break;
case MNODEST:
case MNOPERM:
default:
LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, rc);
done (1);
}
return;
}
static void cancel (req_id)
char *req_id;
{
int rc;
BEGIN_CRITICAL
send_message (S_CANCEL_REQUEST, req_id);
rc = output(R_CANCEL_REQUEST);
END_CRITICAL
switch (rc) {
case MOK:
case MUNKNOWN:
case M2LATE:
break;
case MNOPERM:
default:
LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, rc);
done (1);
}
return;
}
static int again ()
{
char answer[BUFSIZ];
for (;;) {
printf (
gettext("Press return to print an alignment pattern [q to quit]: ")
);
if (!fgets(answer, sizeof (answer), stdin))
return (0);
answer[strlen(answer) -1] = '\0';
if (
STREQU(answer, "q")
|| STREQU(answer, "n")
|| STREQU(answer, "no")
)
return (0);
else if (
!*answer
|| STREQU(answer, "y")
|| STREQU(answer, "yes")
)
return (1);
printf (gettext("Sorry?\n"));
}
}
static void sigpipe ()
{
signal (SIGPIPE, SIG_IGN);
longjmp (pipe_env, 1);
}
static void sigother (sig)
int sig;
{
signal (sig, SIG_IGN);
longjmp (cleanup_env, 1);
}