Home | History | Annotate | Download | only in lpsched
      1     0  stevel /*
      2     0  stevel  * CDDL HEADER START
      3     0  stevel  *
      4     0  stevel  * The contents of this file are subject to the terms of the
      5  3125  jacobs  * Common Development and Distribution License (the "License").
      6  3125  jacobs  * You may not use this file except in compliance with the License.
      7     0  stevel  *
      8     0  stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9     0  stevel  * or http://www.opensolaris.org/os/licensing.
     10     0  stevel  * See the License for the specific language governing permissions
     11     0  stevel  * and limitations under the License.
     12     0  stevel  *
     13     0  stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14     0  stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15     0  stevel  * If applicable, add the following below this CDDL HEADER, with the
     16     0  stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17     0  stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18     0  stevel  *
     19     0  stevel  * CDDL HEADER END
     20     0  stevel  */
     21     0  stevel 
     22     0  stevel /*
     23  4321  casper  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     24     0  stevel  * Use is subject to license terms.
     25     0  stevel  */
     26   547  jacobs 
     27   547  jacobs /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     28   547  jacobs /*	  All Rights Reserved  	*/
     29     0  stevel 
     30     0  stevel #pragma ident	"%Z%%M%	%I%	%E% SMI"
     31     0  stevel 
     32     0  stevel #include "lpsched.h"
     33     0  stevel #include <syslog.h>
     34   534  wendyp #include <strings.h>
     35     0  stevel 
     36     0  stevel static char time_buf[50];
     37     0  stevel #ifdef LP_USE_PAPI_ATTR
     38     0  stevel static char *extractReqno(char *req_file);
     39     0  stevel #endif
     40     0  stevel 
     41     0  stevel /**
     42     0  stevel  ** chfiles() - CHANGE OWNERSHIP OF FILES, RETURN TOTAL SIZE
     43     0  stevel  **/
     44     0  stevel 
     45     0  stevel off_t chfiles ( char * * list, uid_t uid, gid_t gid )	/* funcdef */
     46     0  stevel {
     47     0  stevel     size_t	total;
     48     0  stevel     struct stat	stbuf;
     49     0  stevel     char	*file;
     50     0  stevel 
     51     0  stevel     total = 0;
     52     0  stevel 
     53     0  stevel     while(file = *list++)
     54     0  stevel     {
     55     0  stevel 	if (STRNEQU(Lp_Temp, file, strlen(Lp_Temp)) ||
     56     0  stevel 	    STRNEQU(Lp_Tmp, file, strlen(Lp_Tmp)))
     57     0  stevel 	{
     58     0  stevel 	    /*
     59     0  stevel 	     * Once this routine (chfiles) is called for a request,
     60     0  stevel 	     * any temporary files are ``ours'', i.e. they are on our
     61     0  stevel 	     * machine. A user running on an RFS-connected remote machine
     62     0  stevel 	     * can't necessarily know our machine name, so can't put
     63     0  stevel 	     * the files where they belong (Lp_Tmp/machine). But now we
     64     0  stevel 	     * can. Of course, this is all done with mirrors, as Lp_Temp
     65     0  stevel 	     * and Lp_Tmp/local-machine are symbolicly linked. So we just
     66     0  stevel 	     * change the name. This saves on wear and tear later.
     67     0  stevel 	     */
     68     0  stevel 	    if (STRNEQU(Lp_Temp, file, strlen(Lp_Temp)))
     69     0  stevel 	    {
     70     0  stevel 		char *newfile = makepath(Lp_Tmp, Local_System,
     71     0  stevel 				file + strlen(Lp_Temp) + 1, NULL);
     72     0  stevel 
     73     0  stevel 		Free(file);
     74     0  stevel 		list[-1] = file = newfile;
     75     0  stevel 	    }
     76     0  stevel 
     77   547  jacobs 	    (void) chownmod(file, uid, gid, 0600);
     78     0  stevel 	}
     79     0  stevel 
     80     0  stevel 	if (Stat(file, &stbuf) == -1)
     81     0  stevel 	    return(-1);
     82     0  stevel 
     83     0  stevel 	switch (stbuf.st_mode & S_IFMT) {
     84     0  stevel 	case 0:
     85     0  stevel 	case S_IFREG:
     86     0  stevel 	    break;
     87     0  stevel 
     88     0  stevel 	case S_IFIFO:
     89     0  stevel 	    if (!isadmin(uid))
     90     0  stevel 		return(-1);
     91     0  stevel 	    /*
     92     0  stevel 	     * If any of the files is a FIFO, the size indicator
     93     0  stevel 	     * becomes meaningless. On the other hand, returning
     94     0  stevel 	     * a total of zero causes the request to be rejected,
     95     0  stevel 	     * so we return something > 0.
     96     0  stevel 	     */
     97     0  stevel 	    stbuf.st_size = 1;
     98     0  stevel 	    break;
     99     0  stevel 
    100     0  stevel 	case S_IFDIR:
    101     0  stevel 	case S_IFCHR:
    102     0  stevel 	case S_IFBLK:
    103     0  stevel 	default:
    104     0  stevel 	    return(-1);
    105     0  stevel 	}
    106     0  stevel 
    107     0  stevel 	total += stbuf.st_size;
    108     0  stevel     }
    109     0  stevel     return(total);
    110     0  stevel }
    111     0  stevel 
    112     0  stevel /**
    113     0  stevel  ** rmfiles() - DELETE/LOG FILES FOR DEFUNCT REQUEST
    114     0  stevel  **/
    115     0  stevel 
    116     0  stevel void rmfiles ( RSTATUS * rp, int log_it )	/* funcdef */
    117     0  stevel {
    118     0  stevel     char	**file	= rp->request->file_list;
    119     0  stevel     char	*path;
    120     0  stevel     char	num[STRSIZE(MOST_FILES) + 1];
    121     0  stevel     static int	fd	= -1;
    122     0  stevel     int		reqfd;
    123     0  stevel     int		count	= 0;
    124     0  stevel #ifdef LP_USE_PAPI_ATTR
    125     0  stevel     struct stat	tmpBuf;
    126     0  stevel     char	*idno = NULL;
    127     0  stevel     char 	tmpName[BUFSIZ];
    128     0  stevel #endif
    129     0  stevel 
    130     0  stevel 
    131     0  stevel     if (rp->req_file) {
    132     0  stevel 	    char *p, *q;
    133     0  stevel 
    134     0  stevel 	   /*
    135     0  stevel 	    * The secure request file is removed first to prevent
    136     0  stevel 	    * reloading should the system crash while in rmfiles().
    137     0  stevel 	    */
    138     0  stevel 	    path = makepath(Lp_Requests, rp->req_file, (char *)0);
    139     0  stevel 	    (void) Unlink(path);
    140     0  stevel 	    Free(path);
    141     0  stevel 
    142     0  stevel 	    /*
    143     0  stevel 	     * Copy the request file to the log file, if asked,
    144     0  stevel 	     * or simply remove it.
    145     0  stevel 	     */
    146     0  stevel 	    path = makepath(Lp_Tmp, rp->req_file, (char *)0);
    147     0  stevel 	    if (log_it && rp->secure && rp->secure->req_id) {
    148     0  stevel 		if (fd == -1)
    149     0  stevel 		    fd = open_locked(Lp_ReqLog, "a", MODE_NOREAD);
    150     0  stevel 		if ((fd  >= 0) && (reqfd = Open(path, O_RDONLY, 0)) != -1) {
    151     0  stevel 		    register int	n;
    152     0  stevel 		    char		buf[BUFSIZ];
    153     0  stevel 
    154     0  stevel 		    (void) strftime(time_buf, sizeof (time_buf),
    155     0  stevel 			NULL, localtime(&(rp->secure->date)));
    156  4321  casper 		    fdprintf(fd, "= %s, uid %u, gid %u, size %ld, %s\n",
    157     0  stevel 			rp->secure->req_id, rp->secure->uid, rp->secure->gid,
    158     0  stevel 			rp->secure->size, time_buf);
    159     0  stevel 		    if (rp->slow)
    160     0  stevel 			fdprintf(fd, "x %s\n", rp->slow);
    161     0  stevel 		    if (rp->fast)
    162     0  stevel 			fdprintf(fd, "y %s\n", rp->fast);
    163  3125  jacobs 		    if (rp->printer && rp->printer->printer)
    164     0  stevel 			fdprintf(fd, "z %s\n", rp->printer->printer->name);
    165     0  stevel 		    while ((n = Read(reqfd, buf, BUFSIZ)) > 0)
    166     0  stevel 			write (fd, buf, n);
    167     0  stevel 		    Close (reqfd);
    168     0  stevel 		}
    169     0  stevel 	    }
    170     0  stevel 	    (void)Unlink (path);		/* remove request file */
    171     0  stevel 	    Free (path);
    172     0  stevel 
    173     0  stevel 	    p = strdup(rp->req_file);		/* remove host/id file */
    174     0  stevel 	    if (q = strrchr(p, '-')) {
    175     0  stevel 		    *q = NULL;
    176     0  stevel 		    path = makepath(Lp_Tmp, p, NULL);
    177     0  stevel 		    (void) Unlink(path);
    178     0  stevel 		    Free(path);
    179     0  stevel 	    }
    180     0  stevel 	    Free(p);
    181     0  stevel 
    182     0  stevel #ifdef LP_USE_PAPI_ATTR
    183     0  stevel 	/* Look for a PAPI job attribute file, if it exists remove it */
    184     0  stevel 	idno = extractReqno(rp->req_file);
    185     0  stevel 	snprintf(tmpName, sizeof (tmpName), "%s-%s", idno, LP_PAPIATTRNAME);
    186     0  stevel 	path = makepath(Lp_Temp, tmpName, (char *)0);
    187     0  stevel 
    188     0  stevel 	if (((path != NULL) && (idno != NULL)) && (stat(path, &tmpBuf) == 0))
    189     0  stevel 	{
    190     0  stevel 	    /* PAPI job attribute file exists for this job so remove it */
    191     0  stevel 	    (void) Unlink(path);
    192     0  stevel 	}
    193     0  stevel 
    194     0  stevel 	Free(idno);
    195     0  stevel 	Free(path);
    196     0  stevel #endif
    197     0  stevel     }
    198     0  stevel 
    199     0  stevel     if (file)					/* remove file in filelist */
    200     0  stevel 	while(*file)
    201     0  stevel 	{
    202     0  stevel 		/*
    203     0  stevel 		 * The copies of user files.
    204     0  stevel 		 */
    205   534  wendyp 		if ((STRNEQU(Lp_Temp, *file, strlen(Lp_Temp)) ||
    206   534  wendyp 		    STRNEQU(Lp_Tmp, *file, strlen(Lp_Tmp))) &&
    207   534  wendyp 		    (! strstr(*file, "../")))
    208   534  wendyp 
    209     0  stevel 		    (void) Unlink(*file);
    210   534  wendyp 
    211     0  stevel 		count++;
    212     0  stevel 		file++;
    213     0  stevel 	}
    214     0  stevel 
    215     0  stevel     if (rp->secure && rp->secure->req_id) {
    216     0  stevel 	char *p;
    217     0  stevel 	p = getreqno(rp->secure->req_id);
    218     0  stevel 
    219     0  stevel 	/*
    220     0  stevel 	 * The filtered files. We can't rely on just the RS_FILTERED
    221     0  stevel 	 * flag, since the request may have been cancelled while
    222     0  stevel 	 * filtering. On the other hand, just checking "rp->slow"
    223     0  stevel 	 * doesn't mean that the files exist, because the request
    224     0  stevel 	 * may have been canceled BEFORE filtering started. Oh well.
    225     0  stevel 	 */
    226     0  stevel 	if (rp->slow)
    227     0  stevel 	    while(count > 0)
    228     0  stevel 	    {
    229     0  stevel 		sprintf(num, "%d", count--);
    230  3125  jacobs 		path = makestr(Lp_Temp, "/F", p, "-", num, (char *)0);
    231     0  stevel 		Unlink(path);
    232     0  stevel 		Free(path);
    233     0  stevel 	    }
    234     0  stevel 
    235     0  stevel 	/*
    236     0  stevel 	 * The notify/error file.
    237     0  stevel 	 */
    238     0  stevel 	path = makepath(Lp_Temp, p, (char *)0);
    239     0  stevel 	(void) Unlink(path);
    240     0  stevel 	Free(path);
    241     0  stevel     }
    242     0  stevel }
    243     0  stevel 
    244     0  stevel /**
    245     0  stevel  ** _alloc_req_id(void) - ALLOCATE NEXT REQUEST ID
    246     0  stevel  **/
    247     0  stevel 
    248     0  stevel #define	SEQF_DEF_START	1
    249     0  stevel #define	SEQF_DEF_END	59999
    250     0  stevel #define	SEQF_DEF_INCR	1
    251     0  stevel #define	SEQF		".SEQF"
    252     0  stevel 
    253     0  stevel 
    254     0  stevel long
    255     0  stevel _alloc_req_id ( void )
    256     0  stevel {
    257     0  stevel 	static short		started	= 0;
    258     0  stevel 
    259     0  stevel 	static int		fd;
    260     0  stevel 
    261     0  stevel 	static long		start;
    262     0  stevel 	static long		end;
    263     0  stevel 	static long		incr;
    264     0  stevel 	static long		curr;
    265     0  stevel 	static long		wrap;
    266     0  stevel 
    267     0  stevel 	static char		fmt[
    268     0  stevel 				STRSIZE(BIGGEST_REQID_S)/* start   */
    269     0  stevel 			      + 1			/* :       */
    270     0  stevel 			      + STRSIZE(BIGGEST_REQID_S)/* end     */
    271     0  stevel 			      + 1			/* :       */
    272     0  stevel 			      + STRSIZE(BIGGEST_REQID_S)/* incr    */
    273     0  stevel 			      + 1			/* :       */
    274     0  stevel 			      + 4			/* %ld\n   */
    275     0  stevel 			      + 1			/* (nul)   */
    276     0  stevel 				];
    277     0  stevel 
    278     0  stevel 	char 			buf[256];
    279     0  stevel 	int len;
    280     0  stevel 
    281     0  stevel 	long			ret;
    282     0  stevel 
    283     0  stevel 
    284     0  stevel 	if (!started) {
    285     0  stevel 		snprintf(buf, sizeof (buf), "%s/%s", Lp_Temp, SEQF);
    286     0  stevel 		if (((fd = open_locked(buf, "r+", 0644)) < 0) &&
    287     0  stevel 		    ((fd = open_locked(buf, "w", 0644)) < 0))
    288     0  stevel 			fail ("Can't open file %s (%s).\n", buf, PERROR);
    289     0  stevel 
    290     0  stevel 		lseek(fd, 0, SEEK_SET);
    291     0  stevel 
    292     0  stevel 		read(fd, buf, sizeof (buf));
    293     0  stevel 		if (sscanf(buf, "%ld:%ld:%ld:%ld\n", &start, &end, &incr, &curr) != 4) {
    294     0  stevel 			start = SEQF_DEF_START;
    295     0  stevel 			end = SEQF_DEF_END;
    296     0  stevel 			curr = start;
    297     0  stevel 			incr = SEQF_DEF_INCR;
    298     0  stevel 		}
    299     0  stevel 
    300     0  stevel 		if (start < 0)
    301     0  stevel 			start = SEQF_DEF_START;
    302     0  stevel 		if (end > SEQF_DEF_END)
    303     0  stevel 			end = SEQF_DEF_END;
    304     0  stevel 		if (curr < start || curr > end)
    305     0  stevel 			curr = start;
    306     0  stevel 
    307     0  stevel 		sprintf (fmt, "%ld:%ld:%ld:%%ld\n", start, end, incr);
    308     0  stevel 		started = 1;
    309     0  stevel 	}
    310     0  stevel 
    311     0  stevel 	wrap = curr;
    312     0  stevel 	do {
    313     0  stevel 		ret = curr;
    314     0  stevel 		if ((curr += incr) > end)
    315     0  stevel 	    	curr = start;
    316     0  stevel 
    317     0  stevel 	} while ( wrap != curr && ((RSTATUS *)request_by_id_num(ret)) ) ;
    318     0  stevel 
    319     0  stevel 	/* write the new id file */
    320     0  stevel 	lseek(fd, 0, SEEK_SET);
    321     0  stevel 	len = sprintf(buf, fmt, curr);
    322     0  stevel 	write(fd, buf, len);
    323     0  stevel 	ftruncate(fd, len);
    324     0  stevel 
    325     0  stevel 	if (curr == wrap) {
    326     0  stevel 		note("alloc_req_id(): out of ids\n");
    327     0  stevel 		errno = EEXIST;
    328     0  stevel 		return(SEQF_DEF_START-1);
    329     0  stevel 	} else
    330     0  stevel 		return (ret);
    331     0  stevel }
    332     0  stevel 
    333     0  stevel /**
    334     0  stevel  ** _alloc_file() - ALLOCATE FILES FOR A REQUEST
    335     0  stevel  **/
    336     0  stevel 
    337     0  stevel char *
    338     0  stevel _alloc_files (
    339     0  stevel 	int			num,
    340     0  stevel 	char *			prefix,
    341     0  stevel 	uid_t			uid,
    342  3125  jacobs 	gid_t			gid
    343     0  stevel )
    344     0  stevel {
    345     0  stevel 	static char		base[
    346     0  stevel 				1			/* F       */
    347     0  stevel 			      + STRSIZE(BIGGEST_REQID_S)/* req-id  */
    348     0  stevel 			      + 1			/* -       */
    349     0  stevel 			      + STRSIZE(MOST_FILES_S)	/* file-no */
    350     0  stevel 			      + 1			/* (nul)   */
    351     0  stevel 				];
    352     0  stevel 
    353     0  stevel 	char *			file;
    354     0  stevel 	char *			cp;
    355     0  stevel 
    356     0  stevel 	int			fd;
    357     0  stevel 	int			plus;
    358     0  stevel 
    359     0  stevel 
    360     0  stevel 	if (num > BIGGEST_REQID)
    361     0  stevel 		return (0);
    362     0  stevel 
    363     0  stevel 	if (!prefix) {
    364     0  stevel 		int id;
    365     0  stevel 
    366     0  stevel 		if ((id = _alloc_req_id()) < SEQF_DEF_START )
    367     0  stevel 			return(NULL); /* Out of request IDs (errno = EEXIST) */
    368     0  stevel 		snprintf (base, sizeof (base), "%d-%d", id, MOST_FILES);
    369     0  stevel 		plus = 0;
    370     0  stevel 	} else {
    371     0  stevel 		if (strlen(prefix) > (size_t) 6)
    372     0  stevel 			return (0);
    373     0  stevel 		snprintf (base, sizeof (base), "F%s-%d", prefix, MOST_FILES);
    374     0  stevel 		plus = 1;
    375     0  stevel 	}
    376     0  stevel 
    377  3125  jacobs 	file = makepath(Lp_Temp, base, (char *)0);
    378     0  stevel 
    379     0  stevel 	cp = strrchr(file, '-') + 1;
    380     0  stevel 	while (num--) {
    381     0  stevel 		sprintf (cp, "%d", num + plus);
    382     0  stevel 		if ((fd = Open(file, O_CREAT|O_TRUNC, 0600)) == -1) {
    383     0  stevel 			Free (file);
    384     0  stevel 			return (0);
    385     0  stevel 		} else {
    386     0  stevel 			Close (fd);
    387   547  jacobs 			(void) chownmod(file, uid, gid, 0600);
    388     0  stevel 		}
    389     0  stevel 	}
    390     0  stevel 
    391     0  stevel #ifdef LP_USE_PAPI_ATTR
    392     0  stevel 	if (prefix == NULL)
    393     0  stevel 	{
    394     0  stevel 		/*
    395     0  stevel 		 * Initial job request (s_alloc_files) so create an empty PAPI
    396     0  stevel 		 * Attribute file; note, this file will only be used if the
    397     0  stevel 		 * print job has been submitted via the PAPI interface.
    398     0  stevel 		 */
    399     0  stevel 
    400     0  stevel 		file = (char *)Realloc(file, strlen(file) +
    401     0  stevel 					strlen(LP_PAPIATTRNAME) + 1);
    402     0  stevel 		if (file != NULL)
    403     0  stevel 		{
    404     0  stevel 			cp = strrchr(file, '-') + 1;
    405     0  stevel 			sprintf(cp, "%s", LP_PAPIATTRNAME);
    406     0  stevel 
    407     0  stevel 			if ((fd = Open(file, O_CREAT|O_TRUNC, 0600)) == -1)
    408     0  stevel 			{
    409     0  stevel 				Free(file);
    410     0  stevel 				return (0);
    411     0  stevel 			}
    412     0  stevel 			else
    413     0  stevel 			{
    414     0  stevel 				Close(fd);
    415   547  jacobs 				(void) chownmod(file, uid, gid, 0600);
    416     0  stevel 			}
    417     0  stevel 
    418     0  stevel 			Free(file);
    419     0  stevel 		}
    420     0  stevel 	}
    421     0  stevel #endif
    422     0  stevel 
    423     0  stevel 
    424     0  stevel 	if ((cp = strrchr(base, '-')))
    425     0  stevel 		*cp = 0;
    426     0  stevel 
    427     0  stevel 	return (base);
    428     0  stevel }
    429     0  stevel 
    430     0  stevel 
    431     0  stevel #ifdef LP_USE_PAPI_ATTR
    432     0  stevel static char *extractReqno(char *req_file)
    433     0  stevel 
    434     0  stevel {
    435     0  stevel 	char *start = NULL;
    436     0  stevel 	char *end = NULL;
    437     0  stevel 	char *result = NULL;
    438     0  stevel 
    439     0  stevel 	start = strrchr(req_file, '/');
    440     0  stevel 	end = strrchr(req_file, '-');
    441     0  stevel 
    442     0  stevel 	if ((start != NULL) && (end != NULL))
    443     0  stevel 	{
    444     0  stevel 		start++;
    445     0  stevel 		if (end > start)
    446     0  stevel 		{
    447     0  stevel 			int n = end - start;
    448     0  stevel 			result = (char *)Malloc(n+1);
    449     0  stevel 			strncpy(result, start, n);
    450     0  stevel 			result[n] = '\0';
    451     0  stevel 		}
    452     0  stevel 	}
    453     0  stevel 
    454     0  stevel 	return (result);
    455     0  stevel } /* extractReqno() */
    456     0  stevel #endif
    457