job.c revision c1ecd8b9404ee0d96d93f02e82c441b9bb149a3d
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*LINTLIBRARY*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include <sys/systeminfo.h>
#include <syslog.h>
#include <errno.h>
#include <libintl.h>
#include <grp.h>
#include <job.h>
#include <misc.h>
#include <list.h>
#define MAX_RETRIES (5)
static char *_control_file_prefix = CONTROL_FILE_PREFIX;
static char *_xfer_file_prefix = XFER_FILE_PREFIX;
/*
* _job_unlink_data_file() will unlink the path for the jobfile passed in.
* this is only to be used with job_destroy() so it can iterate through
* the job_df_list.
*/
static int
{
else
return (-1);
}
/*
*
*/
static void
{
return;
if (file->jf_mmapped)
else
}
}
/*
*
*/
static void
{
}
/*
* job_free() frees up memory mmapped for malloced
* being used by the structure.
*/
void
{
return;
if (job->job_df_list)
if (job->job_spool_dir)
}
void
{
return;
return;
/* lose privilege temporarily */
if (name[0] == '\n')
name++;
*p;
continue;
}
continue;
}
*++p = NULL;
}
}
}
(void) seteuid(0); /* get back privilege */
(void) _job_unlink_data_file(cf);
}
static int
{
int n_cnt;
char *p, *cfp;
/* map in the control data */
"canceling %d destined for %s:%s",
return (0);
}
/* look for usr, host, & data files */
/*
* Bugid 4137904 - "File Name" can be
* anywhere in control file.
* Bugid 4179341 - "File Name" can be missing
* in control file.
* Keep a separate pointer to the control file.
* When a CF_UNLINK entry is found use the second
* pointer to search for a corresponding 'N' entry.
* The behavior is to associate the first CF_UNLINK
* entry with the first 'N' entry and so on.
* Note: n_cnt is only used to determine if we
* should test for 'N' at the beginning of
* the file.
*/
n_cnt = 0;
switch (*(++p)) {
case CF_USER:
break;
case CF_HOST:
break;
case CF_UNLINK:
file->jf_mmapped = 0;
return (0);
}
/*
* Beginning of file. Check for first
* character == 'N'
*/
cfp++;
n_cnt++;
} else {
cfp += 2;
n_cnt++;
}
}
/*
* Move cfp to end of line or
* set to NULL if end of file.
*/
}
}
break;
}
}
file->jf_mmapped = 0;
return (0);
}
return (1);
}
/*
* job_retrieve() will retrieve the disk copy of a job associated with the
* transfer file name passed in. It returns a pointer to a job structure
* or a NULL if the job was not on disk.
*/
job_t *
{
int retry_cnt = 0;
char *s;
int fd;
return (NULL);
}
return (NULL);
}
/* get job id, from binding file name */
sizeof (buf));
/* Construct data file and control file names */
sizeof (cFile));
/* remove data file and control file whenever xFile is removed */
return (NULL);
}
/*
* If failed to get a lock on the file, just return NULL. It will
* be retried later.
*/
return (NULL);
}
/*
* Retry a few times if we failed to read or read returns 0, just
* to make sure we tried hard before giving up. In practice,
* there were cases of read() returning 0. To handle that
* scenario just try a few times.
*/
break;
}
}
/*
* If failed to read after MAX_RETRIES, return NULL and remove xFile,
* and cFile.
*/
if (retry_cnt == MAX_RETRIES) {
return (NULL);
}
return (NULL);
}
return (tmp);
}
/*
* job_compar() compare 2 jobs for creation time ordering
*/
static int
{
int server;
int printer;
s2;
/*
* If there is a null value, assume the job submitted remotely.
* Jobs submitted remotely take precedence over those submitted
* from the server.
*/
return (-1);
return (1);
if (server != 0)
return (server);
if (printer != 0)
return (printer);
return (0);
}
/*
* job_list_append() reads all of the jobs associated with the printer passed
* in and appends them to the list of jobs passed in. The returned result
* is a new list of jobs containing all jobs passed in and jobs for the
* printer specified. If the printer is NULL, all jobs for all printers
* are added to the list.
*/
job_t **
{
struct dirent *d;
int i, found = 0;
/*
* 4239765 - in.lpd segfaults performing strcmp()
* in job_list_append()
*/
server = "";
}
return (NULL);
/* should use scandir */
strlen(_xfer_file_prefix)) != 0)
continue;
continue;
found = 0;
if (list) {
found = 1;
}
} /* if (list) */
if (!found)
(void *)job);
}
} /* while */
/* count the length of the list for qsort() */
if (list) {
;
(int(*)(const void *, const void *))job_compar);
}
return (list);
}
/*
*
* Shared routines for Canceling jobs.
*
*/
/*
* vjob_match_attribute() checks to see if the attribute passed in
* matches the the user or id of the job passed in via stdargs. This is
* intended for use with list_iterate().
*/
int
{
return (1);
else
return (0);
}
/*
* vjob_job() determines if the job passed in is for the printer and server
* of the cancel request, and if it is from the user requesting or the
* user is root, it checsk the attributes. If the job matches all of this
* it cancels the job and prints a message. It is intented to be called
* by list_iterate().
*/
int
{
int killed_process = 0;
int lock;
server);
if (list_iterate((void **)list,
0)) < 0) {
killed_process = 1;
}
(void) printf(
}
}
return (killed_process);
}