#include <stdio.h>
#include <stdlib.h>
#include <libintl.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <syslog.h>
#include "netpr.h"
#include "netdebug.h"
static int job_primitive(np_bsdjob_t *, char, char *);
static int create_cfA_file(np_bsdjob_t *);
static char *create_cfname(np_bsdjob_t *);
static char *create_dfname(np_bsdjob_t *);
extern char data_file_type;
np_bsdjob_t *
create_bsd_job(np_job_t *injob, int pr_order, int filesize)
{
np_bsdjob_t *job;
char *id;
int x;
np_data_t *jobdata;
if ((injob->request_id == NULL) || (injob->username == NULL) ||
(injob->dest == NULL) || (injob->printer == NULL)) {
return (NULL);
}
job = (np_bsdjob_t *)malloc(sizeof (np_bsdjob_t));
ASSERT(job, MALLOC_ERR);
(void) memset(job, 0, sizeof (np_bsdjob_t));
job->np_printer = "auto";
if ((id = strrchr(injob->request_id, (int)'-')) == NULL) {
(void) fprintf(stderr,
gettext("Netpr: request_id in unknown format:<%s>\n"),
injob->request_id);
syslog(LOG_DEBUG, "request id in unknown format: %s",
injob->request_id);
return (NULL);
}
id++;
job->np_request_id = malloc(4);
ASSERT(job->np_request_id, MALLOC_ERR);
errno = 0;
x = atoi(id);
if ((errno != 0) || (x < 0)) {
x = 0;
}
(void) snprintf(job->np_request_id, (size_t)4,
"%.3d", x % 1000);
if ((id = strchr(injob->username, '@')) != NULL) {
*id++ = '\0';
job->np_username = strdup(injob->username);
job->np_host = strdup(id);
*--id = '@';
} else if ((id = strrchr(injob->username, '!')) != NULL) {
*id++ = '\0';
job->np_username = strdup(id);
job->np_host = strdup(injob->username);
*--id = '!';
} else {
syslog(LOG_DEBUG, "using localhost for user %s",
injob->username);
job->np_username = strdup(injob->username);
job->np_host = strdup("localhost");
}
job->np_printer = injob->printer;
job->np_filename = injob->filename;
job->np_df_letter = 'A';
if ((job->np_cfAfilename = create_cfname(job)) == NULL) {
(void) fprintf(stderr,
gettext("Netpr: System error creating cfAfilename\n"));
syslog(LOG_DEBUG, "System error creating cfAfilename");
return (NULL);
}
job->np_timeout = injob->timeout;
job->np_banner = injob->banner;
job->np_print_order = pr_order;
if (injob->title == NULL)
job->np_title = injob->filename;
else
job->np_title = injob->title;
if ((create_cfA_file(job)) == -1) {
(void) fprintf(stderr,
gettext("Netpr: Cannot create bsd control file\n"));
syslog(LOG_DEBUG, "Cannot create bsd control file");
return (NULL);
}
if (injob->banner == BANNER) {
(void) job_primitive(job, 'C', job->np_host);
(void) job_primitive(job, 'J', job->np_title);
(void) job_primitive(job, 'L', job->np_username);
}
jobdata = malloc(sizeof (np_data_t));
ASSERT(jobdata, MALLOC_ERR);
(void) memset(jobdata, 0, sizeof (np_data_t));
jobdata->np_path_file = malloc(strlen(job->np_filename) + 1);
ASSERT(jobdata->np_path_file, MALLOC_ERR);
(void) strcpy(jobdata->np_path_file, job->np_filename);
jobdata->np_data_size = filesize;
if ((jobdata->np_dfAfilename = create_dfname(job)) == NULL) {
return (NULL);
}
if (data_file_type != 0) {
(void) job_primitive(job, data_file_type,
jobdata->np_dfAfilename);
(void) job_primitive(job, 'U', jobdata->np_dfAfilename);
(void) job_primitive(job, 'N', "print-data");
}
syslog(LOG_DEBUG, "data file info: %s", job->np_cfAfile);
job->np_data = jobdata;
return (job);
}
static char *
create_dfname(np_bsdjob_t *job)
{
char *dfname;
if (job == NULL)
return (NULL);
if (job->np_df_letter > 'z') {
errno = ENFILE;
return (NULL);
}
dfname = (char *)malloc(strlen(job->np_host) + 3 + 3 + 1);
ASSERT(dfname, MALLOC_ERR);
(void) memset(dfname, 0, strlen(job->np_host) + 3 + 3 + 1);
(void) sprintf(dfname, "%s%c%s%s", "df", job->np_df_letter,
job->np_request_id, job->np_host);
job->np_df_letter += 1;
if ((job->np_df_letter > 'Z') && (job->np_df_letter < 'a'))
job->np_df_letter = 'a';
return (dfname);
}
static char *
create_cfname(np_bsdjob_t *job)
{
char *cfname;
if (job == NULL)
return (NULL);
cfname = (char *)malloc(strlen(job->np_host) + 3 + 3 + 1);
ASSERT(cfname, MALLOC_ERR);
(void) memset(cfname, 0, strlen(job->np_host) + 3 + 3 + 1);
(void) sprintf(cfname, "%s%s%s", "cfA",
job->np_request_id, job->np_host);
return (cfname);
}
static int
create_cfA_file(np_bsdjob_t *job)
{
if ((job->np_host == NULL) || (job->np_username == NULL)) {
(void) fprintf(stderr, gettext(
"Netpr: Missing required data, cannot build control file\n"));
return (-1);
}
(void) job_primitive(job, 'H', job->np_host);
(void) job_primitive(job, 'P', job->np_username);
return (0);
}
static int
job_primitive(np_bsdjob_t *job, char option, char *value)
{
char buf[BUFSIZ];
if ((job == NULL) || (value == NULL))
return (-1);
job->np_cfAfilesize += strlen(value) + 2;
if (job->np_cfAfile == NULL) {
job->np_cfAfile = calloc(1, job->np_cfAfilesize + 1);
ASSERT(job->np_cfAfile, MALLOC_ERR);
} else {
job->np_cfAfile = realloc(job->np_cfAfile,
job->np_cfAfilesize + 1);
ASSERT(job->np_cfAfile, REALLOC_ERR);
}
(void) snprintf(buf, sizeof (buf), "%c%s\n", option, value);
(void) strcat(job->np_cfAfile, buf);
syslog(LOG_DEBUG, "adding: %d %s", job->np_cfAfilesize, buf);
return (0);
}