From 0e8fd3398771da2f016d72830179507f3edda51b Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Sat, 4 May 1996 07:50:46 +0000 Subject: Initial version imported to CVS (This used to be commit 291551d80711daab7b7581720bcd9a08d6096517) --- source3/printing/printing.c | 859 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 859 insertions(+) create mode 100644 source3/printing/printing.c (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c new file mode 100644 index 0000000000..1dd8921800 --- /dev/null +++ b/source3/printing/printing.c @@ -0,0 +1,859 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + printing routines + Copyright (C) Andrew Tridgell 1992-1995 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "loadparm.h" +extern int DEBUGLEVEL; +extern connection_struct Connections[]; +extern files_struct Files[]; + +static BOOL * lpq_cache_reset=NULL; + +static int check_lpq_cache(int snum) { + static int lpq_caches=0; + + if (lpq_caches <= snum) { + BOOL * p; + p = (BOOL *) Realloc(lpq_cache_reset,(snum+1)*sizeof(BOOL)); + if (p) { + lpq_cache_reset=p; + lpq_caches = snum+1; + } + } + return lpq_caches; +} + +void lpq_reset(int snum) +{ + if (check_lpq_cache(snum) > snum) lpq_cache_reset[snum]=True; +} + + +/**************************************************************************** +Build the print command in the supplied buffer. This means getting the +print command for the service and inserting the printer name and the +print file name. Return NULL on error, else the passed buffer pointer. +****************************************************************************/ +static char *build_print_command(int cnum, char *command, char *syscmd, char *filename1) +{ + int snum = SNUM(cnum); + char *tstr; + pstring filename; + + /* get the print command for the service. */ + tstr = command; + if (!syscmd || !tstr) { + DEBUG(0,("No print command for service `%s'\n", SERVICE(snum))); + return (NULL); + } + + /* copy the command into the buffer for extensive meddling. */ + StrnCpy(syscmd, tstr, sizeof(pstring) - 1); + + /* look for "%s" in the string. If there is no %s, we cannot print. */ + if (!strstr(syscmd, "%s") && !strstr(syscmd, "%f")) { + DEBUG(2,("WARNING! No placeholder for the filename in the print command for service %s!\n", SERVICE(snum))); + } + + if (strstr(syscmd,"%s")) { + int iOffset = strstr(syscmd, "%s") - syscmd; + + /* construct the full path for the filename, shouldn't be necessary unless + the subshell causes a "cd" to be executed. + Only use the full path if there isn't a / preceding the %s */ + if (iOffset==0 || syscmd[iOffset-1] != '/') { + StrnCpy(filename,Connections[cnum].connectpath,sizeof(filename)-1); + trim_string(filename,"","/"); + strcat(filename,"/"); + strcat(filename,filename1); + } + else + strcpy(filename,filename1); + + string_sub(syscmd, "%s", filename); + } + + string_sub(syscmd, "%f", filename1); + + /* Does the service have a printername? If not, make a fake and empty */ + /* printer name. That way a %p is treated sanely if no printer */ + /* name was specified to replace it. This eventuality is logged. */ + tstr = PRINTERNAME(snum); + if (tstr == NULL || tstr[0] == '\0') { + DEBUG(3,( "No printer name - using %s.\n", SERVICE(snum))); + tstr = SERVICE(snum); + } + + string_sub(syscmd, "%p", tstr); + + standard_sub(cnum,syscmd); + + return (syscmd); +} + + +/**************************************************************************** +print a file - called on closing the file +****************************************************************************/ +void print_file(int fnum) +{ + pstring syscmd; + int cnum = Files[fnum].cnum; + int snum=SNUM(cnum); + char *tempstr; + + *syscmd = 0; + + if (file_size(Files[fnum].name) <= 0) { + DEBUG(3,("Discarding null print job %s\n",Files[fnum].name)); + sys_unlink(Files[fnum].name); + return; + } + + tempstr = build_print_command(cnum, PRINTCOMMAND(snum), syscmd, Files[fnum].name); + if (tempstr != NULL) + { + int ret = smbrun(syscmd,NULL); + DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); + } + else + DEBUG(0,("Null print command?\n")); + + lpq_reset(snum); +} + +static char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Err"}; + + +/******************************************************************* +process time fields +********************************************************************/ +static time_t EntryTime(string tok[], int ptr, int count, int minimum) +{ + time_t jobtime; + + jobtime = time(NULL); /* default case: take current time */ + if (count >= minimum) { + struct tm *t; + int i, day, hour, min, sec; + char *c; + + for (i=0; i<13; i++) if (!strncmp(tok[ptr], Months[i],3)) break; /* Find month */ + if (i<12) { + t = localtime(&jobtime); + day = atoi(tok[ptr+1]); + c=(char *)(tok[ptr+2]); + *(c+2)=0; + hour = atoi(c); + *(c+5)=0; + min = atoi(c+3); + if(*(c+6) != 0)sec = atoi(c+6); + else sec=0; + + if ((t->tm_mon < i)|| + ((t->tm_mon == i)&& + ((t->tm_mday < day)|| + ((t->tm_mday == day)&& + (t->tm_hour*60+t->tm_min < hour*60+min))))) + t->tm_year--; /* last year's print job */ + + t->tm_mon = i; + t->tm_mday = day; + t->tm_hour = hour; + t->tm_min = min; + t->tm_sec = sec; + jobtime = mktime(t); + } + } + return jobtime; +} + + +/**************************************************************************** +parse a lpq line + +here is an example of lpq output under bsd + +Warning: no daemon present +Rank Owner Job Files Total Size +1st tridge 148 README 8096 bytes + +here is an example of lpq output under osf/1 + +Warning: no daemon present +Rank Pri Owner Job Files Total Size +1st 0 tridge 148 README 8096 bytes +****************************************************************************/ +static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) +{ +#ifdef OSF1 +#define RANKTOK 0 +#define PRIOTOK 1 +#define USERTOK 2 +#define JOBTOK 3 +#define FILETOK 4 +#define TOTALTOK 5 +#define NTOK 6 +#else /* OSF1 */ +#define RANKTOK 0 +#define USERTOK 1 +#define JOBTOK 2 +#define FILETOK 3 +#define TOTALTOK 4 +#define NTOK 5 +#endif /* OSF1 */ + + string tok[NTOK]; + int count=0; + +#ifdef OSF1 + int length; + length = strlen(line); + if (line[length-3] == ':') + return(False); +#endif /* OSF1 */ + + /* handle the case of "(standard input)" as a filename */ + string_sub(line,"standard input","STDIN"); + string_sub(line,"(","\""); + string_sub(line,")","\""); + + for (count=0; countjob = atoi(tok[JOBTOK]); + buf->size = atoi(tok[TOTALTOK]); + buf->status = strequal(tok[RANKTOK],"active")?LPQ_PRINTING:LPQ_QUEUED; + buf->time = time(NULL); + StrnCpy(buf->user,tok[USERTOK],sizeof(buf->user)-1); + StrnCpy(buf->file,tok[FILETOK],sizeof(buf->file)-1); +#ifdef PRIOTOK + buf->priority = atoi(tok[PRIOTOK]); +#else + buf->priority = 1; +#endif + return(True); +} + + + +/******************************************************************* +parse lpq on an aix system + +Queue Dev Status Job Files User PP % Blks Cp Rnk +------- ----- --------- --- ------------------ ---------- ---- -- ----- --- --- +lazer lazer READY +lazer lazer RUNNING 537 6297doc.A kvintus@IE 0 10 2445 1 1 + QUEUED 538 C.ps root@IEDVB 124 1 2 + QUEUED 539 E.ps root@IEDVB 28 1 3 + QUEUED 540 L.ps root@IEDVB 172 1 4 + QUEUED 541 P.ps root@IEDVB 22 1 5 +********************************************************************/ +static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) +{ + string tok[11]; + int count=0; + + /* handle the case of "(standard input)" as a filename */ + string_sub(line,"standard input","STDIN"); + string_sub(line,"(","\""); + string_sub(line,")","\""); + + for (count=0; count<10 && next_token(&line,tok[count],NULL); count++) ; + + /* we must get 6 tokens */ + if (count < 10) + { + if ((count == 7) && (strcmp(tok[0],"QUEUED") == 0)) + { + /* the 2nd and 5th columns must be integer */ + if (!isdigit(*tok[1]) || !isdigit(*tok[4])) return(False); + buf->size = atoi(tok[4]) * 1024; + /* if the fname contains a space then use STDIN */ + if (strchr(tok[2],' ')) + strcpy(tok[2],"STDIN"); + + /* only take the last part of the filename */ + { + string tmp; + char *p = strrchr(tok[2],'/'); + if (p) + { + strcpy(tmp,p+1); + strcpy(tok[2],tmp); + } + } + + + buf->job = atoi(tok[1]); + buf->status = LPQ_QUEUED; + buf->priority = 0; + buf->time = time(NULL); + StrnCpy(buf->user,tok[3],sizeof(buf->user)-1); + StrnCpy(buf->file,tok[2],sizeof(buf->file)-1); + } + else + { + DEBUG(6,("parse_lpq_aix count=%d\n", count)); + return(False); + } + } + else + { + /* the 4th and 9th columns must be integer */ + if (!isdigit(*tok[3]) || !isdigit(*tok[8])) return(False); + buf->size = atoi(tok[8]) * 1024; + /* if the fname contains a space then use STDIN */ + if (strchr(tok[4],' ')) + strcpy(tok[4],"STDIN"); + + /* only take the last part of the filename */ + { + string tmp; + char *p = strrchr(tok[4],'/'); + if (p) + { + strcpy(tmp,p+1); + strcpy(tok[4],tmp); + } + } + + + buf->job = atoi(tok[3]); + buf->status = strequal(tok[2],"RUNNING")?LPQ_PRINTING:LPQ_QUEUED; + buf->priority = 0; + buf->time = time(NULL); + StrnCpy(buf->user,tok[5],sizeof(buf->user)-1); + StrnCpy(buf->file,tok[4],sizeof(buf->file)-1); + } + + + return(True); +} + + +/**************************************************************************** +parse a lpq line +here is an example of lpq output under hpux; note there's no space after -o ! +$> lpstat -oljplus +ljplus-2153 user priority 0 Jan 19 08:14 on ljplus + util.c 125697 bytes + server.c 110712 bytes +ljplus-2154 user priority 0 Jan 19 08:14 from client + (standard input) 7551 bytes +****************************************************************************/ +static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first) +{ + /* must read two lines to process, therefore keep some values static */ + static BOOL header_line_ok=False, base_prio_reset=False; + static string jobuser; + static int jobid; + static int jobprio; + static time_t jobtime; + static int jobstat=LPQ_QUEUED; + /* to store minimum priority to print, lpstat command should be invoked + with -p option first, to work */ + static int base_prio; + + int count; + char TAB = '\011'; + string tok[12]; + + /* If a line begins with a horizontal TAB, it is a subline type */ + + if (line[0] == TAB) { /* subline */ + /* check if it contains the base priority */ + if (!strncmp(line,"\tfence priority : ",18)) { + base_prio=atoi(&line[18]); + DEBUG(4, ("fence priority set at %d\n", base_prio)); + } + if (!header_line_ok) return (False); /* incorrect header line */ + /* handle the case of "(standard input)" as a filename */ + string_sub(line,"standard input","STDIN"); + string_sub(line,"(","\""); + string_sub(line,")","\""); + + for (count=0; count<2 && next_token(&line,tok[count],NULL); count++) ; + /* we must get 2 tokens */ + if (count < 2) return(False); + + /* the 2nd column must be integer */ + if (!isdigit(*tok[1])) return(False); + + /* if the fname contains a space then use STDIN */ + if (strchr(tok[0],' ')) + strcpy(tok[0],"STDIN"); + + buf->size = atoi(tok[1]); + StrnCpy(buf->file,tok[0],sizeof(buf->file)-1); + + /* fill things from header line */ + buf->time = jobtime; + buf->job = jobid; + buf->status = jobstat; + buf->priority = jobprio; + StrnCpy(buf->user,jobuser,sizeof(buf->user)-1); + + return(True); + } + else { /* header line */ + header_line_ok=False; /* reset it */ + if (first) { + if (!base_prio_reset) { + base_prio=0; /* reset it */ + base_prio_reset=True; + } + } + else if (base_prio) base_prio_reset=False; + + /* handle the dash in the job id */ + string_sub(line,"-"," "); + + for (count=0; count<12 && next_token(&line,tok[count],NULL); count++) ; + + /* we must get 8 tokens */ + if (count < 8) return(False); + + /* first token must be printer name (cannot check ?) */ + /* the 2nd, 5th & 7th column must be integer */ + if (!isdigit(*tok[1]) || !isdigit(*tok[4]) || !isdigit(*tok[6])) return(False); + jobid = atoi(tok[1]); + StrnCpy(jobuser,tok[2],sizeof(buf->user)-1); + jobprio = atoi(tok[4]); + + /* process time */ + jobtime=EntryTime(tok, 5, count, 8); + if (jobprio < base_prio) { + jobstat = LPQ_PAUSED; + DEBUG (4, ("job %d is paused: prio %d < %d; jobstat=%d\n", jobid, jobprio, base_prio, jobstat)); + } + else { + jobstat = LPQ_QUEUED; + if ((count >8) && (((strequal(tok[8],"on")) || + ((strequal(tok[8],"from")) && + ((count > 10)&&(strequal(tok[10],"on"))))))) + jobstat = LPQ_PRINTING; + } + + header_line_ok=True; /* information is correct */ + return(False); /* need subline info to include into queuelist */ + } +} + + +/**************************************************************************** +parse a lpq line + +here is an example of "lpstat -o dcslw" output under sysv + +dcslw-896 tridge 4712 Dec 20 10:30:30 on dcslw +dcslw-897 tridge 4712 Dec 20 10:30:30 being held + +****************************************************************************/ +static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first) +{ + string tok[9]; + int count=0; + char *p; + + /* handle the dash in the job id */ + string_sub(line,"-"," "); + + for (count=0; count<9 && next_token(&line,tok[count],NULL); count++) ; + + /* we must get 7 tokens */ + if (count < 7) + return(False); + + /* the 2nd and 4th, 6th columns must be integer */ + if (!isdigit(*tok[1]) || !isdigit(*tok[3])) return(False); + if (!isdigit(*tok[5])) return(False); + + /* if the user contains a ! then trim the first part of it */ + if ((p=strchr(tok[2],'!'))) + { + string tmp; + strcpy(tmp,p+1); + strcpy(tok[2],tmp); + } + + + buf->job = atoi(tok[1]); + buf->size = atoi(tok[3]); + if (count > 7 && strequal(tok[7],"on")) + buf->status = LPQ_PRINTING; + else if (count > 8 && strequal(tok[7],"being") && strequal(tok[8],"held")) + buf->status = LPQ_PAUSED; + else + buf->status = LPQ_QUEUED; + buf->priority = 0; + buf->time = EntryTime(tok, 4, count, 7); + StrnCpy(buf->user,tok[2],sizeof(buf->user)-1); + StrnCpy(buf->file,tok[2],sizeof(buf->file)-1); + return(True); +} + +/**************************************************************************** +parse a lpq line + +here is an example of lpq output under qnx +Spooler: /qnx/spooler, on node 1 +Printer: txt (ready) +0000: root [job #1 ] active 1146 bytes /etc/profile +0001: root [job #2 ] ready 2378 bytes /etc/install +0002: root [job #3 ] ready 1146 bytes -- standard input -- +****************************************************************************/ +static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first) +{ + string tok[7]; + int count=0; + + DEBUG(0,("antes [%s]\n", line)); + + /* handle the case of "-- standard input --" as a filename */ + string_sub(line,"standard input","STDIN"); + DEBUG(0,("despues [%s]\n", line)); + string_sub(line,"-- ","\""); + string_sub(line," --","\""); + DEBUG(0,("despues 1 [%s]\n", line)); + + string_sub(line,"[job #",""); + string_sub(line,"]",""); + DEBUG(0,("despues 2 [%s]\n", line)); + + + + for (count=0; count<7 && next_token(&line,tok[count],NULL); count++) ; + + /* we must get 7 tokens */ + if (count < 7) + return(False); + + /* the 3rd and 5th columns must be integer */ + if (!isdigit(*tok[2]) || !isdigit(*tok[4])) return(False); + + /* only take the last part of the filename */ + { + string tmp; + char *p = strrchr(tok[6],'/'); + if (p) + { + strcpy(tmp,p+1); + strcpy(tok[6],tmp); + } + } + + + buf->job = atoi(tok[2]); + buf->size = atoi(tok[4]); + buf->status = strequal(tok[3],"active")?LPQ_PRINTING:LPQ_QUEUED; + buf->priority = 0; + buf->time = time(NULL); + StrnCpy(buf->user,tok[1],sizeof(buf->user)-1); + StrnCpy(buf->file,tok[6],sizeof(buf->file)-1); + return(True); +} + + + +char *stat0_strings[] = { "enabled", "online", "idle", "no entries", "free", "ready", NULL }; +char *stat1_strings[] = { "offline", "disabled", "down", "off", "waiting", "no daemon", NULL }; +char *stat2_strings[] = { "jam", "paper", "error", "responding", "not accepting", "not running", "turned off", NULL }; + +/**************************************************************************** +parse a lpq line. Choose printing style +****************************************************************************/ +static BOOL parse_lpq_entry(int snum,char *line, + print_queue_struct *buf, + print_status_struct *status,BOOL first) +{ + BOOL ret; + + switch (lp_printing()) + { + case PRINT_SYSV: + ret = parse_lpq_sysv(line,buf,first); + break; + case PRINT_AIX: + ret = parse_lpq_aix(line,buf,first); + break; + case PRINT_HPUX: + ret = parse_lpq_hpux(line,buf,first); + break; + case PRINT_QNX: + ret = parse_lpq_qnx(line,buf,first); + break; + default: + ret = parse_lpq_bsd(line,buf,first); + break; + } + +#ifdef LPQ_GUEST_TO_USER + if (ret) { + extern pstring sesssetup_user; + /* change guest entries to the current logged in user to make + them appear deletable to windows */ + if (sesssetup_user[0] && strequal(buf->user,lp_guestaccount(snum))) + strcpy(buf->user,sesssetup_user); + } +#endif + + if (status && !ret) + { + /* a few simple checks to see if the line might be a + printer status line: + handle them so that most severe condition is shown */ + int i; + strlower(line); + + switch (status->status) { + case LPSTAT_OK: + for (i=0; stat0_strings[i]; i++) + if (strstr(line,stat0_strings[i])) { + StrnCpy(status->message,line,sizeof(status->message)-1); + status->status=LPSTAT_OK; + } + case LPSTAT_STOPPED: + for (i=0; stat1_strings[i]; i++) + if (strstr(line,stat1_strings[i])) { + StrnCpy(status->message,line,sizeof(status->message)-1); + status->status=LPSTAT_STOPPED; + } + case LPSTAT_ERROR: + for (i=0; stat2_strings[i]; i++) + if (strstr(line,stat2_strings[i])) { + StrnCpy(status->message,line,sizeof(status->message)-1); + status->status=LPSTAT_ERROR; + } + break; + } + } + + return(ret); +} + +/**************************************************************************** +get a printer queue +****************************************************************************/ +int get_printqueue(int snum,int cnum,print_queue_struct **queue, + print_status_struct *status) +{ + char *lpq_command = lp_lpqcommand(snum); + char *printername = PRINTERNAME(snum); + int ret=0,count=0; + pstring syscmd; + fstring outfile; + pstring line; + FILE *f; + struct stat sbuf; + BOOL dorun=True; + int cachetime = lp_lpqcachetime(); + int lfd = -1; + + *line = 0; + check_lpq_cache(snum); + + if (!printername || !*printername) + { + DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n", + lp_servicename(snum),snum)); + printername = lp_servicename(snum); + } + + if (!lpq_command || !(*lpq_command)) + { + DEBUG(5,("No lpq command\n")); + return(0); + } + + strcpy(syscmd,lpq_command); + string_sub(syscmd,"%p",printername); + + standard_sub(cnum,syscmd); + + sprintf(outfile,"/tmp/lpq.%08x",str_checksum(syscmd)); + + if (!lpq_cache_reset[snum] && cachetime && !stat(outfile,&sbuf)) + { + if (time(NULL) - sbuf.st_mtime < cachetime) { + DEBUG(3,("Using cached lpq output\n")); + dorun = False; + } + + if (dorun) { + lfd = file_lock(outfile,LPQ_LOCK_TIMEOUT); + if (lfd<0 || + (!fstat(lfd,&sbuf) && (time(NULL) - sbuf.st_mtime)= 0) file_unlock(lfd); + return(0); + } + + if (status) { + strcpy(status->message,""); + status->status = LPSTAT_OK; + } + + while (fgets(line,sizeof(pstring),f)) + { + DEBUG(6,("QUEUE2: %s\n",line)); + + *queue = Realloc(*queue,sizeof(print_queue_struct)*(count+1)); + if (! *queue) + { + count = 0; + break; + } + + bzero((char *)&(*queue)[count],sizeof(**queue)); + + /* parse it */ + if (!parse_lpq_entry(snum,line,&(*queue)[count],status,count==0)) + continue; + + count++; + } + + fclose(f); + + if (lfd >= 0) file_unlock(lfd); + + if (!cachetime) + unlink(outfile); + else + chmod(outfile,0666); + return(count); +} + + +/**************************************************************************** +delete a printer queue entry +****************************************************************************/ +void del_printqueue(int cnum,int snum,int jobid) +{ + char *lprm_command = lp_lprmcommand(snum); + char *printername = PRINTERNAME(snum); + pstring syscmd; + char jobstr[20]; + int ret; + + if (!printername || !*printername) + { + DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n", + lp_servicename(snum),snum)); + printername = lp_servicename(snum); + } + + if (!lprm_command || !(*lprm_command)) + { + DEBUG(5,("No lprm command\n")); + return; + } + + sprintf(jobstr,"%d",jobid); + + strcpy(syscmd,lprm_command); + string_sub(syscmd,"%p",printername); + string_sub(syscmd,"%j",jobstr); + standard_sub(cnum,syscmd); + + ret = smbrun(syscmd,NULL); + DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); + lpq_reset(snum); /* queue has changed */ +} + +/**************************************************************************** +change status of a printer queue entry +****************************************************************************/ +void status_printjob(int cnum,int snum,int jobid,int status) +{ + char *lpstatus_command = + (status==LPQ_PAUSED?lp_lppausecommand(snum):lp_lpresumecommand(snum)); + char *printername = PRINTERNAME(snum); + pstring syscmd; + char jobstr[20]; + int ret; + + if (!printername || !*printername) + { + DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n", + lp_servicename(snum),snum)); + printername = lp_servicename(snum); + } + + if (!lpstatus_command || !(*lpstatus_command)) + { + DEBUG(5,("No lpstatus command to %s job\n", + (status==LPQ_PAUSED?"pause":"resume"))); + return; + } + + sprintf(jobstr,"%d",jobid); + + strcpy(syscmd,lpstatus_command); + string_sub(syscmd,"%p",printername); + string_sub(syscmd,"%j",jobstr); + standard_sub(cnum,syscmd); + + ret = smbrun(syscmd,NULL); + DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); + lpq_reset(snum); /* queue has changed */ +} + + -- cgit From 58734631b4233ec08b7a262587e400792f31f185 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 31 May 1996 15:13:29 +0000 Subject: Lots of changes! - add faq info on NT printer handling - add "delete readonly" option to help rcs users - add stuff to man pages on new printer options - add "proxy name resolution" option - add "command string" -c option to smbclient (thanks Ken) - split time functions into time.c - rearrange the quotas stuff a bit and fix some bugs - complete rehash of the time handling code thanks to Paul Eggert - fix nmblookup output a bit - add plp print queue parsing from Bertrand Wallrich (This used to be commit 635b56f19c817527c52e9bbde31faa6a8a47777b) --- source3/printing/printing.c | 81 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 1dd8921800..2aa27926d9 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -149,7 +149,7 @@ process time fields ********************************************************************/ static time_t EntryTime(string tok[], int ptr, int count, int minimum) { - time_t jobtime; + time_t jobtime,jobtime1; jobtime = time(NULL); /* default case: take current time */ if (count >= minimum) { @@ -181,7 +181,9 @@ static time_t EntryTime(string tok[], int ptr, int count, int minimum) t->tm_hour = hour; t->tm_min = min; t->tm_sec = sec; - jobtime = mktime(t); + jobtime1 = mktime(t); + if (jobtime1 != (time_t)-1) + jobtime = jobtime1; } } return jobtime; @@ -596,6 +598,78 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first) } +/**************************************************************************** + parse a lpq line for the plp printing system + Bertrand Wallrich +****************************************************************************/ +static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first) +{ + string tok[5]; + int count=0; + + /* handle the case of "(standard input)" as a filename */ + string_sub(line,"stdin","STDIN"); + string_sub(line,"(","\""); + string_sub(line,")","\""); + + for (count=0; count<8 && next_token(&line,tok[count],NULL); count++) ; + + /* we must get 5 tokens */ + if (count < 8) + return(False); + + /* the 4rd must be integer */ + if (!isdigit(*tok[3])) return(False); + + /* if the fname contains a space then use STDIN */ + if (strchr(tok[3],' ')) + strcpy(tok[3],"STDIN"); + + /* only take the last part of the filename */ + { + string tmp; + char *p = strrchr(tok[5],'/'); + if (p) + { + strcpy(tmp,p+1); + strcpy(tok[5],tmp); + } + } + + + buf->job = atoi(tok[3]); + + /* calcul de la taille du fichier */ + if (!isdigit(*tok[7])) { buf->size = atoi(tok[7]) * 1.0 ; } + else { + string tmp; + strcpy(tmp,tok[7]); + if (strchr(tok[7],'K')) { + strncpy(tok[7],tmp,strlen(tmp)-1); + buf->size = atoi(tok[7]); + buf->size = buf->size * 1024; + } + if (strchr(tok[7],'M')) { + strncpy(tok[7],tmp,strlen(tmp)-1); + buf->size = atoi(tok[7]); + buf->size = buf->size * 1024.0 * 1000.0; + } + if (strchr(tok[7],'G')) { + strncpy(tok[7],tmp,strlen(tmp)-1); + buf->size = atoi(tok[7]); + buf->size = buf->size * 1024.0 * 1000000.0; + } + + } + buf->status = strequal(tok[0],"active")?LPQ_PRINTING:LPQ_QUEUED; + buf->priority = 0; + buf->time = time(NULL); + StrnCpy(buf->user,tok[1],sizeof(buf->user)-1); + StrnCpy(buf->file,tok[5],sizeof(buf->file)-1); + return(True); +} + + char *stat0_strings[] = { "enabled", "online", "idle", "no entries", "free", "ready", NULL }; char *stat1_strings[] = { "offline", "disabled", "down", "off", "waiting", "no daemon", NULL }; @@ -624,6 +698,9 @@ static BOOL parse_lpq_entry(int snum,char *line, case PRINT_QNX: ret = parse_lpq_qnx(line,buf,first); break; + case PRINT_PLP: + ret = parse_lpq_plp(line,buf,first); + break; default: ret = parse_lpq_bsd(line,buf,first); break; -- cgit From 7e3b4a1c0df1434eb3d02f93c736ce065f9898d8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Jun 1996 04:38:24 +0000 Subject: got rid of a lot of redundent header files as we now globally generate prototypes automatically using "make proto". This is much less prone to error than the old method of manually adding prototypes (This used to be commit b551dc98f7cc194a5fc2e67a4ebae7fd67a01bbc) --- source3/printing/printing.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 2aa27926d9..b6265798a1 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -20,7 +20,6 @@ */ #include "includes.h" -#include "loadparm.h" extern int DEBUGLEVEL; extern connection_struct Connections[]; extern files_struct Files[]; -- cgit From dc38599c5a01211f20b9685dd440df82cd25c5cc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Jun 1996 12:23:54 +0000 Subject: - change date as a demo for john - modified plp printing parser to work on my system (This used to be commit 9408f91e1b9a2482af96afe9df08e0a5fba60cdb) --- source3/printing/printing.c | 64 ++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 33 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index b6265798a1..2eef0d303b 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -600,10 +600,19 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first) /**************************************************************************** parse a lpq line for the plp printing system Bertrand Wallrich + +redone by tridge. Here is a sample queue: + +Local Printer 'lp2' (fjall): + Printing (started at Jun 15 13:33:58, attempt 1). + Rank Owner Pr Opt Job Host Files Size Date + active tridge X - 6 fjall /etc/hosts 739 Jun 15 13:33 + 3rd tridge X - 7 fjall /etc/hosts 739 Jun 15 13:33 + ****************************************************************************/ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first) { - string tok[5]; + string tok[11]; int count=0; /* handle the case of "(standard input)" as a filename */ @@ -611,60 +620,49 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first) string_sub(line,"(","\""); string_sub(line,")","\""); - for (count=0; count<8 && next_token(&line,tok[count],NULL); count++) ; + for (count=0; count<11 && next_token(&line,tok[count],NULL); count++) ; - /* we must get 5 tokens */ - if (count < 8) + /* we must get 11 tokens */ + if (count < 11) return(False); - /* the 4rd must be integer */ - if (!isdigit(*tok[3])) return(False); + /* the first must be "active" or begin with an integer */ + if (strcmp(tok[0],"active") && !isdigit(tok[0][0])) + return(False); + + /* the 5th and 8th must be integer */ + if (!isdigit(*tok[4]) || !isdigit(*tok[7])) + return(False); /* if the fname contains a space then use STDIN */ - if (strchr(tok[3],' ')) - strcpy(tok[3],"STDIN"); + if (strchr(tok[6],' ')) + strcpy(tok[6],"STDIN"); /* only take the last part of the filename */ { string tmp; - char *p = strrchr(tok[5],'/'); + char *p = strrchr(tok[6],'/'); if (p) { strcpy(tmp,p+1); - strcpy(tok[5],tmp); + strcpy(tok[6],tmp); } } - buf->job = atoi(tok[3]); + buf->job = atoi(tok[4]); - /* calcul de la taille du fichier */ - if (!isdigit(*tok[7])) { buf->size = atoi(tok[7]) * 1.0 ; } - else { - string tmp; - strcpy(tmp,tok[7]); - if (strchr(tok[7],'K')) { - strncpy(tok[7],tmp,strlen(tmp)-1); - buf->size = atoi(tok[7]); - buf->size = buf->size * 1024; - } - if (strchr(tok[7],'M')) { - strncpy(tok[7],tmp,strlen(tmp)-1); - buf->size = atoi(tok[7]); - buf->size = buf->size * 1024.0 * 1000.0; - } - if (strchr(tok[7],'G')) { - strncpy(tok[7],tmp,strlen(tmp)-1); - buf->size = atoi(tok[7]); - buf->size = buf->size * 1024.0 * 1000000.0; - } + buf->size = atoi(tok[7]); + if (strchr(tok[7],'K')) + buf->size *= 1024; + if (strchr(tok[7],'M')) + buf->size *= 1024*1024; - } buf->status = strequal(tok[0],"active")?LPQ_PRINTING:LPQ_QUEUED; buf->priority = 0; buf->time = time(NULL); StrnCpy(buf->user,tok[1],sizeof(buf->user)-1); - StrnCpy(buf->file,tok[5],sizeof(buf->file)-1); + StrnCpy(buf->file,tok[6],sizeof(buf->file)-1); return(True); } -- cgit From 396311075cc808278e6dd8469e3ac7eb7e7498c7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 13 Aug 1996 08:57:55 +0000 Subject: - sequent-ptx support from bressler@iftccu.ca.boeing.com (Rick Bressler) - machten support from Trevor Strohman (trev@figment.tenon.com) - added qinfo command to client as part of drag-and-drop printer support for win95 from David Chappell He also added the "printer driver" option - use sigblock() on more systems and use sigsetmask(0) instead of sigunblock() as its more portable. This beats a problem with zombies on heavilily loaded systems. - added internals.doc written by David Chappell into the source tree - get rid of PRINT_COMMAND options from local.h as they are no longer relevent - new kanji code from Fujita - don't set the recursion_available flag on queries in nmbd - fix a potential bug with pointer subtraction in printing.c - got rid of error_count code as the real fix (the EOF problem) is now in (This used to be commit aa6f8b04d125b5bc00f267abf72b800228aabf7d) --- source3/printing/printing.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 2eef0d303b..7ffded8e91 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -73,7 +73,7 @@ static char *build_print_command(int cnum, char *command, char *syscmd, char *fi } if (strstr(syscmd,"%s")) { - int iOffset = strstr(syscmd, "%s") - syscmd; + int iOffset = PTR_DIFF(strstr(syscmd, "%s"),syscmd); /* construct the full path for the filename, shouldn't be necessary unless the subshell causes a "cd" to be executed. @@ -713,6 +713,9 @@ static BOOL parse_lpq_entry(int snum,char *line, } #endif + /* We don't want the newline in the status message. */ + line[strcspn(line,"\n")] = (char)NULL; + if (status && !ret) { /* a few simple checks to see if the line might be a -- cgit From 7ef19ee4bcb089c4894a864b1348f81a1dd07cd0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 13 Aug 1996 09:00:11 +0000 Subject: don't allow newlines in printer status messages (This used to be commit d84f5402fded4ffb9c2735fecaa47ec3d2c636c0) --- source3/printing/printing.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 7ffded8e91..00df859e0a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -714,7 +714,10 @@ static BOOL parse_lpq_entry(int snum,char *line, #endif /* We don't want the newline in the status message. */ - line[strcspn(line,"\n")] = (char)NULL; + { + char *p = strchr(line,'\n'); + if (p) *p = 0; + } if (status && !ret) { -- cgit From 0c33046a0aa0461a5e932dd7b0b6e38ab9708867 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 Aug 1996 11:17:29 +0000 Subject: - added "netbios name" option in smb.conf to make controlling the name that samba uses possible - added "socket address" option to allow virtual SMB servers (on systems with IP aliasing line Linux) - disabled FAST_SHARE_MODES by default in Linux as older Linux boxes can't do shared writeable mappings. We really need autoconf ... - added new option types in loadparm so a string type can be specified ot be uppercase only, this is used for the workgroup and netbios name options - auto-create the lock directory if it doesn't exist in shared mem startup - get rid of announce_backup() - change a few comments in nmbd code - rewrote the chaining code completely. Hopefully it will handle any depth chains now. - added LPRng support (This used to be commit e9eac6cd49c352349580ddb13d720cb201aecc48) --- source3/printing/printing.c | 154 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 00df859e0a..d1b702cb0a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -277,6 +277,157 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) return(True); } +/* + +LPRng_time modifies the current date by inserting the hour and minute from +the lpq output. The lpq time looks like "23:15:07" +*/ +static time_t LPRng_time(string tok[],int pos) +{ + time_t jobtime; + struct tm *t; + char tmp_time[9]; + + jobtime = time(NULL); /* default case: take current time */ + t = localtime(&jobtime); + t->tm_hour = atoi(tok[pos]); + StrnCpy(tmp_time,tok[pos],sizeof(tmp_time)); + t->tm_min = atoi(tmp_time+3); + t->tm_sec = atoi(tmp_time+6); + jobtime = mktime(t); + + return jobtime; +} + + +/**************************************************************************** + parse a lpq line + + Most of the code is directly reused from parse_lpq_bsd() + +here are two examples of lpq output under lprng (LPRng-2.3.0) + +Printer: humprn@hum-fak + Queue: 1 printable job + Server: pid 4840 active, Unspooler: pid 4841 active + Status: job 'cfA659hum-fak', closing device at Fri Jun 21 10:10:21 1996 + Rank Owner Class Job Files Size Time +active magnus@hum-fak A 659 /var/spool/smb/Notesblok-ikke-na4024 10:03:31 + +Printer: humprn@hum-fak (printing disabled) + Queue: 1 printable job + Warning: no server present + Status: finished operations at Fri Jun 21 10:10:32 1996 + Rank Owner Class Job Files Size Time +1 magnus@hum-fak A 387 /var/spool/smb/netbudget.xls 21230 10:50:53 + +****************************************************************************/ +static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first) +{ +#define LPRNG_RANKTOK 0 +#define LPRNG_USERTOK 1 +#define LPRNG_PRIOTOK 2 +#define LPRNG_JOBTOK 3 +#define LPRNG_FILETOK 4 +#define LPRNG_TOTALTOK 5 +#define LPRNG_TIMETOK 6 +#define LPRNG_NTOK 7 + +/**************************************************************************** +From lpd_status.c in LPRng source. +0 1 2 3 4 5 6 7 +12345678901234567890123456789012345678901234567890123456789012345678901234 +" Rank Owner Class Job Files Size Time" + plp_snprintf( msg, sizeof(msg), "%-6s %-19s %c %03d %-32s", + number, line, priority, cfp->number, error ); + plp_snprintf( msg + len, sizeof(msg)-len, "%4d", + cfp->jobsize ); + plp_snprintf( msg+len, sizeof(msg)-len, " %s", + Time_str( 1, cfp->statb.st_ctime ) ); +****************************************************************************/ + /* The following define's are to be able to adjust the values if the +LPRng source changes. This is from version 2.3.0. Magnus */ +#define SPACE_W 1 +#define RANK_W 6 +#define OWNER_W 19 +#define CLASS_W 1 +#define JOB_W 3 +#define FILE_W 32 +/* The JOBSIZE_W is too small for big jobs, so time is pushed to the right */ +#define JOBSIZE_W 4 + +#define RANK_POS 0 +#define OWNER_POS RANK_POS+RANK_W+SPACE_W +#define CLASS_POS OWNER_POS+OWNER_W+SPACE_W +#define JOB_POS CLASS_POS+CLASS_W+SPACE_W +#define FILE_POS JOB_POS+JOB_W+SPACE_W +#define JOBSIZE_POS FILE_POS+FILE_W + + + string tok[LPRNG_NTOK]; + int count=0; + +/* +Need to insert one space in front of the size, to be able to use +next_token() unchanged. I would have liked to be able to insert a +space instead, to prevent losing that one char, but perl has spoiled +me :-\ So I did it the easiest way. + +HINT: Use as short a path as possible for the samba spool directory. +A long spool-path will just waste significant chars of the file name. +*/ + + (char)line[JOBSIZE_POS-1]=' '; + + /* handle the case of "(stdin)" as a filename */ + string_sub(line,"stdin","STDIN"); + string_sub(line,"(","\""); + string_sub(line,")","\""); + + for (count=0; countjob = atoi(tok[LPRNG_JOBTOK]); + buf->size = atoi(tok[LPRNG_TOTALTOK]); + buf->status = strequal(tok[LPRNG_RANKTOK],"active")?LPQ_PRINTING:LPQ_QUEUED; + /* buf->time = time(NULL); */ + buf->time = LPRng_time(tok,LPRNG_TIMETOK); +DEBUG(3,("Time reported for job %d is %s", buf->job, ctime(&buf->time))); + StrnCpy(buf->user,tok[LPRNG_USERTOK],sizeof(buf->user)-1); + StrnCpy(buf->file,tok[LPRNG_FILETOK],sizeof(buf->file)-1); +#ifdef LPRNG_PRIOTOK + /* Here I try to map the CLASS char to a number, but the number + is never shown in Print Manager under NT anyway... Magnus. */ + buf->priority = atoi(tok[LPRNG_PRIOTOK-('A'-1)]); +#else + buf->priority = 1; +#endif + return(True); +} + /******************************************************************* @@ -695,6 +846,9 @@ static BOOL parse_lpq_entry(int snum,char *line, case PRINT_QNX: ret = parse_lpq_qnx(line,buf,first); break; + case PRINT_LPRNG: + ret = parse_lpq_lprng(line,buf,first); + break; case PRINT_PLP: ret = parse_lpq_plp(line,buf,first); break; -- cgit From 66a13075a49a4a77666971f4f23db93793a0831e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 21 Aug 1996 08:33:47 +0000 Subject: fix compiler warning (This used to be commit 5a6425c3cb6181c202f4575733db1c642eadb4bc) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index d1b702cb0a..ad840d7f51 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -377,7 +377,7 @@ HINT: Use as short a path as possible for the samba spool directory. A long spool-path will just waste significant chars of the file name. */ - (char)line[JOBSIZE_POS-1]=' '; + line[JOBSIZE_POS-1]=' '; /* handle the case of "(stdin)" as a filename */ string_sub(line,"stdin","STDIN"); -- cgit From e23f2b9cef8428bda51b413642d9720ba5c590d5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 4 Oct 1996 09:31:07 +0000 Subject: - changed the umask handling. We now set the umask to 0 and explicitly set the mode on all created files. I think this is a better policy. - change the debug levels on some items - fix a charset handling bug which affected foreign and extended charset users - no longer switch back to the original directory when idle, instead switch to / as the original directory may not be readable by ordinary users. - fix some bugs where the create mode of files was not being explicitly set (it was relying on the umask and using fopen). Not a big bug as it only affected obscure commands like the messaging ops. - got rid of the lock code in the lpq cache as its no longer needed - rewrote smbrun to be faster and to remove the security hole. We now don't actually need a external smbrun binary, its all done by smbd. - add a more explicit warning about uids and gids of -1 or 65535 (This used to be commit 5aa735c940ccdb6acae5f28449d484181c912e49) --- source3/printing/printing.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index ad840d7f51..87552ab3ff 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -130,7 +130,7 @@ void print_file(int fnum) tempstr = build_print_command(cnum, PRINTCOMMAND(snum), syscmd, Files[fnum].name); if (tempstr != NULL) { - int ret = smbrun(syscmd,NULL); + int ret = smbrun(syscmd,NULL,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); } else @@ -923,7 +923,6 @@ int get_printqueue(int snum,int cnum,print_queue_struct **queue, struct stat sbuf; BOOL dorun=True; int cachetime = lp_lpqcachetime(); - int lfd = -1; *line = 0; check_lpq_cache(snum); @@ -954,20 +953,10 @@ int get_printqueue(int snum,int cnum,print_queue_struct **queue, DEBUG(3,("Using cached lpq output\n")); dorun = False; } - - if (dorun) { - lfd = file_lock(outfile,LPQ_LOCK_TIMEOUT); - if (lfd<0 || - (!fstat(lfd,&sbuf) && (time(NULL) - sbuf.st_mtime)= 0) file_unlock(lfd); return(0); } @@ -1006,12 +994,13 @@ int get_printqueue(int snum,int cnum,print_queue_struct **queue, fclose(f); - if (lfd >= 0) file_unlock(lfd); - - if (!cachetime) + if (!cachetime) { unlink(outfile); - else + } else { + /* we only expect this to succeed on trapdoor systems, on normal systems + the file is owned by root */ chmod(outfile,0666); + } return(count); } @@ -1047,7 +1036,7 @@ void del_printqueue(int cnum,int snum,int jobid) string_sub(syscmd,"%j",jobstr); standard_sub(cnum,syscmd); - ret = smbrun(syscmd,NULL); + ret = smbrun(syscmd,NULL,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); lpq_reset(snum); /* queue has changed */ } @@ -1085,7 +1074,7 @@ void status_printjob(int cnum,int snum,int jobid,int status) string_sub(syscmd,"%j",jobstr); standard_sub(cnum,syscmd); - ret = smbrun(syscmd,NULL); + ret = smbrun(syscmd,NULL,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); lpq_reset(snum); /* queue has changed */ } -- cgit From 08d00eb68ee93eaead0f3bbaabc3d89540e0818e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 24 Oct 1996 00:09:08 +0000 Subject: - added support for TMPDIR env variable - fixed fault.c for linux 2.1 - put back in the FIND_SELF failing code - cleaned up casts in encryption (This used to be commit 3af04f1580b2569c0a4f2549bf6352c7a25afa0d) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 87552ab3ff..f026d77156 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -945,7 +945,7 @@ int get_printqueue(int snum,int cnum,print_queue_struct **queue, standard_sub(cnum,syscmd); - sprintf(outfile,"/tmp/lpq.%08x",str_checksum(syscmd)); + sprintf(outfile,"%s/lpq.%08x",tmpdir(),str_checksum(syscmd)); if (!lpq_cache_reset[snum] && cachetime && !stat(outfile,&sbuf)) { -- cgit From 087c162f8fb76b338a9b2e037669292f4f81c166 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 6 Feb 1997 17:33:03 +0000 Subject: Fixed incorrect offset into array. jra@cygnus.com (This used to be commit 7c386c45b069462760b4a9c755959b67d5874cc1) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index f026d77156..d2071ace59 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -421,7 +421,7 @@ DEBUG(3,("Time reported for job %d is %s", buf->job, ctime(&buf->time))); #ifdef LPRNG_PRIOTOK /* Here I try to map the CLASS char to a number, but the number is never shown in Print Manager under NT anyway... Magnus. */ - buf->priority = atoi(tok[LPRNG_PRIOTOK-('A'-1)]); + buf->priority = atoi(tok[LPRNG_PRIOTOK]-('A'-1)); #else buf->priority = 1; #endif -- cgit From 0f1f0ceb9519368188f695e18e2341ccfd1b2d15 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 8 May 1997 01:14:17 +0000 Subject: 'The mother of all checkins' :-). Jeremy Allison (jallison@whistle.com) Wed May 7 1997: Update for 1.9.17alpha1 release - 'browsefix release' designed to make browsing across subnets work. byteorder.h: Updated copyright to 1997. charcnv.c: Updated copyright to 1997. charset.c Updated copyright to 1997. charset.h Updated copyright to 1997. client.c Updated copyright to 1997. clientutil.c Updated copyright to 1997. dir.c Updated copyright to 1997. fault.c Updated copyright to 1997. includes.h Updated copyright to 1997. interface.c Updated copyright to 1997. ipc.c Updated copyright to 1997. kanji.c Updated copyright to 1997. kanji.h Updated copyright to 1997. loadparm.c Updated copyright to 1997. locking.c Updated copyright to 1997. mangle.c Updated copyright to 1997. message.c Updated copyright to 1997. nameannounce.c Made use of WINS subnet explicit. Added reset_announce_timer() so announcement can be made immediately when we become a master. Expanded code to do sync with dmb. namebrowse.c Removed redundent checks for AM_MASTER in sync code. Made use of WINS subnet explicit. namedbname.c Made use of WINS subnet explicit. namedbresp.c Made use of WINS subnet explicit. namedbserver.c Made use of WINS subnet explicit. namedbsubnet.c Explicitly add workgroup to WINS subnet when we become a dmb. Made use of WINS subnet explicit. namedbwork.c Made use of WINS subnet explicit. Removed redundent check_work_servertype() function. nameelect.c Explicitly add workgroup to WINS subnet when we become a master browser. Made use of WINS subnet explicit. namelogon.c Updated copyright to 1997. namepacket.c Updated copyright to 1997. namequery.c Updated copyright to 1997. nameresp.c Made use of WINS subnet explicit. Made nmbd fail if configured as master browser and one exists already. nameserv.c Made use of WINS subnet explicit. Remove redundent logon server and domain master code. nameserv.h Add emumerate subnet macros. nameservreply.c Made use of WINS subnet explicit. nameservresp.c Updated copyright to 1997. namework.c Made use of WINS subnet explicit. Updated code to add sync browser entries to add subnet parameter. nmbd.c Added sanity check for misconfigured nmbd. nmblib.c Updated copyright to 1997. nmblookup.c Updated copyright to 1997. nmbsync.c Removed redundent AM_ANY_MASTER check. params.c Updated copyright to 1997. password.c Updated copyright to 1997. pipes.c Updated copyright to 1997. predict.c Updated copyright to 1997. printing.c Updated copyright to 1997. proto.h Changed protos for new nmbd code. quotas.c Updated copyright to 1997. replace.c Updated copyright to 1997. reply.c Updated copyright to 1997. server.c Updated copyright to 1997. shmem.c Updated copyright to 1997. smb.h Updated copyright to 1997. smbencrypt.c Updated copyright to 1997. smbpasswd.c Updated copyright to 1997. smbrun.c Updated copyright to 1997. status.c Updated copyright to 1997. system.c Updated copyright to 1997. testparm.c Updated copyright to 1997. testprns.c Updated copyright to 1997. time.c Updated copyright to 1997. trans2.c Updated copyright to 1997. trans2.h Updated copyright to 1997. uid.c Updated copyright to 1997. username.c Updated copyright to 1997. util.c Updated copyright to 1997. version.h Changed to 1.9.17alpha1. (This used to be commit cf23a155a1315f50d488794a2caf88402bf3e3e6) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index d2071ace59..c4dd9803eb 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. printing routines - Copyright (C) Andrew Tridgell 1992-1995 + Copyright (C) Andrew Tridgell 1992-1997 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From f434139087ea45ed1eb578267843943b0f04c94c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 31 Aug 1997 02:18:59 +0000 Subject: fixed a bug in the printjob encoding/decoding. We weren't doing it for the print_ functions in reply.c, with the effect that you couldn't cancel print jobs from smbclient or from older dos clients. we now use a couple of utility functions printjob_encode() and printjob_decode() rather than sticking the bitops inline in each place. also fixed a bunch of places that used foo%0xFF rather than foo&0xFF Note that this isn't really me doing the commit, it can't be as I'm working on my thesis ... (This used to be commit 3556763be3acbf01c967ee9717943dd44163fb9f) --- source3/printing/printing.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index c4dd9803eb..c83d216989 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -929,8 +929,8 @@ int get_printqueue(int snum,int cnum,print_queue_struct **queue, if (!printername || !*printername) { - DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n", - lp_servicename(snum),snum)); + DEBUG(6,("xx replacing printer name with service (snum=(%s,%d))\n", + lp_servicename(snum),snum)); printername = lp_servicename(snum); } @@ -1080,3 +1080,23 @@ void status_printjob(int cnum,int snum,int jobid,int status) } + +/**************************************************************************** +we encode print job numbers over the wire so that when we get them back we can +tell not only what print job they are but also what service it belongs to, +this is to overcome the problem that windows clients tend to send the wrong +service number when doing print queue manipulation! +****************************************************************************/ +int printjob_encode(int snum, int job) +{ + return ((snum&0xFF)<<8) | (job & 0xFF); +} + +/**************************************************************************** +and now decode them again ... +****************************************************************************/ +void printjob_decode(int jobid, int *snum, int *job) +{ + (*snum) = (jobid >> 8) & 0xFF; + (*job) = jobid & 0xFF; +} -- cgit From cef59090bb2fd3f8a9efd1a453cb90264b891d58 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 26 Sep 1997 18:55:29 +0000 Subject: Adding Andrews buffer overflow fixes into the main branch. Jeremy (jallison@whistle.com) (This used to be commit e7eb1f044d3101679dc7a118820ea5efe0cd837c) --- source3/printing/printing.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index c83d216989..51fd3a992e 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -85,7 +85,7 @@ static char *build_print_command(int cnum, char *command, char *syscmd, char *fi strcat(filename,filename1); } else - strcpy(filename,filename1); + pstrcpy(filename,filename1); string_sub(syscmd, "%s", filename); } @@ -258,7 +258,7 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) if (p) { strcpy(tmp,p+1); - strcpy(tok[FILETOK],tmp); + fstrcpy(tok[FILETOK],tmp); } } @@ -404,8 +404,8 @@ A long spool-path will just waste significant chars of the file name. char *p = strrchr(tok[LPRNG_FILETOK],'/'); if (p) { - strcpy(tmp,p+1); - strcpy(tok[LPRNG_FILETOK],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[LPRNG_FILETOK],tmp); } } @@ -472,8 +472,8 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) char *p = strrchr(tok[2],'/'); if (p) { - strcpy(tmp,p+1); - strcpy(tok[2],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[2],tmp); } } @@ -506,8 +506,8 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) char *p = strrchr(tok[4],'/'); if (p) { - strcpy(tmp,p+1); - strcpy(tok[4],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[4],tmp); } } @@ -666,8 +666,8 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first) if ((p=strchr(tok[2],'!'))) { string tmp; - strcpy(tmp,p+1); - strcpy(tok[2],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[2],tmp); } @@ -731,8 +731,8 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first) char *p = strrchr(tok[6],'/'); if (p) { - strcpy(tmp,p+1); - strcpy(tok[6],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[6],tmp); } } @@ -795,8 +795,8 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first) char *p = strrchr(tok[6],'/'); if (p) { - strcpy(tmp,p+1); - strcpy(tok[6],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[6],tmp); } } @@ -863,7 +863,7 @@ static BOOL parse_lpq_entry(int snum,char *line, /* change guest entries to the current logged in user to make them appear deletable to windows */ if (sesssetup_user[0] && strequal(buf->user,lp_guestaccount(snum))) - strcpy(buf->user,sesssetup_user); + pstrcpy(buf->user,sesssetup_user); } #endif @@ -940,7 +940,7 @@ int get_printqueue(int snum,int cnum,print_queue_struct **queue, return(0); } - strcpy(syscmd,lpq_command); + pstrcpy(syscmd,lpq_command); string_sub(syscmd,"%p",printername); standard_sub(cnum,syscmd); @@ -1031,7 +1031,7 @@ void del_printqueue(int cnum,int snum,int jobid) sprintf(jobstr,"%d",jobid); - strcpy(syscmd,lprm_command); + pstrcpy(syscmd,lprm_command); string_sub(syscmd,"%p",printername); string_sub(syscmd,"%j",jobstr); standard_sub(cnum,syscmd); @@ -1069,7 +1069,7 @@ void status_printjob(int cnum,int snum,int jobid,int status) sprintf(jobstr,"%d",jobid); - strcpy(syscmd,lpstatus_command); + pstrcpy(syscmd,lpstatus_command); string_sub(syscmd,"%p",printername); string_sub(syscmd,"%j",jobstr); standard_sub(cnum,syscmd); -- cgit From bd1abc6927d9f99161c3b6fa2a715d935fa24bf1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 3 Dec 1997 03:00:49 +0000 Subject: hopefully handle "ready and waiting" messages in print queue output a little better (This used to be commit 465edceecf86cafd225e5662b01242f87f0bd603) --- source3/printing/printing.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 51fd3a992e..040bb8c497 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -887,18 +887,21 @@ static BOOL parse_lpq_entry(int snum,char *line, if (strstr(line,stat0_strings[i])) { StrnCpy(status->message,line,sizeof(status->message)-1); status->status=LPSTAT_OK; + return ret; } case LPSTAT_STOPPED: for (i=0; stat1_strings[i]; i++) if (strstr(line,stat1_strings[i])) { StrnCpy(status->message,line,sizeof(status->message)-1); status->status=LPSTAT_STOPPED; + return ret; } case LPSTAT_ERROR: for (i=0; stat2_strings[i]; i++) if (strstr(line,stat2_strings[i])) { StrnCpy(status->message,line,sizeof(status->message)-1); status->status=LPSTAT_ERROR; + return ret; } break; } -- cgit From 11d7f4a2aa01d5bd010fd18934c2516f39a41e3c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 3 Dec 1997 03:37:02 +0000 Subject: make the "printing" option a per share option rather than global. When printing to lots of different sorts of remote printers this is useful (This used to be commit 7a88bed4a5ca8afe1f2836f7f9a019db01bf998e) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 040bb8c497..ccca91a253 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -832,7 +832,7 @@ static BOOL parse_lpq_entry(int snum,char *line, { BOOL ret; - switch (lp_printing()) + switch (lp_printing(snum)) { case PRINT_SYSV: ret = parse_lpq_sysv(line,buf,first); -- cgit From c23ed625b22bfc765ba95cb7b8addf55625fea44 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 7 Jan 1998 06:21:56 +0000 Subject: includes.h: Added FreeBSD 3.x fixes. Added HPUX10.x fixes. interface.c: Added netmask fix. nmbd_nameregister.c: Fixed unitialised variable warnings. nmbd_winsproxy.c: Fixed unitialised variable warnings. nmbd_winsserver.c: Fixed DEC warnings. print_svid.c: Fixed DEC warnings. printing.c: Added LPRng fixes. Jeremy. (This used to be commit 28aff043c4a3693a0c20e87c7ce11eb4bf285b78) --- source3/printing/printing.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index ccca91a253..76b962606b 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -320,6 +320,23 @@ Printer: humprn@hum-fak (printing disabled) Status: finished operations at Fri Jun 21 10:10:32 1996 Rank Owner Class Job Files Size Time 1 magnus@hum-fak A 387 /var/spool/smb/netbudget.xls 21230 10:50:53 + +****************************************************************************** + +NEW FOR LPRng-3.3.5 ! + + +This will not happen anymore: with LPRng-3.3.5 there is always a blank between +the filename and the size, and the format has changed: + +Printer: lj6@lizard 'HP LaserJet 6P' + Queue: 2 printable jobs + Server: pid 11941 active + Unspooler: pid 11942 active + Status: printed all 1818 bytes at 19:49:59 + Rank Owner/ID Class Job Files Size Time +active root@lizard+937 A 937 (stdin) 1818 19:49:58 +2 root@lizard+969 A 969 junk.txt 2170 19:50:12 ****************************************************************************/ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first) @@ -367,6 +384,12 @@ LPRng source changes. This is from version 2.3.0. Magnus */ string tok[LPRNG_NTOK]; int count=0; +#ifdef OLD_LPRNG +/* We only need this bugfix for older versions of lprng - current + information is that version 3.3.5 must not have this line + in order to work correctly. +*/ + /* Need to insert one space in front of the size, to be able to use next_token() unchanged. I would have liked to be able to insert a @@ -378,6 +401,7 @@ A long spool-path will just waste significant chars of the file name. */ line[JOBSIZE_POS-1]=' '; +#endif /* OLD_LPRNG */ /* handle the case of "(stdin)" as a filename */ string_sub(line,"stdin","STDIN"); -- cgit From 118213c059501d384be9a6dcaf02d13a681bedc3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Jan 1998 09:25:05 +0000 Subject: printing.c: Bug fix for lpng reporting. server.c: Large fix for oplock deadlock bug. util.c: Fix for oplock deadlock bug. Jeremy. (This used to be commit 4cae830ab3a942b2f2868173a492d02f6332651d) --- source3/printing/printing.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 76b962606b..629b3ad496 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -436,7 +436,12 @@ A long spool-path will just waste significant chars of the file name. buf->job = atoi(tok[LPRNG_JOBTOK]); buf->size = atoi(tok[LPRNG_TOTALTOK]); - buf->status = strequal(tok[LPRNG_RANKTOK],"active")?LPQ_PRINTING:LPQ_QUEUED; + if (strequal(tok[LPRNG_RANKTOK],"active")) + buf->status = LPQ_PRINTING; + else if (strequal(tok[LPRNG_RANKTOK],"hold")) + buf->status = LPQ_PAUSED; + else + buf->status = LPQ_QUEUED; /* buf->time = time(NULL); */ buf->time = LPRng_time(tok,LPRNG_TIMETOK); DEBUG(3,("Time reported for job %d is %s", buf->job, ctime(&buf->time))); -- cgit From 55f400bd84f26027f5ec9b7fa06b22895de7557c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Jan 1998 13:27:43 +0000 Subject: This is *not* a big change (although it looks like one). This is merely updating the Copyright statements from 1997 to 1998. It's a once a year thing :-). NO OTHER CHANGES WERE MADE. Jeremy. (This used to be commit b9c16977231efb274e08856f7f3f4408dad6d96c) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 629b3ad496..71b89022e6 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. printing routines - Copyright (C) Andrew Tridgell 1992-1997 + Copyright (C) Andrew Tridgell 1992-1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From 5546e28e69b1a43dbb48e024e233d8ebf7fa667a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 7 Feb 1998 12:15:20 +0000 Subject: A small raft of changes, I will sync up with 1.9.18 also. chgpasswd.c: Fixed typo in debug message. includes.h: Fix include for aix. kanji.c: Added cap_to_sj as inverse of sj_to_cap. loadparm.c: local.h: password.c: Added code for "networkstation user login" parameter. - patch from Rob Nielsen . printing.c: Added further aix printing fixes. reply.c: Changed access time fetch to a function. trans2.c: Changed access time fetch to a function. time.c: Changed access time fetch to a function. server.c: Made NT redirector workaround final. util.c: Added debug for write_socket failing. Jeremy. (This used to be commit a031404623c22d62f8de035be2239f609af08112) --- source3/printing/printing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 71b89022e6..bf49a37203 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -486,7 +486,7 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) /* we must get 6 tokens */ if (count < 10) { - if ((count == 7) && (strcmp(tok[0],"QUEUED") == 0)) + if ((count == 7) && ((strcmp(tok[0],"QUEUED") == 0) || (strcmp(tok[0],"HELD") == 0))) { /* the 2nd and 5th columns must be integer */ if (!isdigit(*tok[1]) || !isdigit(*tok[4])) return(False); @@ -508,7 +508,7 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) buf->job = atoi(tok[1]); - buf->status = LPQ_QUEUED; + buf->status = strequal(tok[0],"HELD")?LPQ_PAUSED:LPQ_QUEUED; buf->priority = 0; buf->time = time(NULL); StrnCpy(buf->user,tok[3],sizeof(buf->user)-1); -- cgit From 612cbb6a6039c2cafb3de5e644f23a2a26d6c645 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 2 Apr 1998 01:01:24 +0000 Subject: Patch from Chris Maltby . His comments follow: + improvement to smbtar to allow exclusion/inclusion of system and hidden files, and to generate a listing of what has been archived in a format useful for automated backup systems. + add the "Softq" spooling system to samba's printing capabilities. + I have "fixed" the intrusion of US style dates into samba reporting as well. The format yyyy/mm/dd is not only uunambiguous, but also has the benefit of making lexicographic sorts work correctly. Jeremy. (This used to be commit f9dacd1d8b89fccad859c0c6bc7a492823eb4b06) --- source3/printing/printing.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index bf49a37203..c7db5744e2 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -846,6 +846,84 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first) return(True); } +/**************************************************************************** +parse a qstat line + +here is an example of "qstat -l -d qms" output under softq + +Queue qms: 2 jobs; daemon active (313); enabled; accepting; + job-ID submission-time pri size owner title +205980: H 98/03/09 13:04:05 0 15733 stephenf chap1.ps +206086:> 98/03/12 17:24:40 0 659 chris - +206087: 98/03/12 17:24:45 0 4876 chris - +Total: 21268 bytes in queue + + +****************************************************************************/ +static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first) +{ + string tok[10]; + int count=0; + + /* mung all the ":"s to spaces*/ + string_sub(line,":"," "); + + for (count=0; count<10 && next_token(&line,tok[count],NULL); count++) ; + + /* we must get 9 tokens */ + if (count < 9) + return(False); + + /* the 1st and 7th columns must be integer */ + if (!isdigit(*tok[0]) || !isdigit(*tok[6])) return(False); + /* if the 2nd column is either '>' or 'H' then the 7th and 8th must be + * integer, else it's the 6th and 7th that must be + */ + if (*tok[1] == 'H' || *tok[1] == '>') + { + if (!isdigit(*tok[7])) + return(False); + buf->status = *tok[1] == '>' ? LPQ_PRINTING : LPQ_PAUSED; + count = 1; + } + else + { + if (!isdigit(*tok[5])) + return(False); + buf->status = LPQ_QUEUED; + count = 0; + } + + + buf->job = atoi(tok[0]); + buf->size = atoi(tok[count+6]); + buf->priority = atoi(tok[count+5]); + StrnCpy(buf->user,tok[count+7],sizeof(buf->user)-1); + StrnCpy(buf->file,tok[count+8],sizeof(buf->file)-1); + buf->time = time(NULL); /* default case: take current time */ + { + time_t jobtime; + struct tm *t; + + t = localtime(&buf->time); + t->tm_mday = atoi(tok[count+2]+6); + t->tm_mon = atoi(tok[count+2]+3); + switch (*tok[count+2]) + { + case 7: case 8: case 9: t->tm_year = atoi(tok[count+2]) + 1900; break; + default: t->tm_year = atoi(tok[count+2]) + 2000; break; + } + + t->tm_hour = atoi(tok[count+3]); + t->tm_min = atoi(tok[count+4]); + t->tm_sec = atoi(tok[count+5]); + jobtime = mktime(t); + if (jobtime != (time_t)-1) + buf->time = jobtime; + } + + return(True); +} char *stat0_strings[] = { "enabled", "online", "idle", "no entries", "free", "ready", NULL }; @@ -881,6 +959,9 @@ static BOOL parse_lpq_entry(int snum,char *line, case PRINT_PLP: ret = parse_lpq_plp(line,buf,first); break; + case PRINT_SOFTQ: + ret = parse_lpq_softq(line,buf,first); + break; default: ret = parse_lpq_bsd(line,buf,first); break; -- cgit From a2bddb20ed078c3e1b9cb60a7420b3d107898f52 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 6 May 1998 01:34:51 +0000 Subject: Fixes for the %U and %G problems people have reported. Essentially, multiple session_setup_and_X's may be done to an smbd. As there is only one global variable containing the requested connection name (sessionsetup_user), then any subsequent sessionsetups overwrite this name (causing %U and %G to get the wrong name). This is particularly common when an NT client does a null session setup to get a browse list after the user has connected, but before a share has been mounted. These changes store the requested_name in the vuid structure (so this only really works for user level and above security) and copies this name back into the global variable before the standard_sub call. Jeremy. (This used to be commit b5187ad6a3b3af9fbbeee8bced0ab16b41e9825b) --- source3/printing/printing.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index c7db5744e2..bbc0ff6144 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -103,7 +103,7 @@ static char *build_print_command(int cnum, char *command, char *syscmd, char *fi string_sub(syscmd, "%p", tstr); - standard_sub(cnum,syscmd); + standard_sub(cnum,syscmd,UID_FIELD_INVALID); return (syscmd); } @@ -1056,7 +1056,7 @@ int get_printqueue(int snum,int cnum,print_queue_struct **queue, pstrcpy(syscmd,lpq_command); string_sub(syscmd,"%p",printername); - standard_sub(cnum,syscmd); + standard_sub(cnum,syscmd,UID_FIELD_INVALID); sprintf(outfile,"%s/lpq.%08x",tmpdir(),str_checksum(syscmd)); @@ -1147,7 +1147,7 @@ void del_printqueue(int cnum,int snum,int jobid) pstrcpy(syscmd,lprm_command); string_sub(syscmd,"%p",printername); string_sub(syscmd,"%j",jobstr); - standard_sub(cnum,syscmd); + standard_sub(cnum,syscmd,UID_FIELD_INVALID); ret = smbrun(syscmd,NULL,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); @@ -1185,7 +1185,7 @@ void status_printjob(int cnum,int snum,int jobid,int status) pstrcpy(syscmd,lpstatus_command); string_sub(syscmd,"%p",printername); string_sub(syscmd,"%j",jobstr); - standard_sub(cnum,syscmd); + standard_sub(cnum,syscmd,UID_FIELD_INVALID); ret = smbrun(syscmd,NULL,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); -- cgit From 01df1ed95f880a671ead7bc92b3bcff01a2e2dc0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 May 1998 19:04:14 +0000 Subject: This should (hopefully :-) be the final fix for the %U %G substitution problem.... smbpass.c: Removed Luke's dire warning - as some of the functions in here *need* to be called externally :-). Jeremy. (This used to be commit 1fd8d12ca414066acec71b33eb8a13e16c2acd3a) --- source3/printing/printing.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index bbc0ff6144..c7db5744e2 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -103,7 +103,7 @@ static char *build_print_command(int cnum, char *command, char *syscmd, char *fi string_sub(syscmd, "%p", tstr); - standard_sub(cnum,syscmd,UID_FIELD_INVALID); + standard_sub(cnum,syscmd); return (syscmd); } @@ -1056,7 +1056,7 @@ int get_printqueue(int snum,int cnum,print_queue_struct **queue, pstrcpy(syscmd,lpq_command); string_sub(syscmd,"%p",printername); - standard_sub(cnum,syscmd,UID_FIELD_INVALID); + standard_sub(cnum,syscmd); sprintf(outfile,"%s/lpq.%08x",tmpdir(),str_checksum(syscmd)); @@ -1147,7 +1147,7 @@ void del_printqueue(int cnum,int snum,int jobid) pstrcpy(syscmd,lprm_command); string_sub(syscmd,"%p",printername); string_sub(syscmd,"%j",jobstr); - standard_sub(cnum,syscmd,UID_FIELD_INVALID); + standard_sub(cnum,syscmd); ret = smbrun(syscmd,NULL,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); @@ -1185,7 +1185,7 @@ void status_printjob(int cnum,int snum,int jobid,int status) pstrcpy(syscmd,lpstatus_command); string_sub(syscmd,"%p",printername); string_sub(syscmd,"%j",jobstr); - standard_sub(cnum,syscmd,UID_FIELD_INVALID); + standard_sub(cnum,syscmd); ret = smbrun(syscmd,NULL,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); -- cgit From 3dfc0c847240ac7e12c39f4ed9c31a888949ade1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 11 May 1998 06:38:36 +0000 Subject: changed to use slprintf() instead of sprintf() just about everywhere. I've implemented slprintf() as a bounds checked sprintf() using mprotect() and a non-writeable page. This should prevent any sprintf based security holes. (This used to be commit ee09e9dadb69aaba5a751dd20ccc6d587d841bd6) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index c7db5744e2..278c54933d 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1058,7 +1058,7 @@ int get_printqueue(int snum,int cnum,print_queue_struct **queue, standard_sub(cnum,syscmd); - sprintf(outfile,"%s/lpq.%08x",tmpdir(),str_checksum(syscmd)); + slprintf(outfile,sizeof(outfile)-1, "%s/lpq.%08x",tmpdir(),str_checksum(syscmd)); if (!lpq_cache_reset[snum] && cachetime && !stat(outfile,&sbuf)) { -- cgit From f888868f46a5418bac9ab528497136c152895305 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 May 1998 00:55:32 +0000 Subject: This is a security audit change of the main source. It removed all ocurrences of the following functions : sprintf strcpy strcat The replacements are slprintf, safe_strcpy and safe_strcat. It should not be possible to use code in Samba that uses sprintf, strcpy or strcat, only the safe_equivalents. Once Andrew has fixed the slprintf implementation then this code will be moved back to the 1.9.18 code stream. Jeremy. (This used to be commit 2d774454005f0b54e5684cf618da7060594dfcbb) --- source3/printing/printing.c | 60 ++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 278c54933d..1ffe9d00a9 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -81,8 +81,8 @@ static char *build_print_command(int cnum, char *command, char *syscmd, char *fi if (iOffset==0 || syscmd[iOffset-1] != '/') { StrnCpy(filename,Connections[cnum].connectpath,sizeof(filename)-1); trim_string(filename,"","/"); - strcat(filename,"/"); - strcat(filename,filename1); + pstrcat(filename,"/"); + pstrcat(filename,filename1); } else pstrcpy(filename,filename1); @@ -146,7 +146,7 @@ static char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", /******************************************************************* process time fields ********************************************************************/ -static time_t EntryTime(string tok[], int ptr, int count, int minimum) +static time_t EntryTime(fstring tok[], int ptr, int count, int minimum) { time_t jobtime,jobtime1; @@ -223,7 +223,7 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) #define NTOK 5 #endif /* OSF1 */ - string tok[NTOK]; + fstring tok[NTOK]; int count=0; #ifdef OSF1 @@ -249,15 +249,15 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) /* if the fname contains a space then use STDIN */ if (strchr(tok[FILETOK],' ')) - strcpy(tok[FILETOK],"STDIN"); + fstrcpy(tok[FILETOK],"STDIN"); /* only take the last part of the filename */ { - string tmp; + fstring tmp; char *p = strrchr(tok[FILETOK],'/'); if (p) { - strcpy(tmp,p+1); + fstrcpy(tmp,p+1); fstrcpy(tok[FILETOK],tmp); } } @@ -282,7 +282,7 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) LPRng_time modifies the current date by inserting the hour and minute from the lpq output. The lpq time looks like "23:15:07" */ -static time_t LPRng_time(string tok[],int pos) +static time_t LPRng_time(fstring tok[],int pos) { time_t jobtime; struct tm *t; @@ -381,7 +381,7 @@ LPRng source changes. This is from version 2.3.0. Magnus */ #define JOBSIZE_POS FILE_POS+FILE_W - string tok[LPRNG_NTOK]; + fstring tok[LPRNG_NTOK]; int count=0; #ifdef OLD_LPRNG @@ -420,11 +420,11 @@ A long spool-path will just waste significant chars of the file name. /* if the fname contains a space then use STDIN */ /* I do not understand how this would be possible. Magnus. */ if (strchr(tok[LPRNG_FILETOK],' ')) - strcpy(tok[LPRNG_FILETOK],"STDIN"); + fstrcpy(tok[LPRNG_FILETOK],"STDIN"); /* only take the last part of the filename */ { - string tmp; + fstring tmp; char *p = strrchr(tok[LPRNG_FILETOK],'/'); if (p) { @@ -473,7 +473,7 @@ lazer lazer RUNNING 537 6297doc.A kvintus@IE 0 10 2445 1 1 ********************************************************************/ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) { - string tok[11]; + fstring tok[11]; int count=0; /* handle the case of "(standard input)" as a filename */ @@ -493,11 +493,11 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) buf->size = atoi(tok[4]) * 1024; /* if the fname contains a space then use STDIN */ if (strchr(tok[2],' ')) - strcpy(tok[2],"STDIN"); + fstrcpy(tok[2],"STDIN"); /* only take the last part of the filename */ { - string tmp; + fstring tmp; char *p = strrchr(tok[2],'/'); if (p) { @@ -527,11 +527,11 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) buf->size = atoi(tok[8]) * 1024; /* if the fname contains a space then use STDIN */ if (strchr(tok[4],' ')) - strcpy(tok[4],"STDIN"); + fstrcpy(tok[4],"STDIN"); /* only take the last part of the filename */ { - string tmp; + fstring tmp; char *p = strrchr(tok[4],'/'); if (p) { @@ -568,7 +568,7 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first) { /* must read two lines to process, therefore keep some values static */ static BOOL header_line_ok=False, base_prio_reset=False; - static string jobuser; + static fstring jobuser; static int jobid; static int jobprio; static time_t jobtime; @@ -579,7 +579,7 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first) int count; char TAB = '\011'; - string tok[12]; + fstring tok[12]; /* If a line begins with a horizontal TAB, it is a subline type */ @@ -604,7 +604,7 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first) /* if the fname contains a space then use STDIN */ if (strchr(tok[0],' ')) - strcpy(tok[0],"STDIN"); + fstrcpy(tok[0],"STDIN"); buf->size = atoi(tok[1]); StrnCpy(buf->file,tok[0],sizeof(buf->file)-1); @@ -674,7 +674,7 @@ dcslw-897 tridge 4712 Dec 20 10:30:30 being held ****************************************************************************/ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first) { - string tok[9]; + fstring tok[9]; int count=0; char *p; @@ -694,7 +694,7 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first) /* if the user contains a ! then trim the first part of it */ if ((p=strchr(tok[2],'!'))) { - string tmp; + fstring tmp; fstrcpy(tmp,p+1); fstrcpy(tok[2],tmp); } @@ -727,7 +727,7 @@ Printer: txt (ready) ****************************************************************************/ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first) { - string tok[7]; + fstring tok[7]; int count=0; DEBUG(0,("antes [%s]\n", line)); @@ -756,7 +756,7 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first) /* only take the last part of the filename */ { - string tmp; + fstring tmp; char *p = strrchr(tok[6],'/'); if (p) { @@ -792,7 +792,7 @@ Local Printer 'lp2' (fjall): ****************************************************************************/ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first) { - string tok[11]; + fstring tok[11]; int count=0; /* handle the case of "(standard input)" as a filename */ @@ -816,11 +816,11 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first) /* if the fname contains a space then use STDIN */ if (strchr(tok[6],' ')) - strcpy(tok[6],"STDIN"); + fstrcpy(tok[6],"STDIN"); /* only take the last part of the filename */ { - string tmp; + fstring tmp; char *p = strrchr(tok[6],'/'); if (p) { @@ -862,7 +862,7 @@ Total: 21268 bytes in queue ****************************************************************************/ static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first) { - string tok[10]; + fstring tok[10]; int count=0; /* mung all the ":"s to spaces*/ @@ -1081,7 +1081,7 @@ int get_printqueue(int snum,int cnum,print_queue_struct **queue, } if (status) { - strcpy(status->message,""); + fstrcpy(status->message,""); status->status = LPSTAT_OK; } @@ -1142,7 +1142,7 @@ void del_printqueue(int cnum,int snum,int jobid) return; } - sprintf(jobstr,"%d",jobid); + slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid); pstrcpy(syscmd,lprm_command); string_sub(syscmd,"%p",printername); @@ -1180,7 +1180,7 @@ void status_printjob(int cnum,int snum,int jobid,int status) return; } - sprintf(jobstr,"%d",jobid); + slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid); pstrcpy(syscmd,lpstatus_command); string_sub(syscmd,"%p",printername); -- cgit From 35c65576f71bb95f1bda5909c3a3cf32665a0dd4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 21 May 1998 23:50:16 +0000 Subject: printing.c: Fixed overflow by one problem in LPRng. reply.c: Fixed password length modifiers to always be done is none-encrypted mode used. This fixes Samba for people who are using non-encrypted passwords with security=server. Jeremy. (This used to be commit 720b565349e3467bd81d6d863b9ac54237edd3cf) --- source3/printing/printing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 1ffe9d00a9..2b9c0c7199 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -286,12 +286,12 @@ static time_t LPRng_time(fstring tok[],int pos) { time_t jobtime; struct tm *t; - char tmp_time[9]; + fstring tmp_time; jobtime = time(NULL); /* default case: take current time */ t = localtime(&jobtime); t->tm_hour = atoi(tok[pos]); - StrnCpy(tmp_time,tok[pos],sizeof(tmp_time)); + fstrcpy(tmp_time,tok[pos]); t->tm_min = atoi(tmp_time+3); t->tm_sec = atoi(tmp_time+6); jobtime = mktime(t); -- cgit From f1cd3cb54c6495db2a91c473f91c78d24622d98e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 16 Jul 1998 00:06:29 +0000 Subject: Makefile: Added CC=gcc to DGUX on Intel. Comment from ross@filmworks.com. ipc.c: loadparm.c: printing.c: Added code from to implement print queue pausing. New parameters are "queuepause command" and "queueresume command". util.c: Added fix for mount options in autmount map. lib/rpc/include/rpc_misc.h: Removed duplicate pipe names for Jean-Francois. Jeremy. (This used to be commit 559a9bf2bbdeae3e76ba9178779cd3a9537c4e91) --- source3/printing/printing.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 2b9c0c7199..6fa7091677 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1213,3 +1213,36 @@ void printjob_decode(int jobid, int *snum, int *job) (*snum) = (jobid >> 8) & 0xFF; (*job) = jobid & 0xFF; } + +/**************************************************************************** + Change status of a printer queue +****************************************************************************/ + +void status_printqueue(int cnum,int snum,int status) +{ + char *queuestatus_command = (status==LPSTAT_STOPPED ? + lp_queuepausecommand(snum):lp_queueresumecommand(snum)); + char *printername = PRINTERNAME(snum); + pstring syscmd; + int ret; + + if (!printername || !*printername) { + DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n", + lp_servicename(snum),snum)); + printername = lp_servicename(snum); + } + + if (!queuestatus_command || !(*queuestatus_command)) { + DEBUG(5,("No queuestatus command to %s job\n", + (status==LPSTAT_STOPPED?"pause":"resume"))); + return; + } + + pstrcpy(syscmd,queuestatus_command); + string_sub(syscmd,"%p",printername); + standard_sub(cnum,syscmd); + + ret = smbrun(syscmd,NULL,False); + DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); + lpq_reset(snum); /* queue has changed */ +} -- cgit From b9623ab59e813131b1ed3f51616a46e719d59c21 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 Aug 1998 17:38:29 +0000 Subject: this is the bug change to using connection_struct* instead of cnum. Connections[] is now a local array in server.c I might have broken something with this change. In particular the oplock code is suspect and some .dll files aren't being oplocked when I expected them to be. I'll look at it after I've got some sleep. (This used to be commit c7ee025ead4a85b6fa44a832047b878451845fb6) --- source3/printing/printing.c | 337 ++++++++++++++++++++++++-------------------- 1 file changed, 186 insertions(+), 151 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 6fa7091677..00ff869278 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -21,8 +21,6 @@ #include "includes.h" extern int DEBUGLEVEL; -extern connection_struct Connections[]; -extern files_struct Files[]; static BOOL * lpq_cache_reset=NULL; @@ -51,92 +49,84 @@ Build the print command in the supplied buffer. This means getting the print command for the service and inserting the printer name and the print file name. Return NULL on error, else the passed buffer pointer. ****************************************************************************/ -static char *build_print_command(int cnum, char *command, char *syscmd, char *filename1) +static char *build_print_command(connection_struct *conn, + char *command, + char *syscmd, char *filename1) { - int snum = SNUM(cnum); - char *tstr; - pstring filename; + int snum = SNUM(conn); + char *tstr; + pstring filename; - /* get the print command for the service. */ - tstr = command; - if (!syscmd || !tstr) { - DEBUG(0,("No print command for service `%s'\n", SERVICE(snum))); - return (NULL); - } + /* get the print command for the service. */ + tstr = command; + if (!syscmd || !tstr) { + DEBUG(0,("No print command for service `%s'\n", + SERVICE(snum))); + return (NULL); + } - /* copy the command into the buffer for extensive meddling. */ - StrnCpy(syscmd, tstr, sizeof(pstring) - 1); + /* copy the command into the buffer for extensive meddling. */ + StrnCpy(syscmd, tstr, sizeof(pstring) - 1); - /* look for "%s" in the string. If there is no %s, we cannot print. */ - if (!strstr(syscmd, "%s") && !strstr(syscmd, "%f")) { - DEBUG(2,("WARNING! No placeholder for the filename in the print command for service %s!\n", SERVICE(snum))); - } + /* look for "%s" in the string. If there is no %s, we cannot print. */ + if (!strstr(syscmd, "%s") && !strstr(syscmd, "%f")) { + DEBUG(2,("WARNING! No placeholder for the filename in the print command for service %s!\n", SERVICE(snum))); + } - if (strstr(syscmd,"%s")) { - int iOffset = PTR_DIFF(strstr(syscmd, "%s"),syscmd); + if (strstr(syscmd,"%s")) { + pstrcpy(filename,filename1); - /* construct the full path for the filename, shouldn't be necessary unless - the subshell causes a "cd" to be executed. - Only use the full path if there isn't a / preceding the %s */ - if (iOffset==0 || syscmd[iOffset-1] != '/') { - StrnCpy(filename,Connections[cnum].connectpath,sizeof(filename)-1); - trim_string(filename,"","/"); - pstrcat(filename,"/"); - pstrcat(filename,filename1); - } - else - pstrcpy(filename,filename1); - - string_sub(syscmd, "%s", filename); - } + string_sub(syscmd, "%s", filename); + } - string_sub(syscmd, "%f", filename1); + string_sub(syscmd, "%f", filename1); - /* Does the service have a printername? If not, make a fake and empty */ - /* printer name. That way a %p is treated sanely if no printer */ - /* name was specified to replace it. This eventuality is logged. */ - tstr = PRINTERNAME(snum); - if (tstr == NULL || tstr[0] == '\0') { - DEBUG(3,( "No printer name - using %s.\n", SERVICE(snum))); - tstr = SERVICE(snum); - } + /* Does the service have a printername? If not, make a fake + and empty */ + /* printer name. That way a %p is treated sanely if no printer */ + /* name was specified to replace it. This eventuality is logged. */ + tstr = PRINTERNAME(snum); + if (tstr == NULL || tstr[0] == '\0') { + DEBUG(3,( "No printer name - using %s.\n", SERVICE(snum))); + tstr = SERVICE(snum); + } - string_sub(syscmd, "%p", tstr); + string_sub(syscmd, "%p", tstr); - standard_sub(cnum,syscmd); + standard_sub(conn,syscmd); - return (syscmd); + return (syscmd); } /**************************************************************************** print a file - called on closing the file ****************************************************************************/ -void print_file(int fnum) +void print_file(connection_struct *conn, files_struct *file) { - pstring syscmd; - int cnum = Files[fnum].cnum; - int snum=SNUM(cnum); - char *tempstr; + pstring syscmd; + int snum = SNUM(conn); + char *tempstr; - *syscmd = 0; + *syscmd = 0; - if (file_size(Files[fnum].name) <= 0) { - DEBUG(3,("Discarding null print job %s\n",Files[fnum].name)); - sys_unlink(Files[fnum].name); - return; - } + if (file_size(file->fsp_name) <= 0) { + DEBUG(3,("Discarding null print job %s\n",file->fsp_name)); + sys_unlink(file->fsp_name); + return; + } - tempstr = build_print_command(cnum, PRINTCOMMAND(snum), syscmd, Files[fnum].name); - if (tempstr != NULL) - { - int ret = smbrun(syscmd,NULL,False); - DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); - } - else - DEBUG(0,("Null print command?\n")); + tempstr = build_print_command(conn, + PRINTCOMMAND(snum), + syscmd, file->fsp_name); + if (tempstr != NULL) { + int ret = smbrun(syscmd,NULL,False); + DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); + } else { + DEBUG(0,("Null print command?\n")); + } - lpq_reset(snum); + lpq_reset(snum); } static char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", @@ -1023,105 +1013,102 @@ static BOOL parse_lpq_entry(int snum,char *line, /**************************************************************************** get a printer queue ****************************************************************************/ -int get_printqueue(int snum,int cnum,print_queue_struct **queue, +int get_printqueue(int snum, + connection_struct *conn,print_queue_struct **queue, print_status_struct *status) { - char *lpq_command = lp_lpqcommand(snum); - char *printername = PRINTERNAME(snum); - int ret=0,count=0; - pstring syscmd; - fstring outfile; - pstring line; - FILE *f; - struct stat sbuf; - BOOL dorun=True; - int cachetime = lp_lpqcachetime(); - - *line = 0; - check_lpq_cache(snum); - - if (!printername || !*printername) - { - DEBUG(6,("xx replacing printer name with service (snum=(%s,%d))\n", - lp_servicename(snum),snum)); - printername = lp_servicename(snum); - } + char *lpq_command = lp_lpqcommand(snum); + char *printername = PRINTERNAME(snum); + int ret=0,count=0; + pstring syscmd; + fstring outfile; + pstring line; + FILE *f; + struct stat sbuf; + BOOL dorun=True; + int cachetime = lp_lpqcachetime(); + + *line = 0; + check_lpq_cache(snum); + + if (!printername || !*printername) { + DEBUG(6,("xx replacing printer name with service (snum=(%s,%d))\n", + lp_servicename(snum),snum)); + printername = lp_servicename(snum); + } - if (!lpq_command || !(*lpq_command)) - { - DEBUG(5,("No lpq command\n")); - return(0); - } + if (!lpq_command || !(*lpq_command)) { + DEBUG(5,("No lpq command\n")); + return(0); + } - pstrcpy(syscmd,lpq_command); - string_sub(syscmd,"%p",printername); + pstrcpy(syscmd,lpq_command); + string_sub(syscmd,"%p",printername); - standard_sub(cnum,syscmd); + standard_sub(conn,syscmd); - slprintf(outfile,sizeof(outfile)-1, "%s/lpq.%08x",tmpdir(),str_checksum(syscmd)); + slprintf(outfile,sizeof(outfile)-1, "%s/lpq.%08x",tmpdir(),str_checksum(syscmd)); - if (!lpq_cache_reset[snum] && cachetime && !stat(outfile,&sbuf)) - { - if (time(NULL) - sbuf.st_mtime < cachetime) { - DEBUG(3,("Using cached lpq output\n")); - dorun = False; - } - } - - if (dorun) { - ret = smbrun(syscmd,outfile,True); - DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); - } - - lpq_cache_reset[snum] = False; + if (!lpq_cache_reset[snum] && cachetime && !stat(outfile,&sbuf)) { + if (time(NULL) - sbuf.st_mtime < cachetime) { + DEBUG(3,("Using cached lpq output\n")); + dorun = False; + } + } - f = fopen(outfile,"r"); - if (!f) { - return(0); - } + if (dorun) { + ret = smbrun(syscmd,outfile,True); + DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); + } - if (status) { - fstrcpy(status->message,""); - status->status = LPSTAT_OK; - } - - while (fgets(line,sizeof(pstring),f)) - { - DEBUG(6,("QUEUE2: %s\n",line)); + lpq_cache_reset[snum] = False; - *queue = Realloc(*queue,sizeof(print_queue_struct)*(count+1)); - if (! *queue) - { - count = 0; - break; + f = fopen(outfile,"r"); + if (!f) { + return(0); } - bzero((char *)&(*queue)[count],sizeof(**queue)); - - /* parse it */ - if (!parse_lpq_entry(snum,line,&(*queue)[count],status,count==0)) - continue; + if (status) { + fstrcpy(status->message,""); + status->status = LPSTAT_OK; + } + + while (fgets(line,sizeof(pstring),f)) { + DEBUG(6,("QUEUE2: %s\n",line)); + + *queue = Realloc(*queue,sizeof(print_queue_struct)*(count+1)); + if (! *queue) { + count = 0; + break; + } + + bzero((char *)&(*queue)[count],sizeof(**queue)); - count++; - } - - fclose(f); - - if (!cachetime) { - unlink(outfile); - } else { - /* we only expect this to succeed on trapdoor systems, on normal systems - the file is owned by root */ - chmod(outfile,0666); - } - return(count); + /* parse it */ + if (!parse_lpq_entry(snum,line, + &(*queue)[count],status,count==0)) + continue; + + count++; + } + + fclose(f); + + if (!cachetime) { + unlink(outfile); + } else { + /* we only expect this to succeed on trapdoor systems, + on normal systems the file is owned by root */ + chmod(outfile,0666); + } + return(count); } /**************************************************************************** delete a printer queue entry ****************************************************************************/ -void del_printqueue(int cnum,int snum,int jobid) +void del_printqueue(connection_struct *conn,int snum,int jobid) { char *lprm_command = lp_lprmcommand(snum); char *printername = PRINTERNAME(snum); @@ -1147,7 +1134,7 @@ void del_printqueue(int cnum,int snum,int jobid) pstrcpy(syscmd,lprm_command); string_sub(syscmd,"%p",printername); string_sub(syscmd,"%j",jobstr); - standard_sub(cnum,syscmd); + standard_sub(conn,syscmd); ret = smbrun(syscmd,NULL,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); @@ -1157,7 +1144,7 @@ void del_printqueue(int cnum,int snum,int jobid) /**************************************************************************** change status of a printer queue entry ****************************************************************************/ -void status_printjob(int cnum,int snum,int jobid,int status) +void status_printjob(connection_struct *conn,int snum,int jobid,int status) { char *lpstatus_command = (status==LPQ_PAUSED?lp_lppausecommand(snum):lp_lpresumecommand(snum)); @@ -1185,7 +1172,7 @@ void status_printjob(int cnum,int snum,int jobid,int status) pstrcpy(syscmd,lpstatus_command); string_sub(syscmd,"%p",printername); string_sub(syscmd,"%j",jobstr); - standard_sub(cnum,syscmd); + standard_sub(conn,syscmd); ret = smbrun(syscmd,NULL,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); @@ -1218,7 +1205,7 @@ void printjob_decode(int jobid, int *snum, int *job) Change status of a printer queue ****************************************************************************/ -void status_printqueue(int cnum,int snum,int status) +void status_printqueue(connection_struct *conn,int snum,int status) { char *queuestatus_command = (status==LPSTAT_STOPPED ? lp_queuepausecommand(snum):lp_queueresumecommand(snum)); @@ -1240,9 +1227,57 @@ void status_printqueue(int cnum,int snum,int status) pstrcpy(syscmd,queuestatus_command); string_sub(syscmd,"%p",printername); - standard_sub(cnum,syscmd); + standard_sub(conn,syscmd); ret = smbrun(syscmd,NULL,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); lpq_reset(snum); /* queue has changed */ } + + + +/*************************************************************************** +auto-load printer services +***************************************************************************/ +static void add_all_printers(void) +{ + int printers = lp_servicenumber(PRINTERS_NAME); + + if (printers < 0) return; + + pcap_printer_fn(lp_add_one_printer); +} + +/*************************************************************************** +auto-load some homes and printer services +***************************************************************************/ +static void add_auto_printers(void) +{ + char *p; + int printers; + char *str = lp_auto_services(); + + if (!str) return; + + printers = lp_servicenumber(PRINTERS_NAME); + + if (printers < 0) return; + + for (p=strtok(str,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) { + if (lp_servicenumber(p) >= 0) continue; + + if (pcap_printername_ok(p,NULL)) { + lp_add_printer(p,printers); + } + } +} + +/*************************************************************************** +load automatic printer services +***************************************************************************/ +void load_printers(void) +{ + add_auto_printers(); + if (lp_load_printers()) + add_all_printers(); +} -- cgit From e13aeea928dd89373cfaf3916c96f853c1227884 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 15 Aug 1998 01:19:26 +0000 Subject: configure: Changes for extra headers. configure.in: Source for header changes. client/clitar.c: Fixed isXXX macros & debugs for gcc pedantic compile. include/config.h.in: Added MEMSET, BZERO, MEMORY, RPCSVC_YPCLNT, STRINGS headers. include/includes.h: Headers for the above. include/smb.h: Made SIGNAL_CAST POSIX by default void (*)(int). lib/access.c: Fixed isXXX macros & debugs for gcc pedantic compile. lib/charset.c: Fixed isXXX macros & debugs for gcc pedantic compile. lib/debug.c: Fixed signal functs. lib/kanji.c: Fixed isXXX macros & debugs for gcc pedantic compile. lib/smbrun.c: Fixed isXXX macros & debugs for gcc pedantic compile. lib/util.c: Fixed isXXX macros & debugs for gcc pedantic compile. libsmb/namequery.c: Fixed isXXX macros & debugs for gcc pedantic compile. locking/shmem.c: Fixed isXXX macros & debugs for gcc pedantic compile. locking/shmem_sysv.c: Fixed error messages in sysV stuff. nmbd/asyncdns.c: Fixed signal functs. nmbd/nmbd.c: Fixed isXXX macros & debugs for gcc pedantic compile. passdb/passdb.c: Fixed isXXX macros & debugs for gcc pedantic compile. passdb/smbpassfile.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/chgpasswd.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/ipc.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/nttrans.c: Fixed fsp code path. smbd/password.c: fixed HAVE_YP_GET_DEFAULT_DOMAIN problem. smbd/printing.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/reply.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/server.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/trans2.c: Fixed core dump bug. smbd/uid.c: Fixed isXXX macros & debugs for gcc pedantic compile. Jeremy. (This used to be commit 1b9cbcd02e575dc0a95fa589f720df30a4acc46b) --- source3/printing/printing.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 00ff869278..2c7197f9db 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -235,7 +235,7 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) return(False); /* the Job and Total columns must be integer */ - if (!isdigit(*tok[JOBTOK]) || !isdigit(*tok[TOTALTOK])) return(False); + if (!isdigit((int)*tok[JOBTOK]) || !isdigit((int)*tok[TOTALTOK])) return(False); /* if the fname contains a space then use STDIN */ if (strchr(tok[FILETOK],' ')) @@ -405,7 +405,7 @@ A long spool-path will just waste significant chars of the file name. return(False); /* the Job and Total columns must be integer */ - if (!isdigit(*tok[LPRNG_JOBTOK]) || !isdigit(*tok[LPRNG_TOTALTOK])) return(False); + if (!isdigit((int)*tok[LPRNG_JOBTOK]) || !isdigit((int)*tok[LPRNG_TOTALTOK])) return(False); /* if the fname contains a space then use STDIN */ /* I do not understand how this would be possible. Magnus. */ @@ -479,7 +479,7 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) if ((count == 7) && ((strcmp(tok[0],"QUEUED") == 0) || (strcmp(tok[0],"HELD") == 0))) { /* the 2nd and 5th columns must be integer */ - if (!isdigit(*tok[1]) || !isdigit(*tok[4])) return(False); + if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4])) return(False); buf->size = atoi(tok[4]) * 1024; /* if the fname contains a space then use STDIN */ if (strchr(tok[2],' ')) @@ -513,7 +513,7 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) else { /* the 4th and 9th columns must be integer */ - if (!isdigit(*tok[3]) || !isdigit(*tok[8])) return(False); + if (!isdigit((int)*tok[3]) || !isdigit((int)*tok[8])) return(False); buf->size = atoi(tok[8]) * 1024; /* if the fname contains a space then use STDIN */ if (strchr(tok[4],' ')) @@ -590,7 +590,7 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first) if (count < 2) return(False); /* the 2nd column must be integer */ - if (!isdigit(*tok[1])) return(False); + if (!isdigit((int)*tok[1])) return(False); /* if the fname contains a space then use STDIN */ if (strchr(tok[0],' ')) @@ -628,7 +628,7 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first) /* first token must be printer name (cannot check ?) */ /* the 2nd, 5th & 7th column must be integer */ - if (!isdigit(*tok[1]) || !isdigit(*tok[4]) || !isdigit(*tok[6])) return(False); + if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4]) || !isdigit((int)*tok[6])) return(False); jobid = atoi(tok[1]); StrnCpy(jobuser,tok[2],sizeof(buf->user)-1); jobprio = atoi(tok[4]); @@ -678,8 +678,8 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first) return(False); /* the 2nd and 4th, 6th columns must be integer */ - if (!isdigit(*tok[1]) || !isdigit(*tok[3])) return(False); - if (!isdigit(*tok[5])) return(False); + if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[3])) return(False); + if (!isdigit((int)*tok[5])) return(False); /* if the user contains a ! then trim the first part of it */ if ((p=strchr(tok[2],'!'))) @@ -742,7 +742,7 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first) return(False); /* the 3rd and 5th columns must be integer */ - if (!isdigit(*tok[2]) || !isdigit(*tok[4])) return(False); + if (!isdigit((int)*tok[2]) || !isdigit((int)*tok[4])) return(False); /* only take the last part of the filename */ { @@ -797,11 +797,11 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first) return(False); /* the first must be "active" or begin with an integer */ - if (strcmp(tok[0],"active") && !isdigit(tok[0][0])) + if (strcmp(tok[0],"active") && !isdigit((int)tok[0][0])) return(False); /* the 5th and 8th must be integer */ - if (!isdigit(*tok[4]) || !isdigit(*tok[7])) + if (!isdigit((int)*tok[4]) || !isdigit((int)*tok[7])) return(False); /* if the fname contains a space then use STDIN */ @@ -865,20 +865,20 @@ static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first) return(False); /* the 1st and 7th columns must be integer */ - if (!isdigit(*tok[0]) || !isdigit(*tok[6])) return(False); + if (!isdigit((int)*tok[0]) || !isdigit((int)*tok[6])) return(False); /* if the 2nd column is either '>' or 'H' then the 7th and 8th must be * integer, else it's the 6th and 7th that must be */ if (*tok[1] == 'H' || *tok[1] == '>') { - if (!isdigit(*tok[7])) + if (!isdigit((int)*tok[7])) return(False); buf->status = *tok[1] == '>' ? LPQ_PRINTING : LPQ_PAUSED; count = 1; } else { - if (!isdigit(*tok[5])) + if (!isdigit((int)*tok[5])) return(False); buf->status = LPQ_QUEUED; count = 0; -- cgit From 61b5fd6f32e9ccb612df1354a3e3b3bed5f2b808 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Aug 1998 03:11:42 +0000 Subject: bounds check next_token() to prevent possible buffer overflows (This used to be commit 3eade55dc7c842bdc50205c330802d211fae54d3) --- source3/printing/printing.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 2c7197f9db..fae4c1cc05 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -228,7 +228,10 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) string_sub(line,"(","\""); string_sub(line,")","\""); - for (count=0; count Date: Tue, 1 Sep 1998 20:11:54 +0000 Subject: More abstraction of file system data types, to move to a 64 bit file interface for the NT SMB's. Created a new define, SMB_STRUCT_STAT that currently is defined to be struct stat - this wil change to a user defined type containing 64 bit info when the correct wrappers are written for 64 bit stat(), fstat() and lstat() calls. Also changed all sys_xxxx() calls that were previously just wrappers to the same call prefixed by a dos_to_unix() call into dos_xxxx() calls. This makes it explicit when a pathname translation is being done, and when it is not. Now, all sys_xxx() calls are meant to be wrappers to mask OS differences, and not silently converting filenames on the fly. Jeremy. (This used to be commit 28aa182dbffaa4ffd86047e608400de4b26e80eb) --- source3/printing/printing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index fae4c1cc05..45a9515b51 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -112,7 +112,7 @@ void print_file(connection_struct *conn, files_struct *file) if (file_size(file->fsp_name) <= 0) { DEBUG(3,("Discarding null print job %s\n",file->fsp_name)); - sys_unlink(file->fsp_name); + dos_unlink(file->fsp_name); return; } @@ -1033,7 +1033,7 @@ int get_printqueue(int snum, fstring outfile; pstring line; FILE *f; - struct stat sbuf; + SMB_STRUCT_STAT sbuf; BOOL dorun=True; int cachetime = lp_lpqcachetime(); -- cgit From 7bb86c1b132bce31a006ea9768a54db7a45fe1a5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Sep 1998 18:40:31 +0000 Subject: Ok - this is the 64 bit widening check in. It changes the configure to check for stat64 and friends, and then changes much of Samba to use the data type SMB_OFF_T for file size information. stat/fstat/lstat/lseek/ftruncate have now become sys_stat etc. to hide the 64 bit calls if needed. Note that this still does not expose 64 bit functionality to the client, as the changes to the reply_xxx smb's are not yet done. This code change should make these changes possible. Still to do before full 64 bit-ness to the client: fcntl lock code. statfs code widening of dev_t and ino_t (now possible due to SMB_DEV_T and SMB_OFF_T types being in place). Let me know if wierd things happen after this check-in and I'll fix them :-). Jeremy. (This used to be commit 14500936c321d15995c963766aac67bf1f4e3824) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 45a9515b51..a7f832b593 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1058,7 +1058,7 @@ int get_printqueue(int snum, slprintf(outfile,sizeof(outfile)-1, "%s/lpq.%08x",tmpdir(),str_checksum(syscmd)); - if (!lpq_cache_reset[snum] && cachetime && !stat(outfile,&sbuf)) { + if (!lpq_cache_reset[snum] && cachetime && !sys_stat(outfile,&sbuf)) { if (time(NULL) - sbuf.st_mtime < cachetime) { DEBUG(3,("Using cached lpq output\n")); dorun = False; -- cgit From 7be02a20373a72789c5ecb254eeb62abdb9585fe Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 18 Sep 1998 18:16:45 +0000 Subject: Changed variable TAB to htab as TAB is defined in a header file on RedHat5.1 Jeremy. (This used to be commit 43ac52ad7a3c1da3c25a63d0458c87f9367453ec) --- source3/printing/printing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index a7f832b593..4df965204a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -577,12 +577,12 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first) static int base_prio; int count; - char TAB = '\011'; + char htab = '\011'; fstring tok[12]; /* If a line begins with a horizontal TAB, it is a subline type */ - if (line[0] == TAB) { /* subline */ + if (line[0] == htab) { /* subline */ /* check if it contains the base priority */ if (!strncmp(line,"\tfence priority : ",18)) { base_prio=atoi(&line[18]); -- cgit From 01e04614c7c466fdbdc398c782acaa931965f925 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 3 Nov 1998 02:25:28 +0000 Subject: Makefile.in configure configure.in include/proto.h smbd/noquotas.c smbd/quotas.c: Added quotas patch for autoconf from Dejan Ilic . printing/printing.c: Filenames with spaces patch from Allan Bjorklund utils/nmblookup.c: Fix usage() function. smbd/reply.c: Split out the security=server and security=domain checks into check_server_security() and check_domain_security() to aid the writing of the 'hack' appliance mode invented by John Schimmel. Jeremy. (This used to be commit f09ab9b52251087a58af92ec753537ca34a970fc) --- source3/printing/printing.c | 282 +++++++++++++++++--------------------------- 1 file changed, 106 insertions(+), 176 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 4df965204a..ddc0f70d18 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -193,6 +193,11 @@ here is an example of lpq output under osf/1 Warning: no daemon present Rank Pri Owner Job Files Total Size 1st 0 tridge 148 README 8096 bytes + + + June 30, 1998. +Modified to handle file names with spaces, like the parse_lpq_lprng code +further below. ****************************************************************************/ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) { @@ -202,19 +207,21 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) #define USERTOK 2 #define JOBTOK 3 #define FILETOK 4 -#define TOTALTOK 5 +#define TOTALTOK (count - 1) #define NTOK 6 +#define MAXTOK 128 #else /* OSF1 */ #define RANKTOK 0 #define USERTOK 1 #define JOBTOK 2 #define FILETOK 3 -#define TOTALTOK 4 +#define TOTALTOK (count - 1) #define NTOK 5 +#define MAXTOK 128 #endif /* OSF1 */ - fstring tok[NTOK]; - int count=0; + char *tok[MAXTOK]; + int count = 0; #ifdef OSF1 int length; @@ -223,38 +230,19 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) return(False); #endif /* OSF1 */ - /* handle the case of "(standard input)" as a filename */ - string_sub(line,"standard input","STDIN"); - string_sub(line,"(","\""); - string_sub(line,")","\""); - - for (count=0; - countjob = atoi(tok[JOBTOK]); buf->size = atoi(tok[TOTALTOK]); @@ -262,6 +250,23 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) buf->time = time(NULL); StrnCpy(buf->user,tok[USERTOK],sizeof(buf->user)-1); StrnCpy(buf->file,tok[FILETOK],sizeof(buf->file)-1); + + if ((FILETOK + 1) != TOTALTOK) { + int bufsize; + int i; + + bufsize = sizeof(buf->file) - strlen(buf->file) - 1; + + for (i = (FILETOK + 1); i < TOTALTOK; i++) { + strncat(buf->file," ",bufsize); + strncat(buf->file,tok[i],bufsize - 1); + bufsize = sizeof(buf->file) - strlen(buf->file) - 1; + if (bufsize <= 0) { + break; + } + } + } + #ifdef PRIOTOK buf->priority = atoi(tok[PRIOTOK]); #else @@ -274,19 +279,20 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) LPRng_time modifies the current date by inserting the hour and minute from the lpq output. The lpq time looks like "23:15:07" + + June 30, 1998. +Modified to work with the re-written parse_lpq_lprng routine. */ -static time_t LPRng_time(fstring tok[],int pos) +static time_t LPRng_time(char *time_string) { time_t jobtime; struct tm *t; - fstring tmp_time; jobtime = time(NULL); /* default case: take current time */ t = localtime(&jobtime); - t->tm_hour = atoi(tok[pos]); - fstrcpy(tmp_time,tok[pos]); - t->tm_min = atoi(tmp_time+3); - t->tm_sec = atoi(tmp_time+6); + t->tm_hour = atoi(time_string); + t->tm_min = atoi(time_string+3); + t->tm_sec = atoi(time_string+6); jobtime = mktime(t); return jobtime; @@ -294,162 +300,86 @@ static time_t LPRng_time(fstring tok[],int pos) /**************************************************************************** - parse a lpq line - - Most of the code is directly reused from parse_lpq_bsd() - -here are two examples of lpq output under lprng (LPRng-2.3.0) - -Printer: humprn@hum-fak - Queue: 1 printable job - Server: pid 4840 active, Unspooler: pid 4841 active - Status: job 'cfA659hum-fak', closing device at Fri Jun 21 10:10:21 1996 - Rank Owner Class Job Files Size Time -active magnus@hum-fak A 659 /var/spool/smb/Notesblok-ikke-na4024 10:03:31 - -Printer: humprn@hum-fak (printing disabled) - Queue: 1 printable job - Warning: no server present - Status: finished operations at Fri Jun 21 10:10:32 1996 - Rank Owner Class Job Files Size Time -1 magnus@hum-fak A 387 /var/spool/smb/netbudget.xls 21230 10:50:53 - -****************************************************************************** - -NEW FOR LPRng-3.3.5 ! - - -This will not happen anymore: with LPRng-3.3.5 there is always a blank between -the filename and the size, and the format has changed: - -Printer: lj6@lizard 'HP LaserJet 6P' - Queue: 2 printable jobs - Server: pid 11941 active - Unspooler: pid 11942 active - Status: printed all 1818 bytes at 19:49:59 - Rank Owner/ID Class Job Files Size Time -active root@lizard+937 A 937 (stdin) 1818 19:49:58 -2 root@lizard+969 A 969 junk.txt 2170 19:50:12 - + parse a lprng lpq line + June 30, 1998. + Re-wrote this to handle file names with spaces, multiple file names on one + lpq line, etc; ****************************************************************************/ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first) { -#define LPRNG_RANKTOK 0 -#define LPRNG_USERTOK 1 -#define LPRNG_PRIOTOK 2 -#define LPRNG_JOBTOK 3 -#define LPRNG_FILETOK 4 -#define LPRNG_TOTALTOK 5 -#define LPRNG_TIMETOK 6 -#define LPRNG_NTOK 7 +#define LPRNG_RANKTOK 0 +#define LPRNG_USERTOK 1 +#define LPRNG_PRIOTOK 2 +#define LPRNG_JOBTOK 3 +#define LPRNG_FILETOK 4 +#define LPRNG_TOTALTOK (num_tok - 2) +#define LPRNG_TIMETOK (num_tok - 1) +#define LPRNG_NTOK 7 +#define LPRNG_MAXTOK 128 /* PFMA just to keep us from running away. */ + + char *tokarr[LPRNG_MAXTOK]; + char *cptr; + int num_tok = 0; + + tokarr[0] = strtok(line," \t"); + num_tok++; + while (((tokarr[num_tok] = strtok(NULL," \t")) != NULL) + && (num_tok < LPRNG_MAXTOK)) { + num_tok++; + } -/**************************************************************************** -From lpd_status.c in LPRng source. -0 1 2 3 4 5 6 7 -12345678901234567890123456789012345678901234567890123456789012345678901234 -" Rank Owner Class Job Files Size Time" - plp_snprintf( msg, sizeof(msg), "%-6s %-19s %c %03d %-32s", - number, line, priority, cfp->number, error ); - plp_snprintf( msg + len, sizeof(msg)-len, "%4d", - cfp->jobsize ); - plp_snprintf( msg+len, sizeof(msg)-len, " %s", - Time_str( 1, cfp->statb.st_ctime ) ); -****************************************************************************/ - /* The following define's are to be able to adjust the values if the -LPRng source changes. This is from version 2.3.0. Magnus */ -#define SPACE_W 1 -#define RANK_W 6 -#define OWNER_W 19 -#define CLASS_W 1 -#define JOB_W 3 -#define FILE_W 32 -/* The JOBSIZE_W is too small for big jobs, so time is pushed to the right */ -#define JOBSIZE_W 4 - -#define RANK_POS 0 -#define OWNER_POS RANK_POS+RANK_W+SPACE_W -#define CLASS_POS OWNER_POS+OWNER_W+SPACE_W -#define JOB_POS CLASS_POS+CLASS_W+SPACE_W -#define FILE_POS JOB_POS+JOB_W+SPACE_W -#define JOBSIZE_POS FILE_POS+FILE_W + /* We must get at least LPRNG_NTOK tokens. */ + if (num_tok < LPRNG_NTOK) { + return(False); + } - - fstring tok[LPRNG_NTOK]; - int count=0; + if (!isdigit(*tokarr[LPRNG_JOBTOK]) || !isdigit(*tokarr[LPRNG_TOTALTOK])) { + return(False); + } -#ifdef OLD_LPRNG -/* We only need this bugfix for older versions of lprng - current - information is that version 3.3.5 must not have this line - in order to work correctly. -*/ + buf->job = atoi(tokarr[LPRNG_JOBTOK]); + buf->size = atoi(tokarr[LPRNG_TOTALTOK]); -/* -Need to insert one space in front of the size, to be able to use -next_token() unchanged. I would have liked to be able to insert a -space instead, to prevent losing that one char, but perl has spoiled -me :-\ So I did it the easiest way. + if (strequal(tokarr[LPRNG_RANKTOK],"active")) { + buf->status = LPQ_PRINTING; + } else if (isdigit(*tokarr[LPRNG_RANKTOK])) { + buf->status = LPQ_QUEUED; + } else { + buf->status = LPQ_PAUSED; + } -HINT: Use as short a path as possible for the samba spool directory. -A long spool-path will just waste significant chars of the file name. -*/ + buf->priority = *tokarr[LPRNG_PRIOTOK] -'A'; - line[JOBSIZE_POS-1]=' '; -#endif /* OLD_LPRNG */ + buf->time = LPRng_time(tokarr[LPRNG_TIMETOK]); - /* handle the case of "(stdin)" as a filename */ - string_sub(line,"stdin","STDIN"); - string_sub(line,"(","\""); - string_sub(line,")","\""); - - for (count=0; - countuser,tokarr[LPRNG_USERTOK],sizeof(buf->user)-1); - /* we must get LPRNG_NTOK tokens */ - if (count < LPRNG_NTOK) - return(False); + /* The '@hostname' prevents windows from displaying the printing icon + * for the current user on the taskbar. Plop in a null. + */ - /* the Job and Total columns must be integer */ - if (!isdigit((int)*tok[LPRNG_JOBTOK]) || !isdigit((int)*tok[LPRNG_TOTALTOK])) return(False); + if ((cptr = strchr(buf->user,'@')) != NULL) { + *cptr = '\0'; + } - /* if the fname contains a space then use STDIN */ - /* I do not understand how this would be possible. Magnus. */ - if (strchr(tok[LPRNG_FILETOK],' ')) - fstrcpy(tok[LPRNG_FILETOK],"STDIN"); + StrnCpy(buf->file,tokarr[LPRNG_FILETOK],sizeof(buf->file)-1); - /* only take the last part of the filename */ - { - fstring tmp; - char *p = strrchr(tok[LPRNG_FILETOK],'/'); - if (p) - { - fstrcpy(tmp,p+1); - fstrcpy(tok[LPRNG_FILETOK],tmp); + if ((LPRNG_FILETOK + 1) != LPRNG_TOTALTOK) { + int bufsize; + int i; + + bufsize = sizeof(buf->file) - strlen(buf->file) - 1; + + for (i = (LPRNG_FILETOK + 1); i < LPRNG_TOTALTOK; i++) { + strncat(buf->file," ",bufsize); + strncat(buf->file,tokarr[i],bufsize - 1); + bufsize = sizeof(buf->file) - strlen(buf->file) - 1; + if (bufsize <= 0) { + break; } + } } - - buf->job = atoi(tok[LPRNG_JOBTOK]); - buf->size = atoi(tok[LPRNG_TOTALTOK]); - if (strequal(tok[LPRNG_RANKTOK],"active")) - buf->status = LPQ_PRINTING; - else if (strequal(tok[LPRNG_RANKTOK],"hold")) - buf->status = LPQ_PAUSED; - else - buf->status = LPQ_QUEUED; - /* buf->time = time(NULL); */ - buf->time = LPRng_time(tok,LPRNG_TIMETOK); -DEBUG(3,("Time reported for job %d is %s", buf->job, ctime(&buf->time))); - StrnCpy(buf->user,tok[LPRNG_USERTOK],sizeof(buf->user)-1); - StrnCpy(buf->file,tok[LPRNG_FILETOK],sizeof(buf->file)-1); -#ifdef LPRNG_PRIOTOK - /* Here I try to map the CLASS char to a number, but the number - is never shown in Print Manager under NT anyway... Magnus. */ - buf->priority = atoi(tok[LPRNG_PRIOTOK]-('A'-1)); -#else - buf->priority = 1; -#endif return(True); } -- cgit From e4f974c611c179a5e7827ec8325e01811db6540b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Nov 1998 20:33:37 +0000 Subject: Makefile.in: Removed rpc_server/srv_ldap_helpers.c per J.F.'s instructions. client/client.c: client/clitar.c: include/client.h: smbwrapper/smbw_dir.c: smbwrapper/smbw_stat.c: smbwrapper/smbw.c: lib/util.c: Converted all use of 'mode' to uint16. smbd/quotas.c: Fixed stupid comment bug I put in there :-(. printing/printing.c: Fix from J.F. to new code. Jeremy. (This used to be commit bacd3e9d2036a804e73644a28fc498f229c8446c) --- source3/printing/printing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index ddc0f70d18..faa099c359 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -207,7 +207,7 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) #define USERTOK 2 #define JOBTOK 3 #define FILETOK 4 -#define TOTALTOK (count - 1) +#define TOTALTOK (count - 2) #define NTOK 6 #define MAXTOK 128 #else /* OSF1 */ @@ -215,7 +215,7 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) #define USERTOK 1 #define JOBTOK 2 #define FILETOK 3 -#define TOTALTOK (count - 1) +#define TOTALTOK (count - 2) #define NTOK 5 #define MAXTOK 128 #endif /* OSF1 */ -- cgit From 375e53826c59c33d52009307f757b71a1fe3d589 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 10 Nov 1998 20:51:25 +0000 Subject: include/local.h: include/smb.h: param/loadparm.c: Made GUEST_SESSSETUP run time selectable. Horror of horrors :-). printing/printing.c: Added J.F.'s latest fix. rpc_parse/parse_misc.c: parse_reg.c: rpcclient/cmd_reg.c: rpcclient/display.c: SGI compiler signed/unsigned issues. smbd/reply.c: Made GUEST_SESSSETUP run time selectable. Horror of horrors :-). utils/testparm.c: Added extra test. Jeremy. (This used to be commit 9668a5ef50be2e6b575f9989e87ee2ff8da5ac1d) --- source3/printing/printing.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index faa099c359..2aecb58047 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -222,15 +222,18 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) char *tok[MAXTOK]; int count = 0; + pstring line2; + + pstrcpy(line2,line); #ifdef OSF1 int length; - length = strlen(line); - if (line[length-3] == ':') + length = strlen(line2); + if (line2[length-3] == ':') return(False); #endif /* OSF1 */ - tok[0] = strtok(line," \t"); + tok[0] = strtok(line2," \t"); count++; while (((tok[count] = strtok(NULL," \t")) != NULL) && (count < MAXTOK)) { -- cgit From f9584f93be33ee69912708e6402809f47703a5d5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 11 Nov 1998 23:31:37 +0000 Subject: J.F.'s latest printer fixes plus his gcc -picky fix for web/cgi.c Jeremy. (This used to be commit bd4e2972f50cafd932a5c915cdeeef7eedda07cc) --- source3/printing/printing.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 2aecb58047..09a574c2c9 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -323,8 +323,10 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first) char *tokarr[LPRNG_MAXTOK]; char *cptr; int num_tok = 0; + pstring line2; - tokarr[0] = strtok(line," \t"); + pstrcpy(line2,line); + tokarr[0] = strtok(line2," \t"); num_tok++; while (((tokarr[num_tok] = strtok(NULL," \t")) != NULL) && (num_tok < LPRNG_MAXTOK)) { -- cgit From 609f348217371a87f3a467bde307c3beb3ec27ff Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 12 Nov 1998 19:40:33 +0000 Subject: include/kanji.h include/proto.h lib/kanji.c: Added const parameters in string wrappers. printing/printing.c: Added OSF1 fix. Jeremy. (This used to be commit 9d05d80f811426f83a975d28e64c5d6b10574c25) --- source3/printing/printing.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 09a574c2c9..d779a42ec7 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -227,10 +227,12 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) pstrcpy(line2,line); #ifdef OSF1 - int length; - length = strlen(line2); - if (line2[length-3] == ':') - return(False); + { + size_t length; + length = strlen(line2); + if (line2[length-3] == ':') + return(False); + } #endif /* OSF1 */ tok[0] = strtok(line2," \t"); -- cgit From 768761820e8d7481c586c4e0ab4ac7cb36d18c4b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 17 Nov 1998 20:50:07 +0000 Subject: Added the same open()/fopen()/creat()/mmap() -> sys_XXX calls. Tidied up some of the mess (no other word for it). Still doesn't compile cleanly. There are calls with incorrect parameters that don't seem to be doing the right thing. This code still needs surgery :-(. Jeremy. (This used to be commit 18ff93a9abbf68ee8c59c0af3e57c63e4a015dac) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index d779a42ec7..dfb87dc6fa 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1009,7 +1009,7 @@ int get_printqueue(int snum, lpq_cache_reset[snum] = False; - f = fopen(outfile,"r"); + f = sys_fopen(outfile,"r"); if (!f) { return(0); } -- cgit From 735926877bb8333a9e862657ea89001bea376b9f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 23 Nov 1998 03:46:51 +0000 Subject: replace ' with _ as well (This used to be commit e93491953a2555401a372de74ac2aee0cc44cb88) --- source3/printing/printing.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index dfb87dc6fa..87be54618b 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -411,8 +411,8 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) /* handle the case of "(standard input)" as a filename */ string_sub(line,"standard input","STDIN"); - string_sub(line,"(","\""); - string_sub(line,")","\""); + all_string_sub(line,"(","\""); + all_string_sub(line,")","\""); for (count=0; count<10 && @@ -528,8 +528,8 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first) if (!header_line_ok) return (False); /* incorrect header line */ /* handle the case of "(standard input)" as a filename */ string_sub(line,"standard input","STDIN"); - string_sub(line,"(","\""); - string_sub(line,")","\""); + all_string_sub(line,"(","\""); + all_string_sub(line,")","\""); for (count=0; count<2 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ; /* we must get 2 tokens */ @@ -666,18 +666,18 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first) fstring tok[7]; int count=0; - DEBUG(0,("antes [%s]\n", line)); + DEBUG(4,("antes [%s]\n", line)); /* handle the case of "-- standard input --" as a filename */ string_sub(line,"standard input","STDIN"); - DEBUG(0,("despues [%s]\n", line)); - string_sub(line,"-- ","\""); - string_sub(line," --","\""); - DEBUG(0,("despues 1 [%s]\n", line)); + DEBUG(4,("despues [%s]\n", line)); + all_string_sub(line,"-- ","\""); + all_string_sub(line," --","\""); + DEBUG(4,("despues 1 [%s]\n", line)); string_sub(line,"[job #",""); string_sub(line,"]",""); - DEBUG(0,("despues 2 [%s]\n", line)); + DEBUG(4,("despues 2 [%s]\n", line)); @@ -733,8 +733,8 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first) /* handle the case of "(standard input)" as a filename */ string_sub(line,"stdin","STDIN"); - string_sub(line,"(","\""); - string_sub(line,")","\""); + all_string_sub(line,"(","\""); + all_string_sub(line,")","\""); for (count=0; count<11 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ; -- cgit From bfc38ff872446e0ad365c22327c779e72a81bef9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Nov 1998 21:17:20 +0000 Subject: Makefile.in: Added maintainer mode fixes. aclocal.m4: Added AC_LIBTESTFUNC. configure.in: Fixed -lsecurity -lsec problems. client.c: dos_ fixes. groupdb/aliasunix.c: Dead code removal. include/includes.h: Added default PRINTCAP_NAME. lib/genrand.c: dos_ fixes. lib/replace.c: Added strtoul. lib/system.c: dos_ fixes. lib/util.c: dos_ fixes. lib/util_sid.c: Signed/unsigned fixes. lib/util_str.c: removed bad const. locking/locking_slow.c: dos_ fixes. printing/printing.c: dos_ fixes. rpc_server/srv_samr.c: Dead code removal. rpc_server/srv_sid.c: global_myworkgroup defined with wrong size AGAIN ! smbd/dir.c: dos_ fixes. smbd/open.c: dos_ fixes. smbd/oplock.c: dos_ fixes. smbd/reply.c smbd/server.c smbd/service.c smbd/uid.c: dos_ fixes. Jeremy. (This used to be commit 6acb4b68f68d516e2ac3c47e500f5600d653435e) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 87be54618b..c38808ab7e 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -110,7 +110,7 @@ void print_file(connection_struct *conn, files_struct *file) *syscmd = 0; - if (file_size(file->fsp_name) <= 0) { + if (dos_file_size(file->fsp_name) <= 0) { DEBUG(3,("Discarding null print job %s\n",file->fsp_name)); dos_unlink(file->fsp_name); return; -- cgit From bc40376caa1e828b9e739cd94e46387e0eaf7652 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 7 Apr 1999 04:20:00 +0000 Subject: Changed calls to strncat() to safe_strcat(). Fix from SAMBA_2_0 branch. (This used to be commit 2d2c5ae7cd610b0d97151f90ad5ac7f4e41e514d) --- source3/printing/printing.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index c38808ab7e..dc28f17615 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -263,8 +263,8 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) bufsize = sizeof(buf->file) - strlen(buf->file) - 1; for (i = (FILETOK + 1); i < TOTALTOK; i++) { - strncat(buf->file," ",bufsize); - strncat(buf->file,tok[i],bufsize - 1); + safe_strcat(buf->file," ",bufsize); + safe_strcat(buf->file,tok[i],bufsize - 1); bufsize = sizeof(buf->file) - strlen(buf->file) - 1; if (bufsize <= 0) { break; @@ -378,8 +378,8 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first) bufsize = sizeof(buf->file) - strlen(buf->file) - 1; for (i = (LPRNG_FILETOK + 1); i < LPRNG_TOTALTOK; i++) { - strncat(buf->file," ",bufsize); - strncat(buf->file,tokarr[i],bufsize - 1); + safe_strcat(buf->file," ",bufsize); + safe_strcat(buf->file,tokarr[i],bufsize - 1); bufsize = sizeof(buf->file) - strlen(buf->file) - 1; if (bufsize <= 0) { break; -- cgit From 0ce128e3550794d4dbbd1def00e87c020f72c992 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 12 Dec 1999 01:25:49 +0000 Subject: delineation between smb and msrpc more marked. smbd now constructs pdus, and then feeds them over either a "local" function call or a "remote" function call to an msrpc service. the "remote" msrpc daemon, on the other side of a unix socket, then calls the same "local" function that smbd would, if the msrpc service were being run from inside smbd. this allows a transition from local msrpc services (inside the same smbd process) to remote (over a unix socket). removed reference to pipes_struct in msrpc services. all msrpc processing functions take rpcsrv_struct which is a structure containing state info for the msrpc functions to decode and create pdus. created become_vuser() which does everything not related to connection_struct that become_user() does. removed, as best i could, connection_struct dependencies from the nt spoolss printing code. todo: remove dcinfo from rpcsrv_struct because this stores NETLOGON-specific info on a per-connection basis, and if the connection dies then so does the info, and that's a fairly serious problem. had to put pretty much everything that is in user_struct into parse_creds.c to feed unix user info over to the msrpc daemons. why? because it's expensive to do unix password/group database lookups, and it's definitely expensive to do nt user profile lookups, not to mention pretty difficult and if you did either of these it would introduce a complication / unnecessary interdependency. so, send uid/gid/num_groups/gid_t* + SID+num_rids+domain_group_rids* + unix username + nt username + nt domain + user session key etc. this is the MINIMUM info identified so far that's actually implemented. missing bits include the called and calling netbios names etc. (basically, anything that can be loaded into standard_sub() and standard_sub_basic()...) (This used to be commit aa3c659a8dba0437c17c60055a6ed30fdfecdb6d) --- source3/printing/printing.c | 58 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 13 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index dc28f17615..e1fb53f40d 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -49,11 +49,10 @@ Build the print command in the supplied buffer. This means getting the print command for the service and inserting the printer name and the print file name. Return NULL on error, else the passed buffer pointer. ****************************************************************************/ -static char *build_print_command(connection_struct *conn, +static char *build_print_command(connection_struct *conn, int snum, char *command, char *syscmd, char *filename1) { - int snum = SNUM(conn); char *tstr; pstring filename; @@ -93,8 +92,15 @@ static char *build_print_command(connection_struct *conn, string_sub(syscmd, "%p", tstr); - standard_sub(conn,syscmd); - + if (conn != NULL) + { + standard_sub(conn, syscmd); + } + else + { + standard_sub_basic(syscmd); + } + return (syscmd); } @@ -102,10 +108,9 @@ static char *build_print_command(connection_struct *conn, /**************************************************************************** print a file - called on closing the file ****************************************************************************/ -void print_file(connection_struct *conn, files_struct *file) +void print_file(connection_struct *conn, int snum, files_struct *file) { pstring syscmd; - int snum = SNUM(conn); char *tempstr; *syscmd = 0; @@ -116,7 +121,7 @@ void print_file(connection_struct *conn, files_struct *file) return; } - tempstr = build_print_command(conn, + tempstr = build_print_command(conn, snum, PRINTCOMMAND(snum), syscmd, file->fsp_name); if (tempstr != NULL) { @@ -959,8 +964,7 @@ static BOOL parse_lpq_entry(int snum,char *line, /**************************************************************************** get a printer queue ****************************************************************************/ -int get_printqueue(int snum, - connection_struct *conn,print_queue_struct **queue, +int get_printqueue(int snum, connection_struct *conn, print_queue_struct **queue, print_status_struct *status) { char *lpq_command = lp_lpqcommand(snum); @@ -991,7 +995,14 @@ int get_printqueue(int snum, pstrcpy(syscmd,lpq_command); string_sub(syscmd,"%p",printername); - standard_sub(conn,syscmd); + if (conn != NULL) + { + standard_sub(conn, syscmd); + } + else + { + standard_sub_basic(syscmd); + } slprintf(outfile,sizeof(outfile)-1, "%s/lpq.%08x",tmpdir(),str_checksum(syscmd)); @@ -1080,7 +1091,14 @@ void del_printqueue(connection_struct *conn,int snum,int jobid) pstrcpy(syscmd,lprm_command); string_sub(syscmd,"%p",printername); string_sub(syscmd,"%j",jobstr); - standard_sub(conn,syscmd); + if (conn != NULL) + { + standard_sub(conn, syscmd); + } + else + { + standard_sub_basic(syscmd); + } ret = smbrun(syscmd,NULL,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); @@ -1118,7 +1136,14 @@ void status_printjob(connection_struct *conn,int snum,int jobid,int status) pstrcpy(syscmd,lpstatus_command); string_sub(syscmd,"%p",printername); string_sub(syscmd,"%j",jobstr); - standard_sub(conn,syscmd); + if (conn != NULL) + { + standard_sub(conn, syscmd); + } + else + { + standard_sub_basic(syscmd); + } ret = smbrun(syscmd,NULL,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); @@ -1173,7 +1198,14 @@ void status_printqueue(connection_struct *conn,int snum,int status) pstrcpy(syscmd,queuestatus_command); string_sub(syscmd,"%p",printername); - standard_sub(conn,syscmd); + if (conn != NULL) + { + standard_sub(conn, syscmd); + } + else + { + standard_sub_basic(syscmd); + } ret = smbrun(syscmd,NULL,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); -- cgit From 3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 1999 13:27:58 +0000 Subject: first pass at updating head branch to be to be the same as the SAMBA_2_0 branch (This used to be commit 453a822a76780063dff23526c35408866d0c0154) --- source3/printing/printing.c | 174 ++++++++++++++++++++------------------------ 1 file changed, 80 insertions(+), 94 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index e1fb53f40d..134a594630 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -49,12 +49,12 @@ Build the print command in the supplied buffer. This means getting the print command for the service and inserting the printer name and the print file name. Return NULL on error, else the passed buffer pointer. ****************************************************************************/ -static char *build_print_command(connection_struct *conn, int snum, +static char *build_print_command(connection_struct *conn, char *command, - char *syscmd, char *filename1) + char *syscmd, char *filename) { + int snum = SNUM(conn); char *tstr; - pstring filename; /* get the print command for the service. */ tstr = command; @@ -72,13 +72,8 @@ static char *build_print_command(connection_struct *conn, int snum, DEBUG(2,("WARNING! No placeholder for the filename in the print command for service %s!\n", SERVICE(snum))); } - if (strstr(syscmd,"%s")) { - pstrcpy(filename,filename1); - - string_sub(syscmd, "%s", filename); - } - - string_sub(syscmd, "%f", filename1); + pstring_sub(syscmd, "%s", filename); + pstring_sub(syscmd, "%f", filename); /* Does the service have a printername? If not, make a fake and empty */ @@ -90,17 +85,10 @@ static char *build_print_command(connection_struct *conn, int snum, tstr = SERVICE(snum); } - string_sub(syscmd, "%p", tstr); + pstring_sub(syscmd, "%p", tstr); + + standard_sub(conn,syscmd); - if (conn != NULL) - { - standard_sub(conn, syscmd); - } - else - { - standard_sub_basic(syscmd); - } - return (syscmd); } @@ -108,9 +96,10 @@ static char *build_print_command(connection_struct *conn, int snum, /**************************************************************************** print a file - called on closing the file ****************************************************************************/ -void print_file(connection_struct *conn, int snum, files_struct *file) +void print_file(connection_struct *conn, files_struct *file) { pstring syscmd; + int snum = SNUM(conn); char *tempstr; *syscmd = 0; @@ -121,7 +110,7 @@ void print_file(connection_struct *conn, int snum, files_struct *file) return; } - tempstr = build_print_command(conn, snum, + tempstr = build_print_command(conn, PRINTCOMMAND(snum), syscmd, file->fsp_name); if (tempstr != NULL) { @@ -252,7 +241,7 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) return(False); /* the Job and Total columns must be integer */ - if (!isdigit(*tok[JOBTOK]) || !isdigit(*tok[TOTALTOK])) return(False); + if (!isdigit((int)*tok[JOBTOK]) || !isdigit((int)*tok[TOTALTOK])) return(False); buf->job = atoi(tok[JOBTOK]); buf->size = atoi(tok[TOTALTOK]); @@ -275,6 +264,8 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) break; } } + /* Ensure null termination. */ + buf->file[sizeof(buf->file)-1] = '\0'; } #ifdef PRIOTOK @@ -345,7 +336,7 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first) return(False); } - if (!isdigit(*tokarr[LPRNG_JOBTOK]) || !isdigit(*tokarr[LPRNG_TOTALTOK])) { + if (!isdigit((int)*tokarr[LPRNG_JOBTOK]) || !isdigit((int)*tokarr[LPRNG_TOTALTOK])) { return(False); } @@ -354,7 +345,7 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first) if (strequal(tokarr[LPRNG_RANKTOK],"active")) { buf->status = LPQ_PRINTING; - } else if (isdigit(*tokarr[LPRNG_RANKTOK])) { + } else if (isdigit((int)*tokarr[LPRNG_RANKTOK])) { buf->status = LPQ_QUEUED; } else { buf->status = LPQ_PAUSED; @@ -390,6 +381,8 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first) break; } } + /* Ensure null termination. */ + buf->file[sizeof(buf->file)-1] = '\0'; } return(True); @@ -415,9 +408,9 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) int count=0; /* handle the case of "(standard input)" as a filename */ - string_sub(line,"standard input","STDIN"); - all_string_sub(line,"(","\""); - all_string_sub(line,")","\""); + pstring_sub(line,"standard input","STDIN"); + all_string_sub(line,"(","\"",0); + all_string_sub(line,")","\"",0); for (count=0; count<10 && @@ -532,9 +525,9 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first) } if (!header_line_ok) return (False); /* incorrect header line */ /* handle the case of "(standard input)" as a filename */ - string_sub(line,"standard input","STDIN"); - all_string_sub(line,"(","\""); - all_string_sub(line,")","\""); + pstring_sub(line,"standard input","STDIN"); + all_string_sub(line,"(","\"",0); + all_string_sub(line,")","\"",0); for (count=0; count<2 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ; /* we must get 2 tokens */ @@ -570,7 +563,7 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first) else if (base_prio) base_prio_reset=False; /* handle the dash in the job id */ - string_sub(line,"-"," "); + pstring_sub(line,"-"," "); for (count=0; count<12 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ; @@ -605,7 +598,7 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first) /**************************************************************************** -parse a lpq line +parse a lpstat line here is an example of "lpstat -o dcslw" output under sysv @@ -619,27 +612,47 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first) int count=0; char *p; - /* handle the dash in the job id */ - string_sub(line,"-"," "); - - for (count=0; count<9 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ; + /* + * Handle the dash in the job id, but make sure that we skip over + * the printer name in case we have a dash in that. + * Patch from Dom.Mitchell@palmerharvey.co.uk. + */ + + /* + * Move to the first space. + */ + for (p = line ; !isspace(*p) && *p; p++) + ; + + /* + * Back up until the last '-' character or + * start of line. + */ + for (; (p >= line) && (*p != '-'); p--) + ; + + if((p >= line) && (*p == '-')) + *p = ' '; + + for (count=0; count<9 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) + ; /* we must get 7 tokens */ if (count < 7) return(False); /* the 2nd and 4th, 6th columns must be integer */ - if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[3])) return(False); - if (!isdigit((int)*tok[5])) return(False); + if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[3])) + return(False); + if (!isdigit((int)*tok[5])) + return(False); /* if the user contains a ! then trim the first part of it */ - if ((p=strchr(tok[2],'!'))) - { + if ((p=strchr(tok[2],'!'))) { fstring tmp; fstrcpy(tmp,p+1); fstrcpy(tok[2],tmp); - } - + } buf->job = atoi(tok[1]); buf->size = atoi(tok[3]); @@ -674,14 +687,14 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first) DEBUG(4,("antes [%s]\n", line)); /* handle the case of "-- standard input --" as a filename */ - string_sub(line,"standard input","STDIN"); + pstring_sub(line,"standard input","STDIN"); DEBUG(4,("despues [%s]\n", line)); - all_string_sub(line,"-- ","\""); - all_string_sub(line," --","\""); + all_string_sub(line,"-- ","\"",0); + all_string_sub(line," --","\"",0); DEBUG(4,("despues 1 [%s]\n", line)); - string_sub(line,"[job #",""); - string_sub(line,"]",""); + pstring_sub(line,"[job #",""); + pstring_sub(line,"]",""); DEBUG(4,("despues 2 [%s]\n", line)); @@ -737,9 +750,9 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first) int count=0; /* handle the case of "(standard input)" as a filename */ - string_sub(line,"stdin","STDIN"); - all_string_sub(line,"(","\""); - all_string_sub(line,")","\""); + pstring_sub(line,"stdin","STDIN"); + all_string_sub(line,"(","\"",0); + all_string_sub(line,")","\"",0); for (count=0; count<11 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ; @@ -807,7 +820,7 @@ static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first) int count=0; /* mung all the ":"s to spaces*/ - string_sub(line,":"," "); + pstring_sub(line,":"," "); for (count=0; count<10 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ; @@ -851,8 +864,8 @@ static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first) t->tm_mon = atoi(tok[count+2]+3); switch (*tok[count+2]) { - case 7: case 8: case 9: t->tm_year = atoi(tok[count+2]) + 1900; break; - default: t->tm_year = atoi(tok[count+2]) + 2000; break; + case 7: case 8: case 9: t->tm_year = atoi(tok[count+2]); break; + default: t->tm_year = atoi(tok[count+2]); break; } t->tm_hour = atoi(tok[count+3]); @@ -964,7 +977,8 @@ static BOOL parse_lpq_entry(int snum,char *line, /**************************************************************************** get a printer queue ****************************************************************************/ -int get_printqueue(int snum, connection_struct *conn, print_queue_struct **queue, +int get_printqueue(int snum, + connection_struct *conn,print_queue_struct **queue, print_status_struct *status) { char *lpq_command = lp_lpqcommand(snum); @@ -993,16 +1007,9 @@ int get_printqueue(int snum, connection_struct *conn, print_queue_struct **queue } pstrcpy(syscmd,lpq_command); - string_sub(syscmd,"%p",printername); + pstring_sub(syscmd,"%p",printername); - if (conn != NULL) - { - standard_sub(conn, syscmd); - } - else - { - standard_sub_basic(syscmd); - } + standard_sub(conn,syscmd); slprintf(outfile,sizeof(outfile)-1, "%s/lpq.%08x",tmpdir(),str_checksum(syscmd)); @@ -1039,7 +1046,7 @@ int get_printqueue(int snum, connection_struct *conn, print_queue_struct **queue break; } - bzero((char *)&(*queue)[count],sizeof(**queue)); + memset((char *)&(*queue)[count],'\0',sizeof(**queue)); /* parse it */ if (!parse_lpq_entry(snum,line, @@ -1089,16 +1096,9 @@ void del_printqueue(connection_struct *conn,int snum,int jobid) slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid); pstrcpy(syscmd,lprm_command); - string_sub(syscmd,"%p",printername); - string_sub(syscmd,"%j",jobstr); - if (conn != NULL) - { - standard_sub(conn, syscmd); - } - else - { - standard_sub_basic(syscmd); - } + pstring_sub(syscmd,"%p",printername); + pstring_sub(syscmd,"%j",jobstr); + standard_sub(conn,syscmd); ret = smbrun(syscmd,NULL,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); @@ -1134,16 +1134,9 @@ void status_printjob(connection_struct *conn,int snum,int jobid,int status) slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid); pstrcpy(syscmd,lpstatus_command); - string_sub(syscmd,"%p",printername); - string_sub(syscmd,"%j",jobstr); - if (conn != NULL) - { - standard_sub(conn, syscmd); - } - else - { - standard_sub_basic(syscmd); - } + pstring_sub(syscmd,"%p",printername); + pstring_sub(syscmd,"%j",jobstr); + standard_sub(conn,syscmd); ret = smbrun(syscmd,NULL,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); @@ -1197,15 +1190,8 @@ void status_printqueue(connection_struct *conn,int snum,int status) } pstrcpy(syscmd,queuestatus_command); - string_sub(syscmd,"%p",printername); - if (conn != NULL) - { - standard_sub(conn, syscmd); - } - else - { - standard_sub_basic(syscmd); - } + pstring_sub(syscmd,"%p",printername); + standard_sub(conn,syscmd); ret = smbrun(syscmd,NULL,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); -- cgit From 6e11f213782361a6d96d442814f83fc148d331fc Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Mon, 13 Mar 2000 11:21:03 +0000 Subject: Interim fix for LPRng. If a lpq parsed line start with a space, we skip it, to prevent false status return value. Jeremy, it's a gross hack but you should consider it for 2.0.7 also. J.F. (This used to be commit 2b1663ec13d9c481fb535c757744068919201f6a) --- source3/printing/printing.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 134a594630..e4768582a8 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -937,6 +937,14 @@ static BOOL parse_lpq_entry(int snum,char *line, if (p) *p = 0; } + /* in the LPRNG case, we skip lines starting by a space.*/ + if (line && !ret && (lp_printing(snum)==PRINT_LPRNG) ) + { + if (line[0]==' ') + return ret; + } + + if (status && !ret) { /* a few simple checks to see if the line might be a -- cgit From 001765501ed5dcc9e3c29d9f662c428e2a66187a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Apr 2000 03:09:42 +0000 Subject: split out the lpq parsing code into a separate file printing/lpq_parse.c getting ready for the new printing backend (This used to be commit 0ec1072e0143952139be64e8001582eadcc9f60e) --- source3/printing/printing.c | 858 -------------------------------------------- 1 file changed, 858 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index e4768582a8..7edb69de27 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -123,864 +123,6 @@ void print_file(connection_struct *conn, files_struct *file) lpq_reset(snum); } -static char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Err"}; - - -/******************************************************************* -process time fields -********************************************************************/ -static time_t EntryTime(fstring tok[], int ptr, int count, int minimum) -{ - time_t jobtime,jobtime1; - - jobtime = time(NULL); /* default case: take current time */ - if (count >= minimum) { - struct tm *t; - int i, day, hour, min, sec; - char *c; - - for (i=0; i<13; i++) if (!strncmp(tok[ptr], Months[i],3)) break; /* Find month */ - if (i<12) { - t = localtime(&jobtime); - day = atoi(tok[ptr+1]); - c=(char *)(tok[ptr+2]); - *(c+2)=0; - hour = atoi(c); - *(c+5)=0; - min = atoi(c+3); - if(*(c+6) != 0)sec = atoi(c+6); - else sec=0; - - if ((t->tm_mon < i)|| - ((t->tm_mon == i)&& - ((t->tm_mday < day)|| - ((t->tm_mday == day)&& - (t->tm_hour*60+t->tm_min < hour*60+min))))) - t->tm_year--; /* last year's print job */ - - t->tm_mon = i; - t->tm_mday = day; - t->tm_hour = hour; - t->tm_min = min; - t->tm_sec = sec; - jobtime1 = mktime(t); - if (jobtime1 != (time_t)-1) - jobtime = jobtime1; - } - } - return jobtime; -} - - -/**************************************************************************** -parse a lpq line - -here is an example of lpq output under bsd - -Warning: no daemon present -Rank Owner Job Files Total Size -1st tridge 148 README 8096 bytes - -here is an example of lpq output under osf/1 - -Warning: no daemon present -Rank Pri Owner Job Files Total Size -1st 0 tridge 148 README 8096 bytes - - - June 30, 1998. -Modified to handle file names with spaces, like the parse_lpq_lprng code -further below. -****************************************************************************/ -static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) -{ -#ifdef OSF1 -#define RANKTOK 0 -#define PRIOTOK 1 -#define USERTOK 2 -#define JOBTOK 3 -#define FILETOK 4 -#define TOTALTOK (count - 2) -#define NTOK 6 -#define MAXTOK 128 -#else /* OSF1 */ -#define RANKTOK 0 -#define USERTOK 1 -#define JOBTOK 2 -#define FILETOK 3 -#define TOTALTOK (count - 2) -#define NTOK 5 -#define MAXTOK 128 -#endif /* OSF1 */ - - char *tok[MAXTOK]; - int count = 0; - pstring line2; - - pstrcpy(line2,line); - -#ifdef OSF1 - { - size_t length; - length = strlen(line2); - if (line2[length-3] == ':') - return(False); - } -#endif /* OSF1 */ - - tok[0] = strtok(line2," \t"); - count++; - - while (((tok[count] = strtok(NULL," \t")) != NULL) && (count < MAXTOK)) { - count++; - } - - /* we must get at least NTOK tokens */ - if (count < NTOK) - return(False); - - /* the Job and Total columns must be integer */ - if (!isdigit((int)*tok[JOBTOK]) || !isdigit((int)*tok[TOTALTOK])) return(False); - - buf->job = atoi(tok[JOBTOK]); - buf->size = atoi(tok[TOTALTOK]); - buf->status = strequal(tok[RANKTOK],"active")?LPQ_PRINTING:LPQ_QUEUED; - buf->time = time(NULL); - StrnCpy(buf->user,tok[USERTOK],sizeof(buf->user)-1); - StrnCpy(buf->file,tok[FILETOK],sizeof(buf->file)-1); - - if ((FILETOK + 1) != TOTALTOK) { - int bufsize; - int i; - - bufsize = sizeof(buf->file) - strlen(buf->file) - 1; - - for (i = (FILETOK + 1); i < TOTALTOK; i++) { - safe_strcat(buf->file," ",bufsize); - safe_strcat(buf->file,tok[i],bufsize - 1); - bufsize = sizeof(buf->file) - strlen(buf->file) - 1; - if (bufsize <= 0) { - break; - } - } - /* Ensure null termination. */ - buf->file[sizeof(buf->file)-1] = '\0'; - } - -#ifdef PRIOTOK - buf->priority = atoi(tok[PRIOTOK]); -#else - buf->priority = 1; -#endif - return(True); -} - -/* - -LPRng_time modifies the current date by inserting the hour and minute from -the lpq output. The lpq time looks like "23:15:07" - - June 30, 1998. -Modified to work with the re-written parse_lpq_lprng routine. -*/ -static time_t LPRng_time(char *time_string) -{ - time_t jobtime; - struct tm *t; - - jobtime = time(NULL); /* default case: take current time */ - t = localtime(&jobtime); - t->tm_hour = atoi(time_string); - t->tm_min = atoi(time_string+3); - t->tm_sec = atoi(time_string+6); - jobtime = mktime(t); - - return jobtime; -} - - -/**************************************************************************** - parse a lprng lpq line - June 30, 1998. - Re-wrote this to handle file names with spaces, multiple file names on one - lpq line, etc; -****************************************************************************/ -static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first) -{ -#define LPRNG_RANKTOK 0 -#define LPRNG_USERTOK 1 -#define LPRNG_PRIOTOK 2 -#define LPRNG_JOBTOK 3 -#define LPRNG_FILETOK 4 -#define LPRNG_TOTALTOK (num_tok - 2) -#define LPRNG_TIMETOK (num_tok - 1) -#define LPRNG_NTOK 7 -#define LPRNG_MAXTOK 128 /* PFMA just to keep us from running away. */ - - char *tokarr[LPRNG_MAXTOK]; - char *cptr; - int num_tok = 0; - pstring line2; - - pstrcpy(line2,line); - tokarr[0] = strtok(line2," \t"); - num_tok++; - while (((tokarr[num_tok] = strtok(NULL," \t")) != NULL) - && (num_tok < LPRNG_MAXTOK)) { - num_tok++; - } - - /* We must get at least LPRNG_NTOK tokens. */ - if (num_tok < LPRNG_NTOK) { - return(False); - } - - if (!isdigit((int)*tokarr[LPRNG_JOBTOK]) || !isdigit((int)*tokarr[LPRNG_TOTALTOK])) { - return(False); - } - - buf->job = atoi(tokarr[LPRNG_JOBTOK]); - buf->size = atoi(tokarr[LPRNG_TOTALTOK]); - - if (strequal(tokarr[LPRNG_RANKTOK],"active")) { - buf->status = LPQ_PRINTING; - } else if (isdigit((int)*tokarr[LPRNG_RANKTOK])) { - buf->status = LPQ_QUEUED; - } else { - buf->status = LPQ_PAUSED; - } - - buf->priority = *tokarr[LPRNG_PRIOTOK] -'A'; - - buf->time = LPRng_time(tokarr[LPRNG_TIMETOK]); - - StrnCpy(buf->user,tokarr[LPRNG_USERTOK],sizeof(buf->user)-1); - - /* The '@hostname' prevents windows from displaying the printing icon - * for the current user on the taskbar. Plop in a null. - */ - - if ((cptr = strchr(buf->user,'@')) != NULL) { - *cptr = '\0'; - } - - StrnCpy(buf->file,tokarr[LPRNG_FILETOK],sizeof(buf->file)-1); - - if ((LPRNG_FILETOK + 1) != LPRNG_TOTALTOK) { - int bufsize; - int i; - - bufsize = sizeof(buf->file) - strlen(buf->file) - 1; - - for (i = (LPRNG_FILETOK + 1); i < LPRNG_TOTALTOK; i++) { - safe_strcat(buf->file," ",bufsize); - safe_strcat(buf->file,tokarr[i],bufsize - 1); - bufsize = sizeof(buf->file) - strlen(buf->file) - 1; - if (bufsize <= 0) { - break; - } - } - /* Ensure null termination. */ - buf->file[sizeof(buf->file)-1] = '\0'; - } - - return(True); -} - - - -/******************************************************************* -parse lpq on an aix system - -Queue Dev Status Job Files User PP % Blks Cp Rnk -------- ----- --------- --- ------------------ ---------- ---- -- ----- --- --- -lazer lazer READY -lazer lazer RUNNING 537 6297doc.A kvintus@IE 0 10 2445 1 1 - QUEUED 538 C.ps root@IEDVB 124 1 2 - QUEUED 539 E.ps root@IEDVB 28 1 3 - QUEUED 540 L.ps root@IEDVB 172 1 4 - QUEUED 541 P.ps root@IEDVB 22 1 5 -********************************************************************/ -static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) -{ - fstring tok[11]; - int count=0; - - /* handle the case of "(standard input)" as a filename */ - pstring_sub(line,"standard input","STDIN"); - all_string_sub(line,"(","\"",0); - all_string_sub(line,")","\"",0); - - for (count=0; - count<10 && - next_token(&line,tok[count],NULL, sizeof(tok[count])); - count++) ; - - /* we must get 6 tokens */ - if (count < 10) - { - if ((count == 7) && ((strcmp(tok[0],"QUEUED") == 0) || (strcmp(tok[0],"HELD") == 0))) - { - /* the 2nd and 5th columns must be integer */ - if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4])) return(False); - buf->size = atoi(tok[4]) * 1024; - /* if the fname contains a space then use STDIN */ - if (strchr(tok[2],' ')) - fstrcpy(tok[2],"STDIN"); - - /* only take the last part of the filename */ - { - fstring tmp; - char *p = strrchr(tok[2],'/'); - if (p) - { - fstrcpy(tmp,p+1); - fstrcpy(tok[2],tmp); - } - } - - - buf->job = atoi(tok[1]); - buf->status = strequal(tok[0],"HELD")?LPQ_PAUSED:LPQ_QUEUED; - buf->priority = 0; - buf->time = time(NULL); - StrnCpy(buf->user,tok[3],sizeof(buf->user)-1); - StrnCpy(buf->file,tok[2],sizeof(buf->file)-1); - } - else - { - DEBUG(6,("parse_lpq_aix count=%d\n", count)); - return(False); - } - } - else - { - /* the 4th and 9th columns must be integer */ - if (!isdigit((int)*tok[3]) || !isdigit((int)*tok[8])) return(False); - buf->size = atoi(tok[8]) * 1024; - /* if the fname contains a space then use STDIN */ - if (strchr(tok[4],' ')) - fstrcpy(tok[4],"STDIN"); - - /* only take the last part of the filename */ - { - fstring tmp; - char *p = strrchr(tok[4],'/'); - if (p) - { - fstrcpy(tmp,p+1); - fstrcpy(tok[4],tmp); - } - } - - - buf->job = atoi(tok[3]); - buf->status = strequal(tok[2],"RUNNING")?LPQ_PRINTING:LPQ_QUEUED; - buf->priority = 0; - buf->time = time(NULL); - StrnCpy(buf->user,tok[5],sizeof(buf->user)-1); - StrnCpy(buf->file,tok[4],sizeof(buf->file)-1); - } - - - return(True); -} - - -/**************************************************************************** -parse a lpq line -here is an example of lpq output under hpux; note there's no space after -o ! -$> lpstat -oljplus -ljplus-2153 user priority 0 Jan 19 08:14 on ljplus - util.c 125697 bytes - server.c 110712 bytes -ljplus-2154 user priority 0 Jan 19 08:14 from client - (standard input) 7551 bytes -****************************************************************************/ -static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first) -{ - /* must read two lines to process, therefore keep some values static */ - static BOOL header_line_ok=False, base_prio_reset=False; - static fstring jobuser; - static int jobid; - static int jobprio; - static time_t jobtime; - static int jobstat=LPQ_QUEUED; - /* to store minimum priority to print, lpstat command should be invoked - with -p option first, to work */ - static int base_prio; - - int count; - char htab = '\011'; - fstring tok[12]; - - /* If a line begins with a horizontal TAB, it is a subline type */ - - if (line[0] == htab) { /* subline */ - /* check if it contains the base priority */ - if (!strncmp(line,"\tfence priority : ",18)) { - base_prio=atoi(&line[18]); - DEBUG(4, ("fence priority set at %d\n", base_prio)); - } - if (!header_line_ok) return (False); /* incorrect header line */ - /* handle the case of "(standard input)" as a filename */ - pstring_sub(line,"standard input","STDIN"); - all_string_sub(line,"(","\"",0); - all_string_sub(line,")","\"",0); - - for (count=0; count<2 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ; - /* we must get 2 tokens */ - if (count < 2) return(False); - - /* the 2nd column must be integer */ - if (!isdigit((int)*tok[1])) return(False); - - /* if the fname contains a space then use STDIN */ - if (strchr(tok[0],' ')) - fstrcpy(tok[0],"STDIN"); - - buf->size = atoi(tok[1]); - StrnCpy(buf->file,tok[0],sizeof(buf->file)-1); - - /* fill things from header line */ - buf->time = jobtime; - buf->job = jobid; - buf->status = jobstat; - buf->priority = jobprio; - StrnCpy(buf->user,jobuser,sizeof(buf->user)-1); - - return(True); - } - else { /* header line */ - header_line_ok=False; /* reset it */ - if (first) { - if (!base_prio_reset) { - base_prio=0; /* reset it */ - base_prio_reset=True; - } - } - else if (base_prio) base_prio_reset=False; - - /* handle the dash in the job id */ - pstring_sub(line,"-"," "); - - for (count=0; count<12 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ; - - /* we must get 8 tokens */ - if (count < 8) return(False); - - /* first token must be printer name (cannot check ?) */ - /* the 2nd, 5th & 7th column must be integer */ - if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4]) || !isdigit((int)*tok[6])) return(False); - jobid = atoi(tok[1]); - StrnCpy(jobuser,tok[2],sizeof(buf->user)-1); - jobprio = atoi(tok[4]); - - /* process time */ - jobtime=EntryTime(tok, 5, count, 8); - if (jobprio < base_prio) { - jobstat = LPQ_PAUSED; - DEBUG (4, ("job %d is paused: prio %d < %d; jobstat=%d\n", jobid, jobprio, base_prio, jobstat)); - } - else { - jobstat = LPQ_QUEUED; - if ((count >8) && (((strequal(tok[8],"on")) || - ((strequal(tok[8],"from")) && - ((count > 10)&&(strequal(tok[10],"on"))))))) - jobstat = LPQ_PRINTING; - } - - header_line_ok=True; /* information is correct */ - return(False); /* need subline info to include into queuelist */ - } -} - - -/**************************************************************************** -parse a lpstat line - -here is an example of "lpstat -o dcslw" output under sysv - -dcslw-896 tridge 4712 Dec 20 10:30:30 on dcslw -dcslw-897 tridge 4712 Dec 20 10:30:30 being held - -****************************************************************************/ -static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first) -{ - fstring tok[9]; - int count=0; - char *p; - - /* - * Handle the dash in the job id, but make sure that we skip over - * the printer name in case we have a dash in that. - * Patch from Dom.Mitchell@palmerharvey.co.uk. - */ - - /* - * Move to the first space. - */ - for (p = line ; !isspace(*p) && *p; p++) - ; - - /* - * Back up until the last '-' character or - * start of line. - */ - for (; (p >= line) && (*p != '-'); p--) - ; - - if((p >= line) && (*p == '-')) - *p = ' '; - - for (count=0; count<9 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) - ; - - /* we must get 7 tokens */ - if (count < 7) - return(False); - - /* the 2nd and 4th, 6th columns must be integer */ - if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[3])) - return(False); - if (!isdigit((int)*tok[5])) - return(False); - - /* if the user contains a ! then trim the first part of it */ - if ((p=strchr(tok[2],'!'))) { - fstring tmp; - fstrcpy(tmp,p+1); - fstrcpy(tok[2],tmp); - } - - buf->job = atoi(tok[1]); - buf->size = atoi(tok[3]); - if (count > 7 && strequal(tok[7],"on")) - buf->status = LPQ_PRINTING; - else if (count > 8 && strequal(tok[7],"being") && strequal(tok[8],"held")) - buf->status = LPQ_PAUSED; - else - buf->status = LPQ_QUEUED; - buf->priority = 0; - buf->time = EntryTime(tok, 4, count, 7); - StrnCpy(buf->user,tok[2],sizeof(buf->user)-1); - StrnCpy(buf->file,tok[2],sizeof(buf->file)-1); - return(True); -} - -/**************************************************************************** -parse a lpq line - -here is an example of lpq output under qnx -Spooler: /qnx/spooler, on node 1 -Printer: txt (ready) -0000: root [job #1 ] active 1146 bytes /etc/profile -0001: root [job #2 ] ready 2378 bytes /etc/install -0002: root [job #3 ] ready 1146 bytes -- standard input -- -****************************************************************************/ -static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first) -{ - fstring tok[7]; - int count=0; - - DEBUG(4,("antes [%s]\n", line)); - - /* handle the case of "-- standard input --" as a filename */ - pstring_sub(line,"standard input","STDIN"); - DEBUG(4,("despues [%s]\n", line)); - all_string_sub(line,"-- ","\"",0); - all_string_sub(line," --","\"",0); - DEBUG(4,("despues 1 [%s]\n", line)); - - pstring_sub(line,"[job #",""); - pstring_sub(line,"]",""); - DEBUG(4,("despues 2 [%s]\n", line)); - - - - for (count=0; count<7 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ; - - /* we must get 7 tokens */ - if (count < 7) - return(False); - - /* the 3rd and 5th columns must be integer */ - if (!isdigit((int)*tok[2]) || !isdigit((int)*tok[4])) return(False); - - /* only take the last part of the filename */ - { - fstring tmp; - char *p = strrchr(tok[6],'/'); - if (p) - { - fstrcpy(tmp,p+1); - fstrcpy(tok[6],tmp); - } - } - - - buf->job = atoi(tok[2]); - buf->size = atoi(tok[4]); - buf->status = strequal(tok[3],"active")?LPQ_PRINTING:LPQ_QUEUED; - buf->priority = 0; - buf->time = time(NULL); - StrnCpy(buf->user,tok[1],sizeof(buf->user)-1); - StrnCpy(buf->file,tok[6],sizeof(buf->file)-1); - return(True); -} - - -/**************************************************************************** - parse a lpq line for the plp printing system - Bertrand Wallrich - -redone by tridge. Here is a sample queue: - -Local Printer 'lp2' (fjall): - Printing (started at Jun 15 13:33:58, attempt 1). - Rank Owner Pr Opt Job Host Files Size Date - active tridge X - 6 fjall /etc/hosts 739 Jun 15 13:33 - 3rd tridge X - 7 fjall /etc/hosts 739 Jun 15 13:33 - -****************************************************************************/ -static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first) -{ - fstring tok[11]; - int count=0; - - /* handle the case of "(standard input)" as a filename */ - pstring_sub(line,"stdin","STDIN"); - all_string_sub(line,"(","\"",0); - all_string_sub(line,")","\"",0); - - for (count=0; count<11 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ; - - /* we must get 11 tokens */ - if (count < 11) - return(False); - - /* the first must be "active" or begin with an integer */ - if (strcmp(tok[0],"active") && !isdigit((int)tok[0][0])) - return(False); - - /* the 5th and 8th must be integer */ - if (!isdigit((int)*tok[4]) || !isdigit((int)*tok[7])) - return(False); - - /* if the fname contains a space then use STDIN */ - if (strchr(tok[6],' ')) - fstrcpy(tok[6],"STDIN"); - - /* only take the last part of the filename */ - { - fstring tmp; - char *p = strrchr(tok[6],'/'); - if (p) - { - fstrcpy(tmp,p+1); - fstrcpy(tok[6],tmp); - } - } - - - buf->job = atoi(tok[4]); - - buf->size = atoi(tok[7]); - if (strchr(tok[7],'K')) - buf->size *= 1024; - if (strchr(tok[7],'M')) - buf->size *= 1024*1024; - - buf->status = strequal(tok[0],"active")?LPQ_PRINTING:LPQ_QUEUED; - buf->priority = 0; - buf->time = time(NULL); - StrnCpy(buf->user,tok[1],sizeof(buf->user)-1); - StrnCpy(buf->file,tok[6],sizeof(buf->file)-1); - return(True); -} - -/**************************************************************************** -parse a qstat line - -here is an example of "qstat -l -d qms" output under softq - -Queue qms: 2 jobs; daemon active (313); enabled; accepting; - job-ID submission-time pri size owner title -205980: H 98/03/09 13:04:05 0 15733 stephenf chap1.ps -206086:> 98/03/12 17:24:40 0 659 chris - -206087: 98/03/12 17:24:45 0 4876 chris - -Total: 21268 bytes in queue - - -****************************************************************************/ -static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first) -{ - fstring tok[10]; - int count=0; - - /* mung all the ":"s to spaces*/ - pstring_sub(line,":"," "); - - for (count=0; count<10 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ; - - /* we must get 9 tokens */ - if (count < 9) - return(False); - - /* the 1st and 7th columns must be integer */ - if (!isdigit((int)*tok[0]) || !isdigit((int)*tok[6])) return(False); - /* if the 2nd column is either '>' or 'H' then the 7th and 8th must be - * integer, else it's the 6th and 7th that must be - */ - if (*tok[1] == 'H' || *tok[1] == '>') - { - if (!isdigit((int)*tok[7])) - return(False); - buf->status = *tok[1] == '>' ? LPQ_PRINTING : LPQ_PAUSED; - count = 1; - } - else - { - if (!isdigit((int)*tok[5])) - return(False); - buf->status = LPQ_QUEUED; - count = 0; - } - - - buf->job = atoi(tok[0]); - buf->size = atoi(tok[count+6]); - buf->priority = atoi(tok[count+5]); - StrnCpy(buf->user,tok[count+7],sizeof(buf->user)-1); - StrnCpy(buf->file,tok[count+8],sizeof(buf->file)-1); - buf->time = time(NULL); /* default case: take current time */ - { - time_t jobtime; - struct tm *t; - - t = localtime(&buf->time); - t->tm_mday = atoi(tok[count+2]+6); - t->tm_mon = atoi(tok[count+2]+3); - switch (*tok[count+2]) - { - case 7: case 8: case 9: t->tm_year = atoi(tok[count+2]); break; - default: t->tm_year = atoi(tok[count+2]); break; - } - - t->tm_hour = atoi(tok[count+3]); - t->tm_min = atoi(tok[count+4]); - t->tm_sec = atoi(tok[count+5]); - jobtime = mktime(t); - if (jobtime != (time_t)-1) - buf->time = jobtime; - } - - return(True); -} - - -char *stat0_strings[] = { "enabled", "online", "idle", "no entries", "free", "ready", NULL }; -char *stat1_strings[] = { "offline", "disabled", "down", "off", "waiting", "no daemon", NULL }; -char *stat2_strings[] = { "jam", "paper", "error", "responding", "not accepting", "not running", "turned off", NULL }; - -/**************************************************************************** -parse a lpq line. Choose printing style -****************************************************************************/ -static BOOL parse_lpq_entry(int snum,char *line, - print_queue_struct *buf, - print_status_struct *status,BOOL first) -{ - BOOL ret; - - switch (lp_printing(snum)) - { - case PRINT_SYSV: - ret = parse_lpq_sysv(line,buf,first); - break; - case PRINT_AIX: - ret = parse_lpq_aix(line,buf,first); - break; - case PRINT_HPUX: - ret = parse_lpq_hpux(line,buf,first); - break; - case PRINT_QNX: - ret = parse_lpq_qnx(line,buf,first); - break; - case PRINT_LPRNG: - ret = parse_lpq_lprng(line,buf,first); - break; - case PRINT_PLP: - ret = parse_lpq_plp(line,buf,first); - break; - case PRINT_SOFTQ: - ret = parse_lpq_softq(line,buf,first); - break; - default: - ret = parse_lpq_bsd(line,buf,first); - break; - } - -#ifdef LPQ_GUEST_TO_USER - if (ret) { - extern pstring sesssetup_user; - /* change guest entries to the current logged in user to make - them appear deletable to windows */ - if (sesssetup_user[0] && strequal(buf->user,lp_guestaccount(snum))) - pstrcpy(buf->user,sesssetup_user); - } -#endif - - /* We don't want the newline in the status message. */ - { - char *p = strchr(line,'\n'); - if (p) *p = 0; - } - - /* in the LPRNG case, we skip lines starting by a space.*/ - if (line && !ret && (lp_printing(snum)==PRINT_LPRNG) ) - { - if (line[0]==' ') - return ret; - } - - - if (status && !ret) - { - /* a few simple checks to see if the line might be a - printer status line: - handle them so that most severe condition is shown */ - int i; - strlower(line); - - switch (status->status) { - case LPSTAT_OK: - for (i=0; stat0_strings[i]; i++) - if (strstr(line,stat0_strings[i])) { - StrnCpy(status->message,line,sizeof(status->message)-1); - status->status=LPSTAT_OK; - return ret; - } - case LPSTAT_STOPPED: - for (i=0; stat1_strings[i]; i++) - if (strstr(line,stat1_strings[i])) { - StrnCpy(status->message,line,sizeof(status->message)-1); - status->status=LPSTAT_STOPPED; - return ret; - } - case LPSTAT_ERROR: - for (i=0; stat2_strings[i]; i++) - if (strstr(line,stat2_strings[i])) { - StrnCpy(status->message,line,sizeof(status->message)-1); - status->status=LPSTAT_ERROR; - return ret; - } - break; - } - } - - return(ret); -} /**************************************************************************** get a printer queue -- cgit From c3043695ae507b34580dc1287418ff5704b6f625 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Apr 2000 13:00:12 +0000 Subject: rather than doing print file open processing in open.c we now handle it in print_open_file() that removes a lot of special cases in open.c and makes the print handling code much easier to understand. there is still lots to do in printing.c, but this at least gets printing separated from the mainline code (This used to be commit e064422af335cd791752a2b54a17a13467ace041) --- source3/printing/printing.c | 74 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 7edb69de27..e75871b3c5 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -395,3 +395,77 @@ void load_printers(void) if (lp_load_printers()) add_all_printers(); } + + +void print_open_file(files_struct *fsp,connection_struct *conn,char *fname) +{ + pstring template; + char *p; + SMB_STRUCT_STAT sbuf; + extern struct current_user current_user; + + /* see if we have sufficient disk space */ + if (lp_minprintspace(SNUM(conn))) { + SMB_BIG_UINT dum1,dum2,dum3; + if (conn->vfs_ops.disk_free(conn->connectpath,False,&dum1,&dum2,&dum3) < + (SMB_BIG_UINT)lp_minprintspace(SNUM(conn))) { + errno = ENOSPC; + return; + } + } + + slprintf(template, sizeof(template), "%s/smb.XXXXXX", conn->connectpath); + p = smbd_mktemp(template); + if (!p) { + DEBUG(2,("Error creating temporary filename in %s\n", + conn->connectpath)); + errno = ENOSPC; + return; + } + + fsp->fd = conn->vfs_ops.open(p,O_RDWR|O_CREAT|O_EXCL,0600); + + if (fsp->fd == -1) { + DEBUG(3,("Error opening file %s\n",p)); + return; + } + + /* + * If the printer is marked as postscript output a leading + * file identifier to ensure the file is treated as a raw + * postscript file. + * This has a similar effect as CtrlD=0 in WIN.INI file. + * tim@fsg.com 09/06/94 + */ + if (lp_postscript(SNUM(conn))) { + DEBUG(3,("Writing postscript line\n")); + conn->vfs_ops.write(fsp->fd,"%!\n",3); + } + + /* setup a full fsp */ + conn->vfs_ops.fstat(fsp->fd, &sbuf); + conn->num_files_open++; + fsp->mode = sbuf.st_mode; + fsp->inode = sbuf.st_ino; + fsp->dev = sbuf.st_dev; + GetTimeOfDay(&fsp->open_time); + fsp->vuid = current_user.vuid; + fsp->size = 0; + fsp->pos = -1; + fsp->open = True; + fsp->can_lock = True; + fsp->can_read = False; + fsp->can_write = True; + fsp->share_mode = 0; + fsp->print_file = True; + fsp->modified = False; + fsp->oplock_type = NO_OPLOCK; + fsp->sent_oplock_break = NO_BREAK_SENT; + fsp->is_directory = False; + fsp->stat_open = False; + fsp->directory_delete_on_close = False; + fsp->conn = conn; + string_set(&fsp->fsp_name,p); + fsp->wbmpx_ptr = NULL; + fsp->wcp = NULL; +} -- cgit From 5711f1f196a9caf4dc0de4c3121e920995ebe1bd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Apr 2000 06:20:02 +0000 Subject: the bulk of the changes. Also split the loadparm related code into printing/load.c so swat can get it without linking to the backend code ------------ The following series of commits are for the new tdb based printing backend. This completely replaces our old printing backend. Major changes include: - all print ops are now done in printing/*.c rather than scattered all over the place - system job ids are decoupled from SMB job ids - the lpq parsers don't need to be nearly so smart, they only need to parse the filename, the status and system job id - we can store lots more info about a job, including the full job name - the queue cache control is much better I also added a new utility routine file_lines_load() that loads a text file and parses it into lines. This is used in out lpq parsing and I also want to use it to replace all of our fgets() based code in other places. (This used to be commit a902caf8d78ae4cb11ea3776d10273cb37d5fcd0) --- source3/printing/printing.c | 1037 ++++++++++++++++++++++++++++++------------- 1 file changed, 728 insertions(+), 309 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index e75871b3c5..5eb77c9f55 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1,8 +1,8 @@ /* Unix SMB/Netbios implementation. - Version 1.9. - printing routines - Copyright (C) Andrew Tridgell 1992-1998 + Version 3.0 + printing backend routines + Copyright (C) Andrew Tridgell 1992-2000 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,414 +22,602 @@ #include "includes.h" extern int DEBUGLEVEL; -static BOOL * lpq_cache_reset=NULL; +/* + the printing backend revolves around a tdb database that stores the + SMB view of the print queue + + The key for this database is a jobid - a internally generated number that + uniquely identifies a print job -static int check_lpq_cache(int snum) { - static int lpq_caches=0; - - if (lpq_caches <= snum) { - BOOL * p; - p = (BOOL *) Realloc(lpq_cache_reset,(snum+1)*sizeof(BOOL)); - if (p) { - lpq_cache_reset=p; - lpq_caches = snum+1; - } - } - return lpq_caches; + reading the print queue involves two steps: + - possibly running lpq and updating the internal database from that + - reading entries from the database + + jobids are assigned when a job starts spooling. +*/ + +struct printjob { + pid_t pid; /* which process launched the job */ + int sysjob; /* the system (lp) job number */ + int fd; /* file descriptor of open file if open */ + time_t starttime; /* when the job started spooling */ + int status; /* the status of this job */ + size_t size; /* the size of the job so far */ + BOOL spooled; /* has it been sent to the spooler yet? */ + BOOL smbjob; /* set if the job is a SMB job */ + fstring filename; /* the filename used to spool the file */ + fstring jobname; /* the job name given to us by the client */ + fstring user; /* the user who started the job */ + fstring qname; /* name of the print queue the job was sent to */ +}; + +/* the open printing.tdb database */ +static TDB_CONTEXT *tdb; +static pid_t local_pid; + +#define PRINT_MAX_JOBID 10000 +#define UNIX_JOB_START PRINT_MAX_JOBID + +#define PRINT_SPOOL_PREFIX "smbprn." +#define PRINT_DATABASE_VERSION 1 + +/**************************************************************************** +initialise the printing backend. Called once at startup. +Does not survive a fork +****************************************************************************/ +BOOL print_backend_init(void) +{ + if (tdb && local_pid == getpid()) return True; + tdb = tdb_open(lock_path("printing.tdb"), 0, 0, O_RDWR|O_CREAT, 0600); + if (!tdb) { + DEBUG(0,("Failed to open printing backend database\n")); + } + local_pid = getpid(); + + /* handle a Samba upgrade */ + tdb_writelock(tdb); + if (tdb_get_int(tdb, "INFO/version") != PRINT_DATABASE_VERSION) { + tdb_traverse(tdb, tdb_delete, NULL); + tdb_store_int(tdb, "INFO/version", PRINT_DATABASE_VERSION); + } + tdb_writeunlock(tdb); + + return True; } -void lpq_reset(int snum) +/**************************************************************************** +useful function to generate a tdb key +****************************************************************************/ +static TDB_DATA print_key(int jobid) { - if (check_lpq_cache(snum) > snum) lpq_cache_reset[snum]=True; + static int j; + TDB_DATA ret; + + j = jobid; + ret.dptr = (void *)&j; + ret.dsize = sizeof(j); + return ret; } +/**************************************************************************** +useful function to find a print job in the database +****************************************************************************/ +static struct printjob *print_job_find(int jobid) +{ + static struct printjob pjob; + TDB_DATA ret; + + ret = tdb_fetch(tdb, print_key(jobid)); + if (!ret.dptr || ret.dsize != sizeof(pjob)) return NULL; + + memcpy(&pjob, ret.dptr, sizeof(pjob)); + free(ret.dptr); + return &pjob; +} /**************************************************************************** -Build the print command in the supplied buffer. This means getting the -print command for the service and inserting the printer name and the -print file name. Return NULL on error, else the passed buffer pointer. +store a job structure back to the database ****************************************************************************/ -static char *build_print_command(connection_struct *conn, - char *command, - char *syscmd, char *filename) +static BOOL print_job_store(int jobid, struct printjob *pjob) { - int snum = SNUM(conn); - char *tstr; - - /* get the print command for the service. */ - tstr = command; - if (!syscmd || !tstr) { - DEBUG(0,("No print command for service `%s'\n", - SERVICE(snum))); - return (NULL); - } + TDB_DATA d; + d.dptr = (void *)pjob; + d.dsize = sizeof(*pjob); + return (0 == tdb_store(tdb, print_key(jobid), d, TDB_REPLACE)); +} - /* copy the command into the buffer for extensive meddling. */ - StrnCpy(syscmd, tstr, sizeof(pstring) - 1); - - /* look for "%s" in the string. If there is no %s, we cannot print. */ - if (!strstr(syscmd, "%s") && !strstr(syscmd, "%f")) { - DEBUG(2,("WARNING! No placeholder for the filename in the print command for service %s!\n", SERVICE(snum))); - } - - pstring_sub(syscmd, "%s", filename); - pstring_sub(syscmd, "%f", filename); - - /* Does the service have a printername? If not, make a fake - and empty */ - /* printer name. That way a %p is treated sanely if no printer */ - /* name was specified to replace it. This eventuality is logged. */ - tstr = PRINTERNAME(snum); - if (tstr == NULL || tstr[0] == '\0') { - DEBUG(3,( "No printer name - using %s.\n", SERVICE(snum))); - tstr = SERVICE(snum); - } +/**************************************************************************** +run a given print command +****************************************************************************/ +static int print_run_command(int snum,char *command, + char *outfile, + char *a1, char *v1, + char *a2, char *v2) +{ + pstring syscmd; + char *p; + int ret; + + pstrcpy(syscmd, command); + if (a1) pstring_sub(syscmd, a1, v1); + if (a2) pstring_sub(syscmd, a2, v2); - pstring_sub(syscmd, "%p", tstr); + p = PRINTERNAME(snum); + if (!p || !*p) p = SERVICE(snum); - standard_sub(conn,syscmd); + pstring_sub(syscmd, "%p", p); + standard_sub_snum(snum,syscmd); - return (syscmd); + ret = smbrun(syscmd,outfile,False); + + DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); + return ret; } /**************************************************************************** -print a file - called on closing the file +parse a file name from the system spooler to generate a jobid ****************************************************************************/ -void print_file(connection_struct *conn, files_struct *file) +static int print_parse_jobid(char *fname) { - pstring syscmd; - int snum = SNUM(conn); - char *tempstr; + int jobid; - *syscmd = 0; + if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0) return -1; + fname += strlen(PRINT_SPOOL_PREFIX); - if (dos_file_size(file->fsp_name) <= 0) { - DEBUG(3,("Discarding null print job %s\n",file->fsp_name)); - dos_unlink(file->fsp_name); - return; - } + jobid = atoi(fname); + if (jobid <= 0) return -1; - tempstr = build_print_command(conn, - PRINTCOMMAND(snum), - syscmd, file->fsp_name); - if (tempstr != NULL) { - int ret = smbrun(syscmd,NULL,False); - DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); - } else { - DEBUG(0,("Null print command?\n")); - } - - lpq_reset(snum); + return jobid; } /**************************************************************************** -get a printer queue +list a unix job in the print database ****************************************************************************/ -int get_printqueue(int snum, - connection_struct *conn,print_queue_struct **queue, - print_status_struct *status) +static void print_unix_job(int snum, print_queue_struct *q) { - char *lpq_command = lp_lpqcommand(snum); - char *printername = PRINTERNAME(snum); - int ret=0,count=0; - pstring syscmd; - fstring outfile; - pstring line; - FILE *f; - SMB_STRUCT_STAT sbuf; - BOOL dorun=True; - int cachetime = lp_lpqcachetime(); - - *line = 0; - check_lpq_cache(snum); - - if (!printername || !*printername) { - DEBUG(6,("xx replacing printer name with service (snum=(%s,%d))\n", - lp_servicename(snum),snum)); - printername = lp_servicename(snum); - } - - if (!lpq_command || !(*lpq_command)) { - DEBUG(5,("No lpq command\n")); - return(0); - } - - pstrcpy(syscmd,lpq_command); - pstring_sub(syscmd,"%p",printername); + int jobid = q->job + UNIX_JOB_START; + struct printjob pj; + + ZERO_STRUCT(pj); + + pj.pid = (pid_t)-1; + pj.sysjob = q->job; + pj.fd = -1; + pj.starttime = q->time; + pj.status = q->status; + pj.size = q->size; + pj.spooled = True; + pj.smbjob = False; + fstrcpy(pj.filename, ""); + fstrcpy(pj.jobname, q->file); + fstrcpy(pj.user, q->user); + fstrcpy(pj.qname, lp_servicename(snum)); + + print_job_store(jobid, &pj); +} - standard_sub(conn,syscmd); - slprintf(outfile,sizeof(outfile)-1, "%s/lpq.%08x",tmpdir(),str_checksum(syscmd)); - - if (!lpq_cache_reset[snum] && cachetime && !sys_stat(outfile,&sbuf)) { - if (time(NULL) - sbuf.st_mtime < cachetime) { - DEBUG(3,("Using cached lpq output\n")); - dorun = False; - } - } +struct traverse_struct { + print_queue_struct *queue; + int qcount, snum; +}; + +static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) +{ + struct traverse_struct *ts = (struct traverse_struct *)state; + struct printjob pjob; + int i, jobid; + + if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0; + memcpy(&jobid, key.dptr, sizeof(jobid)); + memcpy(&pjob, data.dptr, sizeof(pjob)); - if (dorun) { - ret = smbrun(syscmd,outfile,True); - DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); + if (strcmp(lp_servicename(ts->snum), pjob.qname)) { + /* this isn't for the queue we are looking at */ + return 0; } - lpq_cache_reset[snum] = False; + if (!pjob.smbjob) { + /* remove a unix job if it isn't in the system queue + any more */ + for (i=0;iqcount;i++) { + if (jobid == ts->queue[i].job + UNIX_JOB_START) break; + } + if (i == ts->qcount) tdb_delete(tdb, key); + return 0; + } - f = sys_fopen(outfile,"r"); - if (!f) { - return(0); + /* maybe it hasn't been spooled yet */ + if (!pjob.spooled) { + /* if a job is not spooled and the process doesn't + exist then kill it. This cleans up after smbd + deaths */ + if (!process_exists(pjob.pid)) { + tdb_delete(tdb, key); + } + return 0; } - if (status) { - fstrcpy(status->message,""); - status->status = LPSTAT_OK; + for (i=0;iqcount;i++) { + int qid = print_parse_jobid(ts->queue[i].file); + if (jobid == qid) break; } - while (fgets(line,sizeof(pstring),f)) { - DEBUG(6,("QUEUE2: %s\n",line)); - - *queue = Realloc(*queue,sizeof(print_queue_struct)*(count+1)); - if (! *queue) { - count = 0; + if (i == ts->qcount) { + /* the job isn't in the system queue - we have to + assume it has completed, so delete the database + entry */ + tdb_delete(t, key); + } + + return 0; +} + +/**************************************************************************** +check if the print queue has been updated recently enough +****************************************************************************/ +static void print_cache_flush(int snum) +{ + fstring key; + slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum)); + tdb_store_int(tdb, key, -1); +} + +/**************************************************************************** +update the internal database from the system print queue for a queue +****************************************************************************/ +static void print_queue_update(int snum) +{ + char *path = lp_pathname(snum); + char *cmd = lp_lpqcommand(snum); + char **qlines; + pstring tmpfile; + int numlines, i, qcount; + print_queue_struct *queue = NULL; + print_status_struct status; + struct printjob *pjob; + struct traverse_struct tstruct; + fstring keystr; + TDB_DATA data, key; + + slprintf(tmpfile, sizeof(tmpfile), "%s/smblpq.%d", path, local_pid); + + unlink(tmpfile); + print_run_command(snum, cmd, tmpfile, + NULL, NULL, NULL, NULL); + + numlines = 0; + qlines = file_lines_load(tmpfile, &numlines); + unlink(tmpfile); + + /* turn the lpq output into a series of job structures */ + qcount = 0; + ZERO_STRUCT(status); + for (i=0; isysjob = queue[i].job; + pjob->status = queue[i].status; + + print_job_store(jobid, pjob); } - return(count); + + /* now delete any queued entries that don't appear in the + system queue */ + tstruct.queue = queue; + tstruct.qcount = qcount; + tstruct.snum = snum; + + tdb_traverse(tdb, traverse_fn_delete, (void *)&tstruct); + + safe_free(tstruct.queue); + + /* store the queue status structure */ + slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum)); + data.dptr = (void *)&status; + data.dsize = sizeof(status); + key.dptr = keystr; + key.dsize = strlen(keystr); + tdb_store(tdb, key, data, TDB_REPLACE); + + /* update the cache time */ + slprintf(keystr, sizeof(keystr), "CACHE/%s", lp_servicename(snum)); + tdb_store_int(tdb, keystr, (int)time(NULL)); +} + +/**************************************************************************** +check if a jobid is valid. It is valid if it exists in the database +****************************************************************************/ +BOOL print_job_exists(int jobid) +{ + return tdb_exists(tdb, print_key(jobid)); } /**************************************************************************** -delete a printer queue entry +work out which service a jobid is for +note that we have to look up by queue name to ensure that it works for +other than the process that started the job ****************************************************************************/ -void del_printqueue(connection_struct *conn,int snum,int jobid) -{ - char *lprm_command = lp_lprmcommand(snum); - char *printername = PRINTERNAME(snum); - pstring syscmd; - char jobstr[20]; - int ret; - - if (!printername || !*printername) - { - DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n", - lp_servicename(snum),snum)); - printername = lp_servicename(snum); - } - - if (!lprm_command || !(*lprm_command)) - { - DEBUG(5,("No lprm command\n")); - return; - } - - slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid); - - pstrcpy(syscmd,lprm_command); - pstring_sub(syscmd,"%p",printername); - pstring_sub(syscmd,"%j",jobstr); - standard_sub(conn,syscmd); - - ret = smbrun(syscmd,NULL,False); - DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); - lpq_reset(snum); /* queue has changed */ +int print_job_snum(int jobid) +{ + struct printjob *pjob = print_job_find(jobid); + if (!pjob) return -1; + + return lp_servicenumber(pjob->qname); } /**************************************************************************** -change status of a printer queue entry +give the fd used for a jobid ****************************************************************************/ -void status_printjob(connection_struct *conn,int snum,int jobid,int status) -{ - char *lpstatus_command = - (status==LPQ_PAUSED?lp_lppausecommand(snum):lp_lpresumecommand(snum)); - char *printername = PRINTERNAME(snum); - pstring syscmd; - char jobstr[20]; - int ret; - - if (!printername || !*printername) - { - DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n", - lp_servicename(snum),snum)); - printername = lp_servicename(snum); - } - - if (!lpstatus_command || !(*lpstatus_command)) - { - DEBUG(5,("No lpstatus command to %s job\n", - (status==LPQ_PAUSED?"pause":"resume"))); - return; - } - - slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid); - - pstrcpy(syscmd,lpstatus_command); - pstring_sub(syscmd,"%p",printername); - pstring_sub(syscmd,"%j",jobstr); - standard_sub(conn,syscmd); - - ret = smbrun(syscmd,NULL,False); - DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); - lpq_reset(snum); /* queue has changed */ +int print_job_fd(int jobid) +{ + struct printjob *pjob = print_job_find(jobid); + if (!pjob) return -1; + /* don't allow another process to get this info - it is meaningless */ + if (pjob->pid != local_pid) return -1; + return pjob->fd; } +/**************************************************************************** +give the filename used for a jobid +only valid for the process doing the spooling and when the job +has not been spooled +****************************************************************************/ +char *print_job_fname(int jobid) +{ + struct printjob *pjob = print_job_find(jobid); + if (!pjob || pjob->spooled || pjob->pid != local_pid) return NULL; + return pjob->filename; +} /**************************************************************************** -we encode print job numbers over the wire so that when we get them back we can -tell not only what print job they are but also what service it belongs to, -this is to overcome the problem that windows clients tend to send the wrong -service number when doing print queue manipulation! +set the place in the queue for a job ****************************************************************************/ -int printjob_encode(int snum, int job) +BOOL print_job_set_place(int jobid, int place) { - return ((snum&0xFF)<<8) | (job & 0xFF); + DEBUG(2,("print_job_set_place not implemented yet\n")); + return False; } /**************************************************************************** -and now decode them again ... +set the name of a job. Only possible for owner ****************************************************************************/ -void printjob_decode(int jobid, int *snum, int *job) +BOOL print_job_set_name(int jobid, char *name) { - (*snum) = (jobid >> 8) & 0xFF; - (*job) = jobid & 0xFF; + struct printjob *pjob = print_job_find(jobid); + if (!pjob || pjob->pid != local_pid) return False; + + fstrcpy(pjob->jobname, name); + return print_job_store(jobid, pjob); } + /**************************************************************************** - Change status of a printer queue +delete a print job - don't update queue ****************************************************************************/ - -void status_printqueue(connection_struct *conn,int snum,int status) +static BOOL print_job_delete1(int jobid) { - char *queuestatus_command = (status==LPSTAT_STOPPED ? - lp_queuepausecommand(snum):lp_queueresumecommand(snum)); - char *printername = PRINTERNAME(snum); - pstring syscmd; - int ret; + struct printjob *pjob = print_job_find(jobid); + int snum; - if (!printername || !*printername) { - DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n", - lp_servicename(snum),snum)); - printername = lp_servicename(snum); - } + if (!pjob) return False; - if (!queuestatus_command || !(*queuestatus_command)) { - DEBUG(5,("No queuestatus command to %s job\n", - (status==LPSTAT_STOPPED?"pause":"resume"))); - return; - } + snum = print_job_snum(jobid); - pstrcpy(syscmd,queuestatus_command); - pstring_sub(syscmd,"%p",printername); - standard_sub(conn,syscmd); + if (pjob->spooled && pjob->sysjob != -1) { + /* need to delete the spooled entry */ + fstring jobstr; + slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob); + print_run_command(snum, + lp_lprmcommand(snum), NULL, + "%j", jobstr, + NULL, NULL); + } - ret = smbrun(syscmd,NULL,False); - DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); - lpq_reset(snum); /* queue has changed */ + return True; } - - -/*************************************************************************** -auto-load printer services -***************************************************************************/ -static void add_all_printers(void) +/**************************************************************************** +delete a print job +****************************************************************************/ +BOOL print_job_delete(int jobid) { - int printers = lp_servicenumber(PRINTERS_NAME); + int snum = print_job_snum(jobid); + + if (!print_job_delete1(jobid)) return False; - if (printers < 0) return; + /* force update the database and say the delete failed if the + job still exists */ + print_queue_update(snum); - pcap_printer_fn(lp_add_one_printer); + return !print_job_exists(jobid); } -/*************************************************************************** -auto-load some homes and printer services -***************************************************************************/ -static void add_auto_printers(void) + +/**************************************************************************** +pause a job +****************************************************************************/ +BOOL print_job_pause(int jobid) { - char *p; - int printers; - char *str = lp_auto_services(); + struct printjob *pjob = print_job_find(jobid); + int snum; + if (!pjob) return False; + + snum = print_job_snum(jobid); + + if (pjob->spooled && pjob->sysjob != -1) { + /* need to pause the spooled entry */ + fstring jobstr; + slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob); + print_run_command(snum, + lp_lppausecommand(snum), NULL, + "%j", jobstr, + NULL, NULL); + } - if (!str) return; + /* force update the database */ + print_cache_flush(snum); - printers = lp_servicenumber(PRINTERS_NAME); + /* how do we tell if this succeeded? */ + return True; +} - if (printers < 0) return; - - for (p=strtok(str,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) { - if (lp_servicenumber(p) >= 0) continue; - - if (pcap_printername_ok(p,NULL)) { - lp_add_printer(p,printers); - } +/**************************************************************************** +resume a job +****************************************************************************/ +BOOL print_job_resume(int jobid) +{ + struct printjob *pjob = print_job_find(jobid); + int snum; + if (!pjob) return False; + + snum = print_job_snum(jobid); + + if (pjob->spooled && pjob->sysjob != -1) { + fstring jobstr; + slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob); + print_run_command(snum, + lp_lpresumecommand(snum), NULL, + "%j", jobstr, + NULL, NULL); } + + /* force update the database */ + print_cache_flush(snum); + + /* how do we tell if this succeeded? */ + return True; } -/*************************************************************************** -load automatic printer services -***************************************************************************/ -void load_printers(void) +/**************************************************************************** +write to a print file +****************************************************************************/ +int print_job_write(int jobid, const char *buf, int size) { - add_auto_printers(); - if (lp_load_printers()) - add_all_printers(); + int fd; + + fd = print_job_fd(jobid); + if (fd == -1) return -1; + + return write(fd, buf, size); } -void print_open_file(files_struct *fsp,connection_struct *conn,char *fname) +/*************************************************************************** +start spooling a job - return the jobid +***************************************************************************/ +int print_job_start(int snum, char *jobname) { - pstring template; - char *p; - SMB_STRUCT_STAT sbuf; + int jobid; + char *path; + struct printjob pjob; + int next_jobid; extern struct current_user current_user; + path = lp_pathname(snum); + /* see if we have sufficient disk space */ - if (lp_minprintspace(SNUM(conn))) { + if (lp_minprintspace(snum)) { SMB_BIG_UINT dum1,dum2,dum3; - if (conn->vfs_ops.disk_free(conn->connectpath,False,&dum1,&dum2,&dum3) < - (SMB_BIG_UINT)lp_minprintspace(SNUM(conn))) { + if (sys_disk_free(path,False,&dum1,&dum2,&dum3) < + (SMB_BIG_UINT)lp_minprintspace(snum)) { errno = ENOSPC; - return; + return -1; } } - slprintf(template, sizeof(template), "%s/smb.XXXXXX", conn->connectpath); - p = smbd_mktemp(template); - if (!p) { - DEBUG(2,("Error creating temporary filename in %s\n", - conn->connectpath)); - errno = ENOSPC; - return; + /* create the database entry */ + ZERO_STRUCT(pjob); + pjob.pid = local_pid; + pjob.sysjob = -1; + pjob.fd = -1; + pjob.starttime = time(NULL); + pjob.status = LPQ_QUEUED; + pjob.size = 0; + pjob.spooled = False; + pjob.smbjob = True; + + fstrcpy(pjob.jobname, jobname); + fstrcpy(pjob.user, uidtoname(current_user.uid)); + fstrcpy(pjob.qname, lp_servicename(snum)); + + /* lock the database */ + tdb_writelock(tdb); + + next_jobid = tdb_get_int(tdb, "INFO/nextjob"); + if (next_jobid == -1) next_jobid = 1; + + for (jobid = next_jobid+1; jobid != next_jobid; ) { + if (!print_job_exists(jobid)) break; + jobid = (jobid + 1) % PRINT_MAX_JOBID; + if (jobid == 0) jobid = 1; + } + if (jobid == next_jobid || !print_job_store(jobid, &pjob)) { + jobid = -1; + goto fail; } - fsp->fd = conn->vfs_ops.open(p,O_RDWR|O_CREAT|O_EXCL,0600); + tdb_store_int(tdb, "INFO/nextjob", jobid); - if (fsp->fd == -1) { - DEBUG(3,("Error opening file %s\n",p)); - return; + /* we have a job entry - now create the spool file + + we unlink first to cope with old spool files and also to beat + a symlink security hole - it allows us to use O_EXCL + */ + slprintf(pjob.filename, sizeof(pjob.filename), "%s/%s%d", + path, PRINT_SPOOL_PREFIX, jobid); + if (unlink(pjob.filename) == -1 && errno != ENOENT) { + goto fail; } - + pjob.fd = sys_open(pjob.filename,O_WRONLY|O_CREAT|O_EXCL,0600); + if (pjob.fd == -1) goto fail; + + print_job_store(jobid, &pjob); + /* * If the printer is marked as postscript output a leading * file identifier to ensure the file is treated as a raw @@ -437,12 +625,231 @@ void print_open_file(files_struct *fsp,connection_struct *conn,char *fname) * This has a similar effect as CtrlD=0 in WIN.INI file. * tim@fsg.com 09/06/94 */ - if (lp_postscript(SNUM(conn))) { - DEBUG(3,("Writing postscript line\n")); - conn->vfs_ops.write(fsp->fd,"%!\n",3); + if (lp_postscript(snum)) { + print_job_write(jobid, "%!\n",3); } + tdb_writeunlock(tdb); + return jobid; + + fail: + if (jobid != -1) { + tdb_delete(tdb, print_key(jobid)); + } + + tdb_writeunlock(tdb); + return jobid; +} + +/**************************************************************************** +print a file - called on closing the file. This spools the job +****************************************************************************/ +BOOL print_job_end(int jobid) +{ + struct printjob *pjob = print_job_find(jobid); + int snum; + SMB_STRUCT_STAT sbuf; + pstring current_directory; + pstring print_directory; + char *wd, *p; + + if (!pjob) return False; + + if (pjob->spooled || pjob->pid != local_pid) return False; + + snum = print_job_snum(jobid); + + if (sys_fstat(pjob->fd, &sbuf) == 0) pjob->size = sbuf.st_size; + + close(pjob->fd); + pjob->fd = -1; + + if (pjob->size == 0) { + /* don't bother spooling empty files */ + unlink(pjob->filename); + tdb_delete(tdb, print_key(jobid)); + return True; + } + + /* we print from the directory path to give the best chance of + parsing the lpq output */ + wd = sys_getwd(current_directory); + if (!wd) return False; + + pstrcpy(print_directory, pjob->filename); + p = strrchr(print_directory,'/'); + if (!p) return False; + *p++ = 0; + + if (chdir(print_directory) != 0) return False; + + /* send it to the system spooler */ + print_run_command(snum, + lp_printcommand(snum), NULL, + "%s", p, + "%f", p); + + chdir(wd); + + pjob->spooled = True; + print_job_store(jobid, pjob); + + /* force update the database */ + print_cache_flush(snum); + + return True; +} + + +/**************************************************************************** +check if the print queue has been updated recently enough +****************************************************************************/ +static BOOL print_cache_expired(int snum) +{ + fstring key; + time_t t2, t = time(NULL); + slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum)); + t2 = tdb_get_int(tdb, key); + if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) { + return True; + } + return False; +} + +static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) +{ + struct traverse_struct *ts = (struct traverse_struct *)state; + struct printjob pjob; + int i, jobid; + + if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0; + memcpy(&jobid, key.dptr, sizeof(jobid)); + memcpy(&pjob, data.dptr, sizeof(pjob)); + + /* maybe it isn't for this queue */ + if (ts->snum != print_queue_snum(pjob.qname)) return 0; + + ts->queue = Realloc(ts->queue,sizeof(print_queue_struct)*(ts->qcount+1)); + if (!ts->queue) return -1; + i = ts->qcount; + + ts->queue[i].job = jobid; + ts->queue[i].size = pjob.size; + ts->queue[i].status = pjob.status; + ts->queue[i].priority = 0; + ts->queue[i].time = pjob.starttime; + fstrcpy(ts->queue[i].user, pjob.user); + fstrcpy(ts->queue[i].file, pjob.jobname); + + ts->qcount++; + + return 0; +} + +/**************************************************************************** +get a printer queue listing +****************************************************************************/ +int print_queue_status(int snum, + print_queue_struct **queue, + print_status_struct *status) +{ + struct traverse_struct tstruct; + fstring keystr; + TDB_DATA data, key; + + /* make sure the database is up to date */ + if (print_cache_expired(snum)) print_queue_update(snum); + + /* fill in the queue */ + tstruct.queue = NULL; + tstruct.qcount = 0; + tstruct.snum = snum; + + tdb_traverse(tdb, traverse_fn_queue, (void *)&tstruct); + + /* also fetch the queue status */ + ZERO_STRUCTP(status); + slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum)); + key.dptr = keystr; + key.dsize = strlen(keystr); + data = tdb_fetch(tdb, key); + if (data.dptr) { + if (data.dsize == sizeof(*status)) { + memcpy(status, data.dptr, sizeof(*status)); + } + free(data.dptr); + } + + *queue = tstruct.queue; + return tstruct.qcount; +} + + +/**************************************************************************** +turn a queue name into a snum +****************************************************************************/ +int print_queue_snum(char *qname) +{ + int snum = lp_servicenumber(qname); + if (snum == -1 || !lp_print_ok(snum)) return -1; + return snum; +} + + +/**************************************************************************** + pause a queue +****************************************************************************/ +BOOL print_queue_pause(int snum) +{ + /* not currently supported */ + return False; +} + +/**************************************************************************** + resume a queue +****************************************************************************/ +BOOL print_queue_resume(int snum) +{ + /* not currently supported */ + return False; +} + +/**************************************************************************** + purge a queue - implemented by deleting all jobs that we can delete +****************************************************************************/ +BOOL print_queue_purge(int snum) +{ + print_queue_struct *queue; + print_status_struct status; + int njobs, i; + + njobs = print_queue_status(snum, &queue, &status); + for (i=0;iprint_jobid = jobid; + fsp->fd = print_job_fd(jobid); conn->vfs_ops.fstat(fsp->fd, &sbuf); conn->num_files_open++; fsp->mode = sbuf.st_mode; @@ -465,7 +872,19 @@ void print_open_file(files_struct *fsp,connection_struct *conn,char *fname) fsp->stat_open = False; fsp->directory_delete_on_close = False; fsp->conn = conn; - string_set(&fsp->fsp_name,p); + string_set(&fsp->fsp_name,print_job_fname(jobid)); fsp->wbmpx_ptr = NULL; fsp->wcp = NULL; } + +/**************************************************************************** +print a file - called on closing the file +****************************************************************************/ +void print_fsp_end(files_struct *fsp) +{ + print_job_end(fsp->print_jobid); + + if (fsp->fsp_name) { + string_free(&fsp->fsp_name); + } +} -- cgit From 7ee1c906f4418440ce3f110f6cae84c186cf1163 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Apr 2000 08:03:37 +0000 Subject: improved the error handling and added queue pause and resume (This used to be commit 5f5b79c9264510f5851ad1d6f3ce9e2b15e4a0da) --- source3/printing/printing.c | 68 ++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 25 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 5eb77c9f55..27219657ea 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -138,6 +138,8 @@ static int print_run_command(int snum,char *command, char *p; int ret; + if (!command || !*command) return -1; + pstrcpy(syscmd, command); if (a1) pstring_sub(syscmd, a1, v1); if (a2) pstring_sub(syscmd, a2, v2); @@ -204,6 +206,7 @@ struct traverse_struct { int qcount, snum; }; +/* utility fn to delete any jobs that are no longer active */ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) { struct traverse_struct *ts = (struct traverse_struct *)state; @@ -484,26 +487,26 @@ pause a job BOOL print_job_pause(int jobid) { struct printjob *pjob = print_job_find(jobid); - int snum; + int snum, ret = -1; + fstring jobstr; if (!pjob) return False; + if (!pjob->spooled || pjob->sysjob == -1) return False; + snum = print_job_snum(jobid); - if (pjob->spooled && pjob->sysjob != -1) { - /* need to pause the spooled entry */ - fstring jobstr; - slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob); - print_run_command(snum, - lp_lppausecommand(snum), NULL, - "%j", jobstr, - NULL, NULL); - } + /* need to pause the spooled entry */ + slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob); + ret = print_run_command(snum, + lp_lppausecommand(snum), NULL, + "%j", jobstr, + NULL, NULL); /* force update the database */ print_cache_flush(snum); /* how do we tell if this succeeded? */ - return True; + return ret == 0; } /**************************************************************************** @@ -512,25 +515,25 @@ resume a job BOOL print_job_resume(int jobid) { struct printjob *pjob = print_job_find(jobid); - int snum; + int snum, ret; + fstring jobstr; if (!pjob) return False; + if (!pjob->spooled || pjob->sysjob == -1) return False; + snum = print_job_snum(jobid); - if (pjob->spooled && pjob->sysjob != -1) { - fstring jobstr; - slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob); - print_run_command(snum, - lp_lpresumecommand(snum), NULL, - "%j", jobstr, - NULL, NULL); - } + slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob); + ret = print_run_command(snum, + lp_lpresumecommand(snum), NULL, + "%j", jobstr, + NULL, NULL); /* force update the database */ print_cache_flush(snum); /* how do we tell if this succeeded? */ - return True; + return ret == 0; } /**************************************************************************** @@ -716,6 +719,7 @@ static BOOL print_cache_expired(int snum) return False; } +/* utility fn to enumerate the print queue */ static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) { struct traverse_struct *ts = (struct traverse_struct *)state; @@ -801,8 +805,15 @@ int print_queue_snum(char *qname) ****************************************************************************/ BOOL print_queue_pause(int snum) { - /* not currently supported */ - return False; + int ret = print_run_command(snum, + lp_queuepausecommand(snum), NULL, + NULL, NULL, + NULL, NULL); + + /* force update the database */ + print_cache_flush(snum); + + return ret == 0; } /**************************************************************************** @@ -810,8 +821,15 @@ BOOL print_queue_pause(int snum) ****************************************************************************/ BOOL print_queue_resume(int snum) { - /* not currently supported */ - return False; + int ret = print_run_command(snum, + lp_queueresumecommand(snum), NULL, + NULL, NULL, + NULL, NULL); + + /* force update the database */ + print_cache_flush(snum); + + return ret == 0; } /**************************************************************************** -- cgit From 4217c939ec6bdb80a3fe953e5b60f6f7b7a43635 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Apr 2000 20:41:04 +0000 Subject: locking/locking.c: Fixed placeholder code for POSIX locking. printing/printing.c: Cast tdb_delete to (tdb_traverse_func) to stop warning. tmpfile gives mirror warning. smbd/groupname.c: Remember to file_lines_free() on exit. tdb/tdb.h: Add tdb_traverse_func typedef. Jeremy (This used to be commit 204ca1195c86499bd9beb273ce573db7a56ccead) --- source3/printing/printing.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 27219657ea..8fa9d7db25 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -77,7 +77,7 @@ BOOL print_backend_init(void) /* handle a Samba upgrade */ tdb_writelock(tdb); if (tdb_get_int(tdb, "INFO/version") != PRINT_DATABASE_VERSION) { - tdb_traverse(tdb, tdb_delete, NULL); + tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL); tdb_store_int(tdb, "INFO/version", PRINT_DATABASE_VERSION); } tdb_writeunlock(tdb); @@ -276,7 +276,7 @@ static void print_queue_update(int snum) char *path = lp_pathname(snum); char *cmd = lp_lpqcommand(snum); char **qlines; - pstring tmpfile; + pstring tmp_file; int numlines, i, qcount; print_queue_struct *queue = NULL; print_status_struct status; @@ -285,15 +285,15 @@ static void print_queue_update(int snum) fstring keystr; TDB_DATA data, key; - slprintf(tmpfile, sizeof(tmpfile), "%s/smblpq.%d", path, local_pid); + slprintf(tmp_file, sizeof(tmp_file), "%s/smblpq.%d", path, local_pid); - unlink(tmpfile); - print_run_command(snum, cmd, tmpfile, + unlink(tmp_file); + print_run_command(snum, cmd, tmp_file, NULL, NULL, NULL, NULL); numlines = 0; - qlines = file_lines_load(tmpfile, &numlines); - unlink(tmpfile); + qlines = file_lines_load(tmp_file, &numlines); + unlink(tmp_file); /* turn the lpq output into a series of job structures */ qcount = 0; -- cgit From b7a1d19d114288ac3292a26d2d42825e26884d36 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Apr 2000 08:44:56 +0000 Subject: use sys_fsusage() not disk_free() in printing.c (This used to be commit 763704f78fc44976b2d977e8a08ffdeb727903c4) --- source3/printing/printing.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 8fa9d7db25..3202c6937d 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -565,9 +565,9 @@ int print_job_start(int snum, char *jobname) /* see if we have sufficient disk space */ if (lp_minprintspace(snum)) { - SMB_BIG_UINT dum1,dum2,dum3; - if (sys_disk_free(path,False,&dum1,&dum2,&dum3) < - (SMB_BIG_UINT)lp_minprintspace(snum)) { + SMB_BIG_UINT dspace, dsize; + if (sys_fsusage(path, &dspace, &dsize) == 0 && + dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) { errno = ENOSPC; return -1; } -- cgit From 6259f51dd9918eccc9697f3763d918f7c9b82b50 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 22 Apr 2000 00:33:16 +0000 Subject: This is a *big* checkin that may break some things, but implements the new open mechanism Andrew & I discussed. config.sub: configure: Included the QNX patch. include/vfs.h: smbd/vfs-wrap.c: smbd/vfs.c: Added ftruncate vfs call (needed). Note that we will also need locking calls in the vfs (to be added). lib/util_unistr.c: nmbd/nmbd_processlogon.c: Fix for NT domain logons causing nmbd to core dump. Also fix for sidsize DOS bug. locking/locking.c: Check value of ret before using it for memdup. printing/printing.c: Convert print_fsp_open to return an allocated fsp. rpc_server/srv_lsa.c: Fix for NT domain logons. I have removed all use of lp_share_modes() from the code (although I left the parameter in the table for backwards compatibility). It no longer makes sense for this to exist. smbd/close.c: Removed lp_share_modes(). smbd/fileio.c: Fixed parameters to unlock_share_entry call in panic code. smbd/files.c: Correctly set the unix_ERR_code to ERRnofids on fsp allocation fail. smbd/nttrans.c: smbd/reply.c: smbd/trans2.c: Changed all occurrences of open_file_shared/open_directory/ open_file_stat to return an fsp from the call. smbd/open.c: Changed all occurrences of open_file_shared/open_directory/ open_file_stat to return an fsp from the call. In addition I have fixed a long standing race condition in the deny mode processing w.r.t. two smbd's creating a file. Andrew, please note that your original idea of using open with O_EXCL in this case would not work (I went over the races very carefully) and so we must re-check deny modes *after* the open() call returns. This is because there is a race between the open with O_EXCL and the lock of the share mode entry. Imagine the case where the first smbd does the open with O_EXCL and a deny mode of DENY_ALL, but is pre-empted before it locks the share modes and creates the deny mode entry for DENY_ALL. A second smbd could then come in with O_RDONLY and a deny mode of DENY_NONE and the two opens would be allowed. The *only* way to fix this race is to lock the share modes after the open and then do the deny mode checks *after* this lock in the case where the file did not originally exist. This code will need extensive testing but seems to initially work. Jeremy. (This used to be commit ab0ecc39d688f16b9692fe90b991f0b89287070a) --- source3/printing/printing.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 3202c6937d..58f284b4fc 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -856,20 +856,27 @@ BOOL print_queue_purge(int snum) open a print file and setup a fsp for it. This is a wrapper around print_job_start(). ***************************************************************************/ -void print_fsp_open(files_struct *fsp,connection_struct *conn,char *jobname) + +files_struct *print_fsp_open(connection_struct *conn,char *jobname) { int jobid; SMB_STRUCT_STAT sbuf; extern struct current_user current_user; + files_struct *fsp = file_new(); + + if(!fsp) + return NULL; jobid = print_job_start(SNUM(conn), jobname); - if (jobid == -1) return; + if (jobid == -1) { + file_free(fsp); + return NULL; + } /* setup a full fsp */ fsp->print_jobid = jobid; fsp->fd = print_job_fd(jobid); conn->vfs_ops.fstat(fsp->fd, &sbuf); - conn->num_files_open++; fsp->mode = sbuf.st_mode; fsp->inode = sbuf.st_ino; fsp->dev = sbuf.st_dev; @@ -893,6 +900,10 @@ void print_fsp_open(files_struct *fsp,connection_struct *conn,char *jobname) string_set(&fsp->fsp_name,print_job_fname(jobid)); fsp->wbmpx_ptr = NULL; fsp->wcp = NULL; + + conn->num_files_open++; + + return fsp; } /**************************************************************************** -- cgit From 943471f2c83325e7ec52e952f57b4cc294856ced Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Apr 2000 07:51:15 +0000 Subject: split fsp specific routines out of printing.c to fix linking problem in TNG (This used to be commit 82df25b28b94b0041676fb433e0e677acb544579) --- source3/printing/printing.c | 65 --------------------------------------------- 1 file changed, 65 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 58f284b4fc..6e9482ad4e 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -852,68 +852,3 @@ BOOL print_queue_purge(int snum) } -/*************************************************************************** -open a print file and setup a fsp for it. This is a wrapper around -print_job_start(). -***************************************************************************/ - -files_struct *print_fsp_open(connection_struct *conn,char *jobname) -{ - int jobid; - SMB_STRUCT_STAT sbuf; - extern struct current_user current_user; - files_struct *fsp = file_new(); - - if(!fsp) - return NULL; - - jobid = print_job_start(SNUM(conn), jobname); - if (jobid == -1) { - file_free(fsp); - return NULL; - } - - /* setup a full fsp */ - fsp->print_jobid = jobid; - fsp->fd = print_job_fd(jobid); - conn->vfs_ops.fstat(fsp->fd, &sbuf); - fsp->mode = sbuf.st_mode; - fsp->inode = sbuf.st_ino; - fsp->dev = sbuf.st_dev; - GetTimeOfDay(&fsp->open_time); - fsp->vuid = current_user.vuid; - fsp->size = 0; - fsp->pos = -1; - fsp->open = True; - fsp->can_lock = True; - fsp->can_read = False; - fsp->can_write = True; - fsp->share_mode = 0; - fsp->print_file = True; - fsp->modified = False; - fsp->oplock_type = NO_OPLOCK; - fsp->sent_oplock_break = NO_BREAK_SENT; - fsp->is_directory = False; - fsp->stat_open = False; - fsp->directory_delete_on_close = False; - fsp->conn = conn; - string_set(&fsp->fsp_name,print_job_fname(jobid)); - fsp->wbmpx_ptr = NULL; - fsp->wcp = NULL; - - conn->num_files_open++; - - return fsp; -} - -/**************************************************************************** -print a file - called on closing the file -****************************************************************************/ -void print_fsp_end(files_struct *fsp) -{ - print_job_end(fsp->print_jobid); - - if (fsp->fsp_name) { - string_free(&fsp->fsp_name); - } -} -- cgit From 31446a98a3c39eb0e48ba056fe07832e807d91fe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Apr 2000 08:13:12 +0000 Subject: check for a valid snum when running a printing command (This used to be commit 381ddb464fd0da671d567177f1ded10f67952692) --- source3/printing/printing.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 6e9482ad4e..2f36cf2f3f 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -140,6 +140,11 @@ static int print_run_command(int snum,char *command, if (!command || !*command) return -1; + if (!VALID_SNUM(snum)) { + DEBUG(0,("Invalid snum %d for command %s\n", snum, command)); + return -1; + } + pstrcpy(syscmd, command); if (a1) pstring_sub(syscmd, a1, v1); if (a2) pstring_sub(syscmd, a2, v2); -- cgit From 693ffb8466ada58ecc59fde754ba79fc6f51528d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 2 May 2000 02:23:41 +0000 Subject: Added sys_fork() and sys_getpid() functions to stop the overhead of doing a system call every time we want to just get our pid. Jeremy. (This used to be commit 148628b616b5c29ba6340d65fc3ddbcabba6e67a) --- source3/printing/printing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 2f36cf2f3f..95aa50fb43 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -67,12 +67,12 @@ Does not survive a fork ****************************************************************************/ BOOL print_backend_init(void) { - if (tdb && local_pid == getpid()) return True; + if (tdb && local_pid == sys_getpid()) return True; tdb = tdb_open(lock_path("printing.tdb"), 0, 0, O_RDWR|O_CREAT, 0600); if (!tdb) { DEBUG(0,("Failed to open printing backend database\n")); } - local_pid = getpid(); + local_pid = sys_getpid(); /* handle a Samba upgrade */ tdb_writelock(tdb); -- cgit From e48b4ec4c5849992b04ed5d293d524779cb7a43a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 May 2000 11:49:06 +0000 Subject: fail a print start on a deleted auto printer (This used to be commit f1f92bf4da75ec6fccd34b07719d642196665258) --- source3/printing/printing.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 95aa50fb43..b23dd3aa73 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -578,6 +578,12 @@ int print_job_start(int snum, char *jobname) } } + /* for autoloaded printers, check that the printcap entry still exists */ + if (lp_autoloaded(snum) && !pcap_printername_ok(lp_servicename(snum), NULL)) { + errno = ENOENT; + return -1; + } + /* create the database entry */ ZERO_STRUCT(pjob); pjob.pid = local_pid; -- cgit From 4cdc54ba244f72a4a143e7a0e0c0b4fcfaa13d3c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 12 May 2000 06:27:35 +0000 Subject: While we're all making incompatible tdb changes, I changed the implementation of tdb_{store,get}_int() to store the length of the string key + 1 so the stored key contains the trailing NULL character. This allows normal string library routines to manipulate keys. Also renamed tdb_get_int() to tdb_fetch_int() to keep the set of verbs consistent. (This used to be commit a423c7c5f21dc4046530b85482dee88dcfcbf070) --- source3/printing/printing.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index b23dd3aa73..0a2f494a27 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -76,7 +76,7 @@ BOOL print_backend_init(void) /* handle a Samba upgrade */ tdb_writelock(tdb); - if (tdb_get_int(tdb, "INFO/version") != PRINT_DATABASE_VERSION) { + if (tdb_fetch_int(tdb, "INFO/version") != PRINT_DATABASE_VERSION) { tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL); tdb_store_int(tdb, "INFO/version", PRINT_DATABASE_VERSION); } @@ -602,7 +602,7 @@ int print_job_start(int snum, char *jobname) /* lock the database */ tdb_writelock(tdb); - next_jobid = tdb_get_int(tdb, "INFO/nextjob"); + next_jobid = tdb_fetch_int(tdb, "INFO/nextjob"); if (next_jobid == -1) next_jobid = 1; for (jobid = next_jobid+1; jobid != next_jobid; ) { @@ -723,7 +723,7 @@ static BOOL print_cache_expired(int snum) fstring key; time_t t2, t = time(NULL); slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum)); - t2 = tdb_get_int(tdb, key); + t2 = tdb_fetch_int(tdb, key); if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) { return True; } -- cgit From a95efec534410cb96ab2e801eb601331b15ca23c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 May 2000 06:10:21 +0000 Subject: a fairly big change in spoolss. got rid of the forms, drivers and printers files in the nt drivers directory and instead use a single tdb note that this is _not_ all finished. (This used to be commit 06763d1ec2fafc42f8ee3f36f0aeacceb3a7109d) --- source3/printing/printing.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 0a2f494a27..7d57a810ee 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -82,7 +82,7 @@ BOOL print_backend_init(void) } tdb_writeunlock(tdb); - return True; + return nt_printing_init(); } /**************************************************************************** @@ -463,6 +463,9 @@ static BOOL print_job_delete1(int jobid) print_run_command(snum, lp_lprmcommand(snum), NULL, "%j", jobstr, + /* + "%T", http_timestring(pjob->starttime), + */ NULL, NULL); } @@ -701,6 +704,7 @@ BOOL print_job_end(int jobid) print_run_command(snum, lp_printcommand(snum), NULL, "%s", p, + /* "%J", stripquote(pjob->jobname), */ "%f", p); chdir(wd); -- cgit From 843120837caf6f32324982dc3c12cf79465cf581 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Jun 2000 06:18:43 +0000 Subject: added %J and %T to run_print_command() made the run_print_command a varargs fn (This used to be commit b9f2cf459322fb3f10844f9441633c7bcd6ed151) --- source3/printing/printing.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 7d57a810ee..662bc606a1 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -128,15 +128,17 @@ static BOOL print_job_store(int jobid, struct printjob *pjob) /**************************************************************************** run a given print command +a null terminated list of value/substitute pairs is provided +for local substitution strings ****************************************************************************/ static int print_run_command(int snum,char *command, char *outfile, - char *a1, char *v1, - char *a2, char *v2) + ...) { pstring syscmd; - char *p; + char *p, *arg; int ret; + va_list ap; if (!command || !*command) return -1; @@ -146,8 +148,13 @@ static int print_run_command(int snum,char *command, } pstrcpy(syscmd, command); - if (a1) pstring_sub(syscmd, a1, v1); - if (a2) pstring_sub(syscmd, a2, v2); + + va_start(ap, outfile); + while ((arg = va_arg(ap, char *))) { + char *value = va_arg(ap,char *); + pstring_sub(syscmd, arg, value); + } + va_end(ap); p = PRINTERNAME(snum); if (!p || !*p) p = SERVICE(snum); @@ -294,7 +301,7 @@ static void print_queue_update(int snum) unlink(tmp_file); print_run_command(snum, cmd, tmp_file, - NULL, NULL, NULL, NULL); + NULL); numlines = 0; qlines = file_lines_load(tmp_file, &numlines); @@ -463,10 +470,8 @@ static BOOL print_job_delete1(int jobid) print_run_command(snum, lp_lprmcommand(snum), NULL, "%j", jobstr, - /* "%T", http_timestring(pjob->starttime), - */ - NULL, NULL); + NULL); } return True; @@ -508,7 +513,7 @@ BOOL print_job_pause(int jobid) ret = print_run_command(snum, lp_lppausecommand(snum), NULL, "%j", jobstr, - NULL, NULL); + NULL); /* force update the database */ print_cache_flush(snum); @@ -535,7 +540,7 @@ BOOL print_job_resume(int jobid) ret = print_run_command(snum, lp_lpresumecommand(snum), NULL, "%j", jobstr, - NULL, NULL); + NULL); /* force update the database */ print_cache_flush(snum); @@ -669,6 +674,7 @@ BOOL print_job_end(int jobid) pstring current_directory; pstring print_directory; char *wd, *p; + pstring jobname; if (!pjob) return False; @@ -700,12 +706,16 @@ BOOL print_job_end(int jobid) if (chdir(print_directory) != 0) return False; + pstrcpy(jobname, pjob->jobname); + pstring_sub(jobname, "'", "_"); + /* send it to the system spooler */ print_run_command(snum, lp_printcommand(snum), NULL, "%s", p, - /* "%J", stripquote(pjob->jobname), */ - "%f", p); + "%J", jobname, + "%f", p, + NULL); chdir(wd); @@ -822,8 +832,7 @@ BOOL print_queue_pause(int snum) { int ret = print_run_command(snum, lp_queuepausecommand(snum), NULL, - NULL, NULL, - NULL, NULL); + NULL); /* force update the database */ print_cache_flush(snum); @@ -838,8 +847,7 @@ BOOL print_queue_resume(int snum) { int ret = print_run_command(snum, lp_queueresumecommand(snum), NULL, - NULL, NULL, - NULL, NULL); + NULL); /* force update the database */ print_cache_flush(snum); -- cgit From ccc32898cf56baf93581b3773cb1d82ce0e59b8d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 16 Jun 2000 08:21:51 +0000 Subject: Call print_access_check() function from printing back end. (This used to be commit 979e083d3dd844b98b03108e636dfe11ae157fb0) --- source3/printing/printing.c | 60 +++++++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 15 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 662bc606a1..9ba6288a68 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -480,10 +480,15 @@ static BOOL print_job_delete1(int jobid) /**************************************************************************** delete a print job ****************************************************************************/ -BOOL print_job_delete(int jobid) +BOOL print_job_delete(uint16 vuid, int jobid) { int snum = print_job_snum(jobid); + if (!print_access_check(snum, vuid, PRINTER_ACE_MANAGE_DOCUMENTS)) { + DEBUG(3, ("delete denied by security descriptor\n")); + return False; + } + if (!print_job_delete1(jobid)) return False; /* force update the database and say the delete failed if the @@ -497,7 +502,7 @@ BOOL print_job_delete(int jobid) /**************************************************************************** pause a job ****************************************************************************/ -BOOL print_job_pause(int jobid) +BOOL print_job_pause(uint16 vuid, int jobid) { struct printjob *pjob = print_job_find(jobid); int snum, ret = -1; @@ -508,6 +513,11 @@ BOOL print_job_pause(int jobid) snum = print_job_snum(jobid); + if (!print_access_check(snum, vuid, PRINTER_ACE_MANAGE_DOCUMENTS)) { + DEBUG(3, ("pause denied by security descriptor\n")); + return False; + } + /* need to pause the spooled entry */ slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob); ret = print_run_command(snum, @@ -525,7 +535,7 @@ BOOL print_job_pause(int jobid) /**************************************************************************** resume a job ****************************************************************************/ -BOOL print_job_resume(int jobid) +BOOL print_job_resume(uint16 vuid, int jobid) { struct printjob *pjob = print_job_find(jobid); int snum, ret; @@ -536,6 +546,11 @@ BOOL print_job_resume(int jobid) snum = print_job_snum(jobid); + if (!print_access_check(snum, vuid, PRINTER_ACE_MANAGE_DOCUMENTS)) { + DEBUG(3, ("resume denied by security descriptor\n")); + return False; + } + slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob); ret = print_run_command(snum, lp_lpresumecommand(snum), NULL, @@ -566,7 +581,7 @@ int print_job_write(int jobid, const char *buf, int size) /*************************************************************************** start spooling a job - return the jobid ***************************************************************************/ -int print_job_start(int snum, char *jobname) +int print_job_start(int snum, uint16 vuid, char *jobname) { int jobid; char *path; @@ -574,6 +589,11 @@ int print_job_start(int snum, char *jobname) int next_jobid; extern struct current_user current_user; + if (!print_access_check(snum, vuid, PRINTER_ACE_PRINT)) { + DEBUG(3, ("job start denied by security descriptor\n")); + return False; + } + path = lp_pathname(snum); /* see if we have sufficient disk space */ @@ -828,11 +848,15 @@ int print_queue_snum(char *qname) /**************************************************************************** pause a queue ****************************************************************************/ -BOOL print_queue_pause(int snum) +BOOL print_queue_pause(int snum, uint16 vuid) { - int ret = print_run_command(snum, - lp_queuepausecommand(snum), NULL, - NULL); + int ret; + + if (!print_access_check(snum, vuid, PRINTER_ACE_MANAGE_DOCUMENTS)) { + return False; + } + + ret = print_run_command(snum, lp_queuepausecommand(snum), NULL, NULL); /* force update the database */ print_cache_flush(snum); @@ -843,11 +867,15 @@ BOOL print_queue_pause(int snum) /**************************************************************************** resume a queue ****************************************************************************/ -BOOL print_queue_resume(int snum) +BOOL print_queue_resume(int snum, uint16 vuid) { - int ret = print_run_command(snum, - lp_queueresumecommand(snum), NULL, - NULL); + int ret; + + if (!print_access_check(snum, vuid, PRINTER_ACE_MANAGE_DOCUMENTS)) { + return False; + } + + ret = print_run_command(snum, lp_queueresumecommand(snum), NULL, NULL); /* force update the database */ print_cache_flush(snum); @@ -858,12 +886,16 @@ BOOL print_queue_resume(int snum) /**************************************************************************** purge a queue - implemented by deleting all jobs that we can delete ****************************************************************************/ -BOOL print_queue_purge(int snum) +BOOL print_queue_purge(int snum, uint16 vuid) { print_queue_struct *queue; print_status_struct status; int njobs, i; + if (!print_access_check(snum, vuid, PRINTER_ACE_MANAGE_DOCUMENTS)) { + return False; + } + njobs = print_queue_status(snum, &queue, &status); for (i=0;i Date: Thu, 6 Jul 2000 07:06:05 +0000 Subject: Implemented NT printer descriptor checking. Yay! User details are passed into the printing back end from the spoolss code. For each print operation these details are checked using the se_access_check() function using information from the winbind daemon. Fixed bug in nt_printing_setsec() where the user and group SIDs were trashed if the permissions were changed from NT. It is necessary to merge these sids from the previous value of the security descriptor before storing it in the tdb. (This used to be commit 8d42661d424d80e1048d08b5cad3281643231d62) --- source3/printing/printing.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 9ba6288a68..80d1884aea 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -480,11 +480,11 @@ static BOOL print_job_delete1(int jobid) /**************************************************************************** delete a print job ****************************************************************************/ -BOOL print_job_delete(uint16 vuid, int jobid) +BOOL print_job_delete(struct current_user *user, int jobid) { int snum = print_job_snum(jobid); - if (!print_access_check(snum, vuid, PRINTER_ACE_MANAGE_DOCUMENTS)) { + if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { DEBUG(3, ("delete denied by security descriptor\n")); return False; } @@ -502,7 +502,7 @@ BOOL print_job_delete(uint16 vuid, int jobid) /**************************************************************************** pause a job ****************************************************************************/ -BOOL print_job_pause(uint16 vuid, int jobid) +BOOL print_job_pause(struct current_user *user, int jobid) { struct printjob *pjob = print_job_find(jobid); int snum, ret = -1; @@ -513,7 +513,7 @@ BOOL print_job_pause(uint16 vuid, int jobid) snum = print_job_snum(jobid); - if (!print_access_check(snum, vuid, PRINTER_ACE_MANAGE_DOCUMENTS)) { + if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { DEBUG(3, ("pause denied by security descriptor\n")); return False; } @@ -535,7 +535,7 @@ BOOL print_job_pause(uint16 vuid, int jobid) /**************************************************************************** resume a job ****************************************************************************/ -BOOL print_job_resume(uint16 vuid, int jobid) +BOOL print_job_resume(struct current_user *user, int jobid) { struct printjob *pjob = print_job_find(jobid); int snum, ret; @@ -546,7 +546,7 @@ BOOL print_job_resume(uint16 vuid, int jobid) snum = print_job_snum(jobid); - if (!print_access_check(snum, vuid, PRINTER_ACE_MANAGE_DOCUMENTS)) { + if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { DEBUG(3, ("resume denied by security descriptor\n")); return False; } @@ -581,7 +581,7 @@ int print_job_write(int jobid, const char *buf, int size) /*************************************************************************** start spooling a job - return the jobid ***************************************************************************/ -int print_job_start(int snum, uint16 vuid, char *jobname) +int print_job_start(struct current_user *user, int snum, char *jobname) { int jobid; char *path; @@ -589,7 +589,7 @@ int print_job_start(int snum, uint16 vuid, char *jobname) int next_jobid; extern struct current_user current_user; - if (!print_access_check(snum, vuid, PRINTER_ACE_PRINT)) { + if (!print_access_check(user, snum, PRINTER_ACE_PRINT)) { DEBUG(3, ("job start denied by security descriptor\n")); return False; } @@ -848,11 +848,11 @@ int print_queue_snum(char *qname) /**************************************************************************** pause a queue ****************************************************************************/ -BOOL print_queue_pause(int snum, uint16 vuid) +BOOL print_queue_pause(struct current_user *user, int snum) { int ret; - if (!print_access_check(snum, vuid, PRINTER_ACE_MANAGE_DOCUMENTS)) { + if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { return False; } @@ -867,11 +867,11 @@ BOOL print_queue_pause(int snum, uint16 vuid) /**************************************************************************** resume a queue ****************************************************************************/ -BOOL print_queue_resume(int snum, uint16 vuid) +BOOL print_queue_resume(struct current_user *user, int snum) { int ret; - if (!print_access_check(snum, vuid, PRINTER_ACE_MANAGE_DOCUMENTS)) { + if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { return False; } @@ -886,13 +886,13 @@ BOOL print_queue_resume(int snum, uint16 vuid) /**************************************************************************** purge a queue - implemented by deleting all jobs that we can delete ****************************************************************************/ -BOOL print_queue_purge(int snum, uint16 vuid) +BOOL print_queue_purge(struct current_user *user, int snum) { print_queue_struct *queue; print_status_struct status; int njobs, i; - if (!print_access_check(snum, vuid, PRINTER_ACE_MANAGE_DOCUMENTS)) { + if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { return False; } -- cgit From 89eafd3ceffc7b4965133f6ddc059a134eaffb61 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 Jul 2000 23:31:46 +0000 Subject: printing/nt_printing.c: (From JF) use the driver name - already given to us. printing/printing.c: priority needs to be 1 not zero (found by checked build). rpc_server/srv_spoolss_nt.c: Log invalid handle access, also print out if this is a different pid handle. This will help track down client access after a connection is closed. Jeremy. (This used to be commit 4ff949228c40b6abb2008df8db985562ac2895d2) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 80d1884aea..9a2994856d 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -785,7 +785,7 @@ static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void * ts->queue[i].job = jobid; ts->queue[i].size = pjob.size; ts->queue[i].status = pjob.status; - ts->queue[i].priority = 0; + ts->queue[i].priority = 1; ts->queue[i].time = pjob.starttime; fstrcpy(ts->queue[i].user, pjob.user); fstrcpy(ts->queue[i].file, pjob.jobname); -- cgit From 78a4848e8da7bb4f96e99e3419c5473c4c23bb6d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 10 Jul 2000 05:08:21 +0000 Subject: Re-instated lanman printing security checks (oops). A user can now pause, resume or delete their own job even if they don't have the Manage Documents privilege. Added call to se_access_check() for changing printer properties. The Full Access privilege is required for the user to perform this. Several uninitialised variables and memory leaks plugged. Modified default ACL created on new printers to be Everyone / Print instead of Everyone / Full Access. This required some random stuffing around with the value of the revision field to correspond with the ACL that NT produces when setting the same permission on the printer. Fixed dodgy function call in printing/printfsp.c (This used to be commit 2abce4dcfa351051df6e5f789b34fa99c9b81c22) --- source3/printing/printing.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 9a2994856d..2f1753b76c 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -477,6 +477,21 @@ static BOOL print_job_delete1(int jobid) return True; } +/* Return true if the uid owns the print job */ + +static BOOL is_owner(uid_t uid, int jobid) +{ + struct printjob *pjob = print_job_find(jobid); + struct passwd *pw; + + if (!pjob || !(pw = sys_getpwuid(uid))) return False; + + DEBUG(0, ("checking owner of jobid %d: %s == %s\n", + jobid, pw->pw_name, pjob->user)); + + return (pw && pjob && strequal(pw->pw_name, pjob->user)); +} + /**************************************************************************** delete a print job ****************************************************************************/ @@ -484,7 +499,11 @@ BOOL print_job_delete(struct current_user *user, int jobid) { int snum = print_job_snum(jobid); - if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { + /* Check access against security descriptor or whether the user + owns their job. */ + + if (!is_owner(user->uid, jobid) && + !print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { DEBUG(3, ("delete denied by security descriptor\n")); return False; } @@ -513,7 +532,8 @@ BOOL print_job_pause(struct current_user *user, int jobid) snum = print_job_snum(jobid); - if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { + if (!is_owner(user->uid, jobid) && + !print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { DEBUG(3, ("pause denied by security descriptor\n")); return False; } @@ -546,7 +566,8 @@ BOOL print_job_resume(struct current_user *user, int jobid) snum = print_job_snum(jobid); - if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { + if (!is_owner(user->uid, jobid) && + !print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { DEBUG(3, ("resume denied by security descriptor\n")); return False; } -- cgit From 3733229fafb8634b40f53d01dc6f71c2cfcbba54 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 17 Jul 2000 02:42:25 +0000 Subject: Allow job owner to delete own print job. (This used to be commit 90b1857c81627e587a7395ee2bdb51b26ea46512) --- source3/printing/printing.c | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 2f1753b76c..64d5a7c4b1 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -159,7 +159,7 @@ static int print_run_command(int snum,char *command, p = PRINTERNAME(snum); if (!p || !*p) p = SERVICE(snum); - pstring_sub(syscmd, "%p", p); + pstring_sub(syscmd, "%p", p); standard_sub_snum(snum,syscmd); ret = smbrun(syscmd,outfile,False); @@ -477,8 +477,9 @@ static BOOL print_job_delete1(int jobid) return True; } -/* Return true if the uid owns the print job */ - +/**************************************************************************** +return true if the uid owns the print job +****************************************************************************/ static BOOL is_owner(uid_t uid, int jobid) { struct printjob *pjob = print_job_find(jobid); @@ -486,9 +487,6 @@ static BOOL is_owner(uid_t uid, int jobid) if (!pjob || !(pw = sys_getpwuid(uid))) return False; - DEBUG(0, ("checking owner of jobid %d: %s == %s\n", - jobid, pw->pw_name, pjob->user)); - return (pw && pjob && strequal(pw->pw_name, pjob->user)); } @@ -498,11 +496,16 @@ delete a print job BOOL print_job_delete(struct current_user *user, int jobid) { int snum = print_job_snum(jobid); + BOOL owner; + + if (!user) return False; + owner = is_owner(user->uid, jobid); + /* Check access against security descriptor or whether the user owns their job. */ - if (!is_owner(user->uid, jobid) && + if (!owner && !print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { DEBUG(3, ("delete denied by security descriptor\n")); return False; @@ -512,6 +515,7 @@ BOOL print_job_delete(struct current_user *user, int jobid) /* force update the database and say the delete failed if the job still exists */ + print_queue_update(snum); return !print_job_exists(jobid); @@ -526,13 +530,17 @@ BOOL print_job_pause(struct current_user *user, int jobid) struct printjob *pjob = print_job_find(jobid); int snum, ret = -1; fstring jobstr; - if (!pjob) return False; + BOOL owner; + + + if (!pjob || !user) return False; if (!pjob->spooled || pjob->sysjob == -1) return False; snum = print_job_snum(jobid); + owner = is_owner(user->uid, jobid); - if (!is_owner(user->uid, jobid) && + if (!owner && !print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { DEBUG(3, ("pause denied by security descriptor\n")); return False; @@ -560,11 +568,14 @@ BOOL print_job_resume(struct current_user *user, int jobid) struct printjob *pjob = print_job_find(jobid); int snum, ret; fstring jobstr; - if (!pjob) return False; + BOOL owner; + + if (!pjob || !user) return False; if (!pjob->spooled || pjob->sysjob == -1) return False; snum = print_job_snum(jobid); + owner = is_owner(user->uid, jobid); if (!is_owner(user->uid, jobid) && !print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { @@ -872,12 +883,15 @@ int print_queue_snum(char *qname) BOOL print_queue_pause(struct current_user *user, int snum) { int ret; - + + if (!user) return False; + if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { return False; } - ret = print_run_command(snum, lp_queuepausecommand(snum), NULL, NULL); + ret = print_run_command(snum, lp_queuepausecommand(snum), NULL, + NULL); /* force update the database */ print_cache_flush(snum); @@ -896,7 +910,8 @@ BOOL print_queue_resume(struct current_user *user, int snum) return False; } - ret = print_run_command(snum, lp_queueresumecommand(snum), NULL, NULL); + ret = print_run_command(snum, lp_queueresumecommand(snum), NULL, + NULL); /* force update the database */ print_cache_flush(snum); -- cgit From d95777ac34f68a3525786103b9217f6397d9f1d4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Aug 2000 00:41:19 +0000 Subject: Added print job substitutions for %{printername}, %{sharename} and %{portname} from the NT printer tdb. Also added checks for time restrictions before allowing a job to print. Jeremy. (This used to be commit 8cfb55e81abebf0354e6d470ed68bbac1d6560ad) --- source3/printing/printing.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 64d5a7c4b1..c6252b8fb1 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -716,8 +716,9 @@ int print_job_start(struct current_user *user, int snum, char *jobname) } /**************************************************************************** -print a file - called on closing the file. This spools the job + Print a file - called on closing the file. This spools the job. ****************************************************************************/ + BOOL print_job_end(int jobid) { struct printjob *pjob = print_job_find(jobid); @@ -728,13 +729,16 @@ BOOL print_job_end(int jobid) char *wd, *p; pstring jobname; - if (!pjob) return False; + if (!pjob) + return False; - if (pjob->spooled || pjob->pid != local_pid) return False; + if (pjob->spooled || pjob->pid != local_pid) + return False; snum = print_job_snum(jobid); - if (sys_fstat(pjob->fd, &sbuf) == 0) pjob->size = sbuf.st_size; + if (sys_fstat(pjob->fd, &sbuf) == 0) + pjob->size = sbuf.st_size; close(pjob->fd); pjob->fd = -1; @@ -749,14 +753,17 @@ BOOL print_job_end(int jobid) /* we print from the directory path to give the best chance of parsing the lpq output */ wd = sys_getwd(current_directory); - if (!wd) return False; + if (!wd) + return False; pstrcpy(print_directory, pjob->filename); p = strrchr(print_directory,'/'); - if (!p) return False; + if (!p) + return False; *p++ = 0; - if (chdir(print_directory) != 0) return False; + if (chdir(print_directory) != 0) + return False; pstrcpy(jobname, pjob->jobname); pstring_sub(jobname, "'", "_"); @@ -780,10 +787,10 @@ BOOL print_job_end(int jobid) return True; } - /**************************************************************************** -check if the print queue has been updated recently enough + Check if the print queue has been updated recently enough. ****************************************************************************/ + static BOOL print_cache_expired(int snum) { fstring key; -- cgit From db2445358161e1a0a68b80a7551ed88e7dcc38c6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 9 Aug 2000 04:19:18 +0000 Subject: added printer admin option any user in that list can do anything to a printer (This used to be commit 7b5912be150dd590d6195be40b0976305b8716ba) --- source3/printing/printing.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index c6252b8fb1..a6dc81b172 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1,3 +1,4 @@ +#define OLD_NTDOMAIN 1 /* Unix SMB/Netbios implementation. Version 3.0 @@ -948,3 +949,4 @@ BOOL print_queue_purge(struct current_user *user, int snum) return True; } +#undef OLD_NTDOMAIN -- cgit From f03879e0b3db1871d003bfb5713a88928f032260 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Aug 2000 23:05:49 +0000 Subject: Tidied up some error returns from printing calls. Still need to map UNIX errors to NT error for print job failure returns. Patch from John Reilly at HP. Jeremy. (This used to be commit 3514b5bb8fffd78e3647425d93b74e2e6291bafc) --- source3/printing/printing.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index a6dc81b172..f5f40d8b9c 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -622,6 +622,8 @@ int print_job_start(struct current_user *user, int snum, char *jobname) int next_jobid; extern struct current_user current_user; + errno = 0; + if (!print_access_check(user, snum, PRINTER_ACE_PRINT)) { DEBUG(3, ("job start denied by security descriptor\n")); return False; @@ -713,7 +715,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) } tdb_writeunlock(tdb); - return jobid; + return -1; } /**************************************************************************** -- cgit From d407579b94ee2647d1e51c536534024e5c4c51ad Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Aug 2000 00:45:59 +0000 Subject: Implemented AbortPrinter() from Gerald's Win32 test code. Just purge all possible printjobs from that printer (I think this is correct). Added error code returns for print_queue_XXX() functions. Jeremy. (This used to be commit 6d081a9017f87f59b7189ba507e211db01c40af5) --- source3/printing/printing.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index f5f40d8b9c..cf3748ed16 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -890,13 +890,14 @@ int print_queue_snum(char *qname) /**************************************************************************** pause a queue ****************************************************************************/ -BOOL print_queue_pause(struct current_user *user, int snum) +BOOL print_queue_pause(struct current_user *user, int snum, int *errcode) { int ret; if (!user) return False; if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { + *errcode = ERROR_ACCESS_DENIED; return False; } @@ -912,11 +913,12 @@ BOOL print_queue_pause(struct current_user *user, int snum) /**************************************************************************** resume a queue ****************************************************************************/ -BOOL print_queue_resume(struct current_user *user, int snum) +BOOL print_queue_resume(struct current_user *user, int snum, int *errcode) { int ret; if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { + *errcode = ERROR_ACCESS_DENIED; return False; } @@ -932,13 +934,14 @@ BOOL print_queue_resume(struct current_user *user, int snum) /**************************************************************************** purge a queue - implemented by deleting all jobs that we can delete ****************************************************************************/ -BOOL print_queue_purge(struct current_user *user, int snum) +BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) { print_queue_struct *queue; print_status_struct status; int njobs, i; if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { + *errcode = ERROR_ACCESS_DENIED; return False; } -- cgit From a3a28675fafbbc5a5a378b3a7235253d772ef63e Mon Sep 17 00:00:00 2001 From: David O'Neill Date: Fri, 1 Sep 2000 18:49:26 +0000 Subject: Changes from APPLIANCE_HEAD (per Tim Potter): - make proto - addition of function to convert from errno values to NT status codes (source/lib/error.c) - purge queue done without full access permission will purge only the jobs owned by that user, rather than failing. - unlock job database tdb before sending job to printer - in print_job_start(), ensure that we don't pick a jobid with an existing temporary file that may be owned by another user, as it causes silent failures. - fixes for printer permission checking for NT5 clients (source/include/rpc_spoolss.h, source/printing/nt_printing.c, source/printing/printing.c, source/rpc_server/srv_spoolss_nt.c) - change from uint8 to 'enum SID_NAME_USE' (source/rpc_server/srv_lsa.c) - fixed memory leaks for win95 driver download process (source/smbd/lanman.c) - properly free prs_structs and dacl in testsuite/printing/psec.c (This used to be commit 74af3e2caec7197e5d1ca389e2f78054a4197502) --- source3/printing/printing.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index cf3748ed16..406cbf2c80 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -507,7 +507,7 @@ BOOL print_job_delete(struct current_user *user, int jobid) owns their job. */ if (!owner && - !print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { + !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("delete denied by security descriptor\n")); return False; } @@ -542,7 +542,7 @@ BOOL print_job_pause(struct current_user *user, int jobid) owner = is_owner(user->uid, jobid); if (!owner && - !print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { + !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("pause denied by security descriptor\n")); return False; } @@ -579,7 +579,7 @@ BOOL print_job_resume(struct current_user *user, int jobid) owner = is_owner(user->uid, jobid); if (!is_owner(user->uid, jobid) && - !print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { + !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("resume denied by security descriptor\n")); return False; } @@ -624,9 +624,9 @@ int print_job_start(struct current_user *user, int snum, char *jobname) errno = 0; - if (!print_access_check(user, snum, PRINTER_ACE_PRINT)) { + if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) { DEBUG(3, ("job start denied by security descriptor\n")); - return False; + return -1; } path = lp_pathname(snum); @@ -665,6 +665,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) /* lock the database */ tdb_writelock(tdb); + next_jobnum: next_jobid = tdb_fetch_int(tdb, "INFO/nextjob"); if (next_jobid == -1) next_jobid = 1; @@ -684,17 +685,20 @@ int print_job_start(struct current_user *user, int snum, char *jobname) we unlink first to cope with old spool files and also to beat a symlink security hole - it allows us to use O_EXCL + There may be old spool files owned by other users lying around. */ slprintf(pjob.filename, sizeof(pjob.filename), "%s/%s%d", path, PRINT_SPOOL_PREFIX, jobid); if (unlink(pjob.filename) == -1 && errno != ENOENT) { - goto fail; + goto next_jobnum; } pjob.fd = sys_open(pjob.filename,O_WRONLY|O_CREAT|O_EXCL,0600); if (pjob.fd == -1) goto fail; print_job_store(jobid, &pjob); + tdb_writeunlock(tdb); + /* * If the printer is marked as postscript output a leading * file identifier to ensure the file is treated as a raw @@ -706,7 +710,6 @@ int print_job_start(struct current_user *user, int snum, char *jobname) print_job_write(jobid, "%!\n",3); } - tdb_writeunlock(tdb); return jobid; fail: @@ -896,7 +899,7 @@ BOOL print_queue_pause(struct current_user *user, int snum, int *errcode) if (!user) return False; - if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { + if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { *errcode = ERROR_ACCESS_DENIED; return False; } @@ -917,7 +920,7 @@ BOOL print_queue_resume(struct current_user *user, int snum, int *errcode) { int ret; - if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { + if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { *errcode = ERROR_ACCESS_DENIED; return False; } @@ -940,14 +943,11 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) print_status_struct status; int njobs, i; - if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) { - *errcode = ERROR_ACCESS_DENIED; - return False; - } - njobs = print_queue_status(snum, &queue, &status); for (i=0;i Date: Wed, 13 Sep 2000 02:24:35 +0000 Subject: Added time check test before allowing print job. Jeremy. (This used to be commit 0249de4cd91d72efb344e9fb05e2be2cb3f03945) --- source3/printing/printing.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 406cbf2c80..70917b214e 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -625,7 +625,12 @@ int print_job_start(struct current_user *user, int snum, char *jobname) errno = 0; if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) { - DEBUG(3, ("job start denied by security descriptor\n")); + DEBUG(3, ("print_job_start: job start denied by security descriptor\n")); + return -1; + } + + if (!print_time_access_check(snum)) { + DEBUG(3, ("print_job_start: job start denied by time check\n")); return -1; } -- cgit From a5ac83d2b2fe84d5e940d94269ae6fb61167a809 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 13 Sep 2000 04:42:06 +0000 Subject: When creating a print job entry for the printing backend, use the Windows username rather than the Unix username. The Windows username will then be shown in the port monitor regardless of the Unix username used to spool the job. (This used to be commit a15e610bb34636448cb30e590277c53e7f9efe1a) --- source3/printing/printing.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 70917b214e..28b5934c37 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -479,16 +479,20 @@ static BOOL print_job_delete1(int jobid) } /**************************************************************************** -return true if the uid owns the print job +return true if the current user owns the print job ****************************************************************************/ -static BOOL is_owner(uid_t uid, int jobid) +static BOOL is_owner(struct current_user *user, int jobid) { struct printjob *pjob = print_job_find(jobid); - struct passwd *pw; + user_struct *vuser; - if (!pjob || !(pw = sys_getpwuid(uid))) return False; + if (!pjob || !user) return False; - return (pw && pjob && strequal(pw->pw_name, pjob->user)); + if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { + return strequal(pjob->user, vuser->user.smb_name); + } else { + return strequal(pjob->user, uidtoname(user->uid)); + } } /**************************************************************************** @@ -501,7 +505,7 @@ BOOL print_job_delete(struct current_user *user, int jobid) if (!user) return False; - owner = is_owner(user->uid, jobid); + owner = is_owner(user, jobid); /* Check access against security descriptor or whether the user owns their job. */ @@ -539,7 +543,7 @@ BOOL print_job_pause(struct current_user *user, int jobid) if (!pjob->spooled || pjob->sysjob == -1) return False; snum = print_job_snum(jobid); - owner = is_owner(user->uid, jobid); + owner = is_owner(user, jobid); if (!owner && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { @@ -576,9 +580,9 @@ BOOL print_job_resume(struct current_user *user, int jobid) if (!pjob->spooled || pjob->sysjob == -1) return False; snum = print_job_snum(jobid); - owner = is_owner(user->uid, jobid); + owner = is_owner(user, jobid); - if (!is_owner(user->uid, jobid) && + if (!is_owner(user, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("resume denied by security descriptor\n")); return False; @@ -620,7 +624,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) char *path; struct printjob pjob; int next_jobid; - extern struct current_user current_user; + user_struct *vuser; errno = 0; @@ -664,7 +668,13 @@ int print_job_start(struct current_user *user, int snum, char *jobname) pjob.smbjob = True; fstrcpy(pjob.jobname, jobname); - fstrcpy(pjob.user, uidtoname(current_user.uid)); + + if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { + fstrcpy(pjob.user, vuser->user.smb_name); + } else { + fstrcpy(pjob.user, uidtoname(user->uid)); + } + fstrcpy(pjob.qname, lp_servicename(snum)); /* lock the database */ -- cgit From 2d33e87424197b993e8e7d218c0945cc2b66078a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Oct 2000 06:45:09 +0000 Subject: got rid of tdb_writelock() and instead lock a chain. tdb_writelock() is conceptually flawed (This used to be commit 6e4a3585521b7e5928298bd0f1418ff9fbcacfb4) --- source3/printing/printing.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 28b5934c37..b884c5ac99 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -68,6 +68,8 @@ Does not survive a fork ****************************************************************************/ BOOL print_backend_init(void) { + char *sversion = "INFO/version"; + if (tdb && local_pid == sys_getpid()) return True; tdb = tdb_open(lock_path("printing.tdb"), 0, 0, O_RDWR|O_CREAT, 0600); if (!tdb) { @@ -76,12 +78,12 @@ BOOL print_backend_init(void) local_pid = sys_getpid(); /* handle a Samba upgrade */ - tdb_writelock(tdb); - if (tdb_fetch_int(tdb, "INFO/version") != PRINT_DATABASE_VERSION) { + tdb_lock_bystring(tdb, sversion); + if (tdb_fetch_int(tdb, sversion) != PRINT_DATABASE_VERSION) { tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL); - tdb_store_int(tdb, "INFO/version", PRINT_DATABASE_VERSION); + tdb_store_int(tdb, sversion, PRINT_DATABASE_VERSION); } - tdb_writeunlock(tdb); + tdb_unlock_bystring(tdb, sversion); return nt_printing_init(); } @@ -678,7 +680,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) fstrcpy(pjob.qname, lp_servicename(snum)); /* lock the database */ - tdb_writelock(tdb); + tdb_lock_bystring(tdb, "INFO/nextjob"); next_jobnum: next_jobid = tdb_fetch_int(tdb, "INFO/nextjob"); @@ -712,7 +714,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) print_job_store(jobid, &pjob); - tdb_writeunlock(tdb); + tdb_unlock_bystring(tdb, "INFO/nextjob"); /* * If the printer is marked as postscript output a leading @@ -732,7 +734,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) tdb_delete(tdb, print_key(jobid)); } - tdb_writeunlock(tdb); + tdb_unlock_bystring(tdb, "INFO/nextjob"); return -1; } -- cgit From 30dbac7e02002ee482629593c1515bd47b799fdd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 10 Oct 2000 18:40:03 +0000 Subject: Fixed Realloc memory fragmentation problems. Jeremy. (This used to be commit 5518f59976ecac796a85db959cb9e8cc6c4d3504) --- source3/printing/printing.c | 74 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 17 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index b884c5ac99..9054c8f36a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -218,7 +218,7 @@ static void print_unix_job(int snum, print_queue_struct *q) struct traverse_struct { print_queue_struct *queue; - int qcount, snum; + int qcount, snum, maxcount; }; /* utility fn to delete any jobs that are no longer active */ @@ -313,18 +313,18 @@ static void print_queue_update(int snum) /* turn the lpq output into a series of job structures */ qcount = 0; ZERO_STRUCT(status); - for (i=0; isnum != print_queue_snum(pjob.qname)) return 0; - ts->queue = Realloc(ts->queue,sizeof(print_queue_struct)*(ts->qcount+1)); - if (!ts->queue) return -1; + if (ts->qcount >= ts->maxcount) return 0; + i = ts->qcount; ts->queue[i].job = jobid; @@ -857,6 +857,29 @@ static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void * return 0; } +struct traverse_count_struct { + int snum, count; +}; + +/* utility fn to count the number of entries in the print queue */ +static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) +{ + struct traverse_count_struct *ts = (struct traverse_count_struct *)state; + struct printjob pjob; + int jobid; + + if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0; + memcpy(&jobid, key.dptr, sizeof(jobid)); + memcpy(&pjob, data.dptr, sizeof(pjob)); + + /* maybe it isn't for this queue */ + if (ts->snum != print_queue_snum(pjob.qname)) return 0; + + ts->count++; + + return 0; +} + /**************************************************************************** get a printer queue listing ****************************************************************************/ @@ -865,15 +888,32 @@ int print_queue_status(int snum, print_status_struct *status) { struct traverse_struct tstruct; + struct traverse_count_struct tsc; fstring keystr; TDB_DATA data, key; /* make sure the database is up to date */ if (print_cache_expired(snum)) print_queue_update(snum); - /* fill in the queue */ - tstruct.queue = NULL; + /* + * Count the number of entries. + */ + tsc.count = 0; + tsc.snum = snum; + tdb_traverse(tdb, traverse_count_fn_queue, (void *)&tsc); + + /* Allocate the queue size. */ + if (( tstruct.queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*tsc.count)) + == NULL) + return 0; + + /* + * Fill in the queue. + * We need maxcount as the queue size may have changed between + * the two calls to tdb_traverse. + */ tstruct.qcount = 0; + tstruct.maxcount = tsc.count; tstruct.snum = snum; tdb_traverse(tdb, traverse_fn_queue, (void *)&tstruct); -- cgit From cdb71ca5181aa1e06bebe2fffb02dc39de83645e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 10 Oct 2000 21:52:31 +0000 Subject: Fixes to periodically scan printing.tdb in idle time and occasionally on exit. Needed to fix printing.tdb from groving to 300Mb+ if being driven by smbclient clients that never ask for status... (effective DOS attack :-). Jeremy. (This used to be commit 6581066b93a674fadf6f9b92441428d2cc8b4a02) --- source3/printing/printing.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 9054c8f36a..486ef5d2c7 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -300,6 +300,14 @@ static void print_queue_update(int snum) fstring keystr; TDB_DATA data, key; + /* + * Update the cache time FIRST ! Stops others doing this + * if the lpq takes a long time. + */ + + slprintf(keystr, sizeof(keystr), "CACHE/%s", lp_servicename(snum)); + tdb_store_int(tdb, keystr, (int)time(NULL)); + slprintf(tmp_file, sizeof(tmp_file), "%s/smblpq.%d", path, local_pid); unlink(tmp_file); @@ -380,7 +388,11 @@ static void print_queue_update(int snum) key.dsize = strlen(keystr); tdb_store(tdb, key, data, TDB_REPLACE); - /* update the cache time */ + /* + * Update the cache time again. We want to do this call + * as little as possible... + */ + slprintf(keystr, sizeof(keystr), "CACHE/%s", lp_servicename(snum)); tdb_store_int(tdb, keystr, (int)time(NULL)); } @@ -1008,7 +1020,36 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) } print_cache_flush(snum); + safe_free(queue); return True; } + +/**************************************************************************** + Periodically run a status on all the queues to ensure the tdb doesn't grow. + Note that this will have no effect if the client is doing its own status + queries. This code is here to clean up jobs submitted by non-Windows printer + clients (eg. smbclient) that never do a status check. +****************************************************************************/ + +void process_print_queue(time_t t) +{ + static time_t last_check_time; + int services = lp_numservices(); + print_queue_struct *queue; + print_status_struct status; + int snum; + + if ((t != (time_t)-1) && ((t - last_check_time) < lp_lpqcachetime())) + return; + + last_check_time = t; + + for (snum = 0; snum < services; snum++) { + if (lp_snum_ok(snum) && lp_print_ok(snum) && lp_browseable(snum)) { + (void)print_queue_status(snum, &queue,&status); + safe_free(queue); + } + } +} #undef OLD_NTDOMAIN -- cgit From e9270d61fc8ddaecd8eb1d2c0a9ce8eba13b1194 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 11 Oct 2000 02:04:46 +0000 Subject: Remove lpq as root fix - do this in print_job_start instead as part of print queue length processing. Jeremy. (This used to be commit e85a0fadd8dcf608822819f00f15569713518806) --- source3/printing/printing.c | 28 ---------------------------- 1 file changed, 28 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 486ef5d2c7..d71ea25d0d 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1024,32 +1024,4 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) return True; } - -/**************************************************************************** - Periodically run a status on all the queues to ensure the tdb doesn't grow. - Note that this will have no effect if the client is doing its own status - queries. This code is here to clean up jobs submitted by non-Windows printer - clients (eg. smbclient) that never do a status check. -****************************************************************************/ - -void process_print_queue(time_t t) -{ - static time_t last_check_time; - int services = lp_numservices(); - print_queue_struct *queue; - print_status_struct status; - int snum; - - if ((t != (time_t)-1) && ((t - last_check_time) < lp_lpqcachetime())) - return; - - last_check_time = t; - - for (snum = 0; snum < services; snum++) { - if (lp_snum_ok(snum) && lp_print_ok(snum) && lp_browseable(snum)) { - (void)print_queue_status(snum, &queue,&status); - safe_free(queue); - } - } -} #undef OLD_NTDOMAIN -- cgit From 26a4a34d36aff371b2b03506b4e7544847dd1d69 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 11 Oct 2000 02:26:27 +0000 Subject: Fix for growing printing.tdb by adding check on job creation. This also updates the printing.tdb db version to 2. Jeremy. (This used to be commit 13395514c632341e7be36eb9589011bb0949b075) --- source3/printing/printing.c | 67 +++++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 17 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index d71ea25d0d..d856023567 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -60,7 +60,7 @@ static pid_t local_pid; #define UNIX_JOB_START PRINT_MAX_JOBID #define PRINT_SPOOL_PREFIX "smbprn." -#define PRINT_DATABASE_VERSION 1 +#define PRINT_DATABASE_VERSION 2 /**************************************************************************** initialise the printing backend. Called once at startup. @@ -381,6 +381,7 @@ static void print_queue_update(int snum) safe_free(tstruct.queue); /* store the queue status structure */ + status.qcount = qcount; slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum)); data.dptr = (void *)&status; data.dsize = sizeof(status); @@ -628,6 +629,49 @@ int print_job_write(int jobid, const char *buf, int size) return write(fd, buf, size); } +/**************************************************************************** + Check if the print queue has been updated recently enough. +****************************************************************************/ + +static BOOL print_cache_expired(int snum) +{ + fstring key; + time_t t2, t = time(NULL); + slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum)); + t2 = tdb_fetch_int(tdb, key); + if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) { + return True; + } + return False; +} + +/**************************************************************************** + Determine the number of jobs in a queue. +****************************************************************************/ + +static int print_queue_length(int snum) +{ + fstring keystr; + TDB_DATA data, key; + print_status_struct status; + + /* make sure the database is up to date */ + if (print_cache_expired(snum)) print_queue_update(snum); + + /* also fetch the queue status */ + ZERO_STRUCTP(&status); + slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum)); + key.dptr = keystr; + key.dsize = strlen(keystr); + data = tdb_fetch(tdb, key); + if (data.dptr) { + if (data.dsize == sizeof(status)) { + memcpy(&status, data.dptr, sizeof(status)); + } + free(data.dptr); + } + return status.qcount; +} /*************************************************************************** start spooling a job - return the jobid @@ -670,6 +714,11 @@ int print_job_start(struct current_user *user, int snum, char *jobname) return -1; } + if (print_queue_length(snum) > lp_maxprintjobs(snum)) { + errno = ENOSPC; + return -1; + } + /* create the database entry */ ZERO_STRUCT(pjob); pjob.pid = local_pid; @@ -822,22 +871,6 @@ BOOL print_job_end(int jobid) return True; } -/**************************************************************************** - Check if the print queue has been updated recently enough. -****************************************************************************/ - -static BOOL print_cache_expired(int snum) -{ - fstring key; - time_t t2, t = time(NULL); - slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum)); - t2 = tdb_fetch_int(tdb, key); - if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) { - return True; - } - return False; -} - /* utility fn to enumerate the print queue */ static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) { -- cgit From 7b0a62c8cd9523df86f1d9aee3e3700f494a8e78 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 18 Oct 2000 06:31:14 +0000 Subject: Removed null user checks to enable lanman print queue pausing and print job deleting. (This used to be commit e40a0e2f52326199264d622c4f11877f20e4ebce) --- source3/printing/printing.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index d856023567..c691573c0a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -518,8 +518,6 @@ BOOL print_job_delete(struct current_user *user, int jobid) int snum = print_job_snum(jobid); BOOL owner; - if (!user) return False; - owner = is_owner(user, jobid); /* Check access against security descriptor or whether the user @@ -999,8 +997,6 @@ BOOL print_queue_pause(struct current_user *user, int snum, int *errcode) { int ret; - if (!user) return False; - if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { *errcode = ERROR_ACCESS_DENIED; return False; -- cgit From 34b397f8ac0afe36bd9b12d87b8080a1e286072d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sat, 4 Nov 2000 18:24:15 +0000 Subject: Merge of printing improvements/fixes from appliance branch. (This used to be commit 8e163eac33e8f407de00c318d3de29fcfbf2b8a7) --- source3/printing/printing.c | 61 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index c691573c0a..e1f58ba6a5 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -808,7 +808,7 @@ BOOL print_job_end(int jobid) SMB_STRUCT_STAT sbuf; pstring current_directory; pstring print_directory; - char *wd, *p; + char *wd, *p, *printer_name; pstring jobname; if (!pjob) @@ -866,6 +866,13 @@ BOOL print_job_end(int jobid) /* force update the database */ print_cache_flush(snum); + /* Send a printer notify message */ + + printer_name = PRINTERNAME(snum); + + message_send_all(MSG_PRINTER_NOTIFY, printer_name, + strlen(printer_name) + 1); + return True; } @@ -923,6 +930,22 @@ static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, return 0; } +/* Sort print jobs by submittal time */ + +static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2) +{ + /* Silly cases */ + + if (!j1 && !j2) return 0; + if (!j1) return -1; + if (!j2) return 1; + + /* Sort on job start time */ + + if (j1->time == j2->time) return 0; + return (j1->time > j2->time) ? 1 : -1; +} + /**************************************************************************** get a printer queue listing ****************************************************************************/ @@ -974,6 +997,12 @@ int print_queue_status(int snum, free(data.dptr); } + /* Sort the queue by submission time otherwise they are displayed + in hash order. */ + + qsort(tstruct.queue, tstruct.qcount, sizeof(print_queue_struct), + QSORT_CAST(printjob_comp)); + *queue = tstruct.queue; return tstruct.qcount; } @@ -1008,6 +1037,17 @@ BOOL print_queue_pause(struct current_user *user, int snum, int *errcode) /* force update the database */ print_cache_flush(snum); + /* Send a printer notify message */ + + if (ret == 0) { + char *printer_name; + + printer_name = PRINTERNAME(snum); + + message_send_all(MSG_PRINTER_NOTIFY, printer_name, + strlen(printer_name) + 1); + } + return ret == 0; } @@ -1029,6 +1069,17 @@ BOOL print_queue_resume(struct current_user *user, int snum, int *errcode) /* force update the database */ print_cache_flush(snum); + /* Send a printer notify message */ + + if (ret == 0) { + char *printer_name; + + printer_name = PRINTERNAME(snum); + + message_send_all(MSG_PRINTER_NOTIFY, printer_name, + strlen(printer_name) + 1); + } + return ret == 0; } @@ -1039,6 +1090,7 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) { print_queue_struct *queue; print_status_struct status; + char *printer_name; int njobs, i; njobs = print_queue_status(snum, &queue, &status); @@ -1051,6 +1103,13 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) print_cache_flush(snum); safe_free(queue); + /* Send a printer notify message */ + + printer_name = PRINTERNAME(snum); + + message_send_all(MSG_PRINTER_NOTIFY, printer_name, + strlen(printer_name) + 1); + return True; } #undef OLD_NTDOMAIN -- cgit From a6ff0d29d6dc60942463adebd819b87da4775da5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 4 Nov 2000 19:48:53 +0000 Subject: Merge from Tim - don't reinsert UNIX job if already exists. Jeremy. (This used to be commit a33c395c98d80f620257fed480d5824fc609d9c9) --- source3/printing/printing.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index e1f58ba6a5..14f39b858c 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -126,6 +126,7 @@ static BOOL print_job_store(int jobid, struct printjob *pjob) TDB_DATA d; d.dptr = (void *)pjob; d.dsize = sizeof(*pjob); + return (0 == tdb_store(tdb, print_key(jobid), d, TDB_REPLACE)); } @@ -197,6 +198,13 @@ static void print_unix_job(int snum, print_queue_struct *q) int jobid = q->job + UNIX_JOB_START; struct printjob pj; + /* Don't re-insert a unix job if it already exists as it mucks + up the timestamp. */ + + if (tdb_exists(tdb, print_key(jobid))) { + return; + } + ZERO_STRUCT(pj); pj.pid = (pid_t)-1; -- cgit From dd2f6f448de4dc2d9f2b8464bb1b0aa158d39ec5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 7 Nov 2000 23:05:53 +0000 Subject: Merge of latest round of printing fixes from appliance branch. (This used to be commit 8fe17fd59488814cdbe9abcfe53ab2627901e421) --- source3/printing/printing.c | 99 +++++++++++++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 30 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 14f39b858c..9fa4b9b8c6 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -21,6 +21,7 @@ */ #include "includes.h" + extern int DEBUGLEVEL; /* @@ -196,21 +197,18 @@ list a unix job in the print database static void print_unix_job(int snum, print_queue_struct *q) { int jobid = q->job + UNIX_JOB_START; - struct printjob pj; + struct printjob pj, *old_pj; - /* Don't re-insert a unix job if it already exists as it mucks - up the timestamp. */ + /* Preserve the timestamp on an existing unix print job */ - if (tdb_exists(tdb, print_key(jobid))) { - return; - } + old_pj = print_job_find(jobid); ZERO_STRUCT(pj); pj.pid = (pid_t)-1; pj.sysjob = q->job; pj.fd = -1; - pj.starttime = q->time; + pj.starttime = old_pj ? old_pj->starttime : q->time; pj.status = q->status; pj.size = q->size; pj.spooled = True; @@ -248,6 +246,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void if (!pjob.smbjob) { /* remove a unix job if it isn't in the system queue any more */ + for (i=0;iqcount;i++) { if (jobid == ts->queue[i].job + UNIX_JOB_START) break; } @@ -521,9 +520,10 @@ static BOOL is_owner(struct current_user *user, int jobid) /**************************************************************************** delete a print job ****************************************************************************/ -BOOL print_job_delete(struct current_user *user, int jobid) +BOOL print_job_delete(struct current_user *user, int jobid, int *errcode) { int snum = print_job_snum(jobid); + char *printer_name; BOOL owner; owner = is_owner(user, jobid); @@ -534,6 +534,7 @@ BOOL print_job_delete(struct current_user *user, int jobid) if (!owner && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("delete denied by security descriptor\n")); + *errcode = ERROR_ACCESS_DENIED; return False; } @@ -544,6 +545,13 @@ BOOL print_job_delete(struct current_user *user, int jobid) print_queue_update(snum); + /* Send a printer notify message */ + + printer_name = PRINTERNAME(snum); + + message_send_all(MSG_PRINTER_NOTIFY, printer_name, + strlen(printer_name) + 1); + return !print_job_exists(jobid); } @@ -551,14 +559,14 @@ BOOL print_job_delete(struct current_user *user, int jobid) /**************************************************************************** pause a job ****************************************************************************/ -BOOL print_job_pause(struct current_user *user, int jobid) +BOOL print_job_pause(struct current_user *user, int jobid, int *errcode) { struct printjob *pjob = print_job_find(jobid); int snum, ret = -1; + char *printer_name; fstring jobstr; BOOL owner; - if (!pjob || !user) return False; if (!pjob->spooled || pjob->sysjob == -1) return False; @@ -569,6 +577,7 @@ BOOL print_job_pause(struct current_user *user, int jobid) if (!owner && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("pause denied by security descriptor\n")); + *errcode = ERROR_ACCESS_DENIED; return False; } @@ -579,19 +588,33 @@ BOOL print_job_pause(struct current_user *user, int jobid) "%j", jobstr, NULL); + if (ret != 0) { + *errcode = ERROR_INVALID_PARAMETER; + return False; + } + /* force update the database */ print_cache_flush(snum); + /* Send a printer notify message */ + + printer_name = PRINTERNAME(snum); + + message_send_all(MSG_PRINTER_NOTIFY, printer_name, + strlen(printer_name) + 1); + /* how do we tell if this succeeded? */ - return ret == 0; + + return True; } /**************************************************************************** resume a job ****************************************************************************/ -BOOL print_job_resume(struct current_user *user, int jobid) +BOOL print_job_resume(struct current_user *user, int jobid, int *errcode) { struct printjob *pjob = print_job_find(jobid); + char *printer_name; int snum, ret; fstring jobstr; BOOL owner; @@ -606,6 +629,7 @@ BOOL print_job_resume(struct current_user *user, int jobid) if (!is_owner(user, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("resume denied by security descriptor\n")); + *errcode = ERROR_ACCESS_DENIED; return False; } @@ -615,11 +639,22 @@ BOOL print_job_resume(struct current_user *user, int jobid) "%j", jobstr, NULL); + if (ret != 0) { + *errcode = ERROR_INVALID_PARAMETER; + return False; + } + /* force update the database */ print_cache_flush(snum); - /* how do we tell if this succeeded? */ - return ret == 0; + /* Send a printer notify message */ + + printer_name = PRINTERNAME(snum); + + message_send_all(MSG_PRINTER_NOTIFY, printer_name, + strlen(printer_name) + 1); + + return True; } /**************************************************************************** @@ -1032,6 +1067,7 @@ int print_queue_snum(char *qname) ****************************************************************************/ BOOL print_queue_pause(struct current_user *user, int snum, int *errcode) { + char *printer_name; int ret; if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { @@ -1042,21 +1078,22 @@ BOOL print_queue_pause(struct current_user *user, int snum, int *errcode) ret = print_run_command(snum, lp_queuepausecommand(snum), NULL, NULL); + if (ret != 0) { + *errcode = ERROR_INVALID_PARAMETER; + return False; + } + /* force update the database */ print_cache_flush(snum); /* Send a printer notify message */ - if (ret == 0) { - char *printer_name; - - printer_name = PRINTERNAME(snum); + printer_name = PRINTERNAME(snum); - message_send_all(MSG_PRINTER_NOTIFY, printer_name, - strlen(printer_name) + 1); - } + message_send_all(MSG_PRINTER_NOTIFY, printer_name, + strlen(printer_name) + 1); - return ret == 0; + return True; } /**************************************************************************** @@ -1064,6 +1101,7 @@ BOOL print_queue_pause(struct current_user *user, int snum, int *errcode) ****************************************************************************/ BOOL print_queue_resume(struct current_user *user, int snum, int *errcode) { + char *printer_name; int ret; if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { @@ -1074,21 +1112,22 @@ BOOL print_queue_resume(struct current_user *user, int snum, int *errcode) ret = print_run_command(snum, lp_queueresumecommand(snum), NULL, NULL); + if (ret != 0) { + *errcode = ERROR_INVALID_PARAMETER; + return False; + } + /* force update the database */ print_cache_flush(snum); /* Send a printer notify message */ - if (ret == 0) { - char *printer_name; - - printer_name = PRINTERNAME(snum); + printer_name = PRINTERNAME(snum); - message_send_all(MSG_PRINTER_NOTIFY, printer_name, - strlen(printer_name) + 1); - } + message_send_all(MSG_PRINTER_NOTIFY, printer_name, + strlen(printer_name) + 1); - return ret == 0; + return True; } /**************************************************************************** -- cgit From c1900772ce6fdedc5c380d88f3640107d52e2096 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Nov 2000 19:36:34 +0000 Subject: printing/nt_printing.c: use getpwuid not smbgetpwuid. Canonicalize printernames. printing/printing.c: Insure fix for malloc of zero. rpc_parse/parse_misc.c: Enusre UNISTR's are zero filled. rpc_parse/parse_spoolss.c: Correct INFO_6 - differs between pre-releases of W2K and shipping build. rpc_server/srv_spoolss_nt.c: Canonicalize printernames. Jeremy. (This used to be commit b17e23a8ff2b44540726968355a4b7e26f244f3b) --- source3/printing/printing.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 9fa4b9b8c6..77e32d5bf0 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1003,6 +1003,8 @@ int print_queue_status(int snum, /* make sure the database is up to date */ if (print_cache_expired(snum)) print_queue_update(snum); + + *queue = NULL; /* * Count the number of entries. @@ -1011,6 +1013,9 @@ int print_queue_status(int snum, tsc.snum = snum; tdb_traverse(tdb, traverse_count_fn_queue, (void *)&tsc); + if (tsc.count == 0) + return 0; + /* Allocate the queue size. */ if (( tstruct.queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*tsc.count)) == NULL) -- cgit From 108f86dcccd21196105fb33f0e2ac0e5ef114341 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Nov 2000 22:05:08 +0000 Subject: Added Tim's changes to lock DB during update. Jeremy. (This used to be commit f25b5798b8610de9748ae90ea1bf813b125f517d) --- source3/printing/printing.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 77e32d5bf0..95bcf2a276 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -128,7 +128,7 @@ static BOOL print_job_store(int jobid, struct printjob *pjob) d.dptr = (void *)pjob; d.dsize = sizeof(*pjob); - return (0 == tdb_store(tdb, print_key(jobid), d, TDB_REPLACE)); + return (tdb_store(tdb, print_key(jobid), d, TDB_REPLACE) == 0); } /**************************************************************************** @@ -170,6 +170,7 @@ static int print_run_command(int snum,char *command, ret = smbrun(syscmd,outfile,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); + return ret; } @@ -318,8 +319,7 @@ static void print_queue_update(int snum) slprintf(tmp_file, sizeof(tmp_file), "%s/smblpq.%d", path, local_pid); unlink(tmp_file); - print_run_command(snum, cmd, tmp_file, - NULL); + print_run_command(snum, cmd, tmp_file, NULL); numlines = 0; qlines = file_lines_load(tmp_file, &numlines); @@ -342,6 +342,14 @@ static void print_queue_update(int snum) } file_lines_free(qlines); + DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ? + "s" : "", lp_servicename(snum))); + + /* Lock the queue for the database update */ + + slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", lp_servicename(snum)); + tdb_lock_bystring(tdb, keystr); + /* any job in the internal database that is marked as spooled and doesn't exist in the system queue is considered finished @@ -396,6 +404,11 @@ static void print_queue_update(int snum) key.dsize = strlen(keystr); tdb_store(tdb, key, data, TDB_REPLACE); + /* Unlock for database update */ + + slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", lp_servicename(snum)); + tdb_unlock_bystring(tdb, keystr); + /* * Update the cache time again. We want to do this call * as little as possible... @@ -678,9 +691,11 @@ static BOOL print_cache_expired(int snum) { fstring key; time_t t2, t = time(NULL); + slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum)); t2 = tdb_fetch_int(tdb, key); if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) { + DEBUG(3, ("print cache expired\n")); return True; } return False; -- cgit From 4bce271e4fe239a8b4aac2bb65a52165d68d8ea5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 14 Nov 2000 21:56:32 +0000 Subject: Merge from appliance head of JR's changes for driver versioning. Jeremy. (This used to be commit cdbd2e99775642dc2e92004be9014bf38a92d80f) --- source3/printing/printing.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 95bcf2a276..8b17e8d5f2 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -305,15 +305,17 @@ static void print_queue_update(int snum) print_status_struct status; struct printjob *pjob; struct traverse_struct tstruct; - fstring keystr; + fstring keystr, printer_name; TDB_DATA data, key; + fstrcpy(printer_name, lp_servicename(snum)); + /* * Update the cache time FIRST ! Stops others doing this * if the lpq takes a long time. */ - slprintf(keystr, sizeof(keystr), "CACHE/%s", lp_servicename(snum)); + slprintf(keystr, sizeof(keystr), "CACHE/%s", printer_name); tdb_store_int(tdb, keystr, (int)time(NULL)); slprintf(tmp_file, sizeof(tmp_file), "%s/smblpq.%d", path, local_pid); @@ -343,11 +345,11 @@ static void print_queue_update(int snum) file_lines_free(qlines); DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ? - "s" : "", lp_servicename(snum))); + "s" : "", printer_name)); /* Lock the queue for the database update */ - slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", lp_servicename(snum)); + slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name); tdb_lock_bystring(tdb, keystr); /* @@ -397,7 +399,7 @@ static void print_queue_update(int snum) /* store the queue status structure */ status.qcount = qcount; - slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum)); + slprintf(keystr, sizeof(keystr), "STATUS/%s", printer_name); data.dptr = (void *)&status; data.dsize = sizeof(status); key.dptr = keystr; @@ -406,7 +408,7 @@ static void print_queue_update(int snum) /* Unlock for database update */ - slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", lp_servicename(snum)); + slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name); tdb_unlock_bystring(tdb, keystr); /* @@ -414,7 +416,7 @@ static void print_queue_update(int snum) * as little as possible... */ - slprintf(keystr, sizeof(keystr), "CACHE/%s", lp_servicename(snum)); + slprintf(keystr, sizeof(keystr), "CACHE/%s", printer_name); tdb_store_int(tdb, keystr, (int)time(NULL)); } @@ -1032,7 +1034,8 @@ int print_queue_status(int snum, return 0; /* Allocate the queue size. */ - if (( tstruct.queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*tsc.count)) + if ((tstruct.queue = (print_queue_struct *) + malloc(sizeof(print_queue_struct)*tsc.count)) == NULL) return 0; -- cgit From e8d43bbfe4c05f813a014fd23b8b491ed2d8d4fa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 15 Nov 2000 01:11:38 +0000 Subject: Tuyrn debug timestamps on by default. Add Tim's lpq race fix. Jeremy. (This used to be commit d43405bc47c95bf8c906035cba23bf95d252d13b) --- source3/printing/printing.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 8b17e8d5f2..2d98aa9974 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -271,11 +271,23 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void if (jobid == qid) break; } + /* The job isn't in the system queue - we have to assume it has + completed, so delete the database entry. */ + if (i == ts->qcount) { - /* the job isn't in the system queue - we have to - assume it has completed, so delete the database - entry */ - tdb_delete(t, key); + time_t cur_t = time(NULL); + + /* A race can occur between the time a job is spooled and + when it appears in the lpq output. This happens when + the job is added to printing.tdb when another smbd + running print_queue_update() has completed a lpq and + is currently traversing the printing tdb and deleting jobs. + A workaround is to not delete the job if it has been + submitted less than lp_lpqcachetime() seconds ago. */ + + if ((cur_t - pjob.starttime) > lp_lpqcachetime()) { + tdb_delete(t, key); + } } return 0; -- cgit From cdac09614ef426092ed1b1de480fe90c3c4cdd83 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 16 Nov 2000 21:38:24 +0000 Subject: Fix for a problem with the new messaging system. If a sender is using the messaging system as a notification mechanism, and the speed of notification greatly exceeds the speed of message recovery, then you get a massively (>75Mb) growing tdb. If the message is a simple notification, then the message is static, and you only need one of them in transit to a target process at any one time. This patch adds a BOOL "allow_duplicates" to the message_send_XX primitives. If set to False, then before sending a message the sender checks the existing message queue for a target pid for a duplicate of this message, and doesn't add to it if one already exists. Also added code into msgtest.c to test this. Jeremy. (This used to be commit 3aa7995660395ecb85c8e35b638fa9fbbb952558) --- source3/printing/printing.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 2d98aa9974..1eb6c27555 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -576,8 +576,7 @@ BOOL print_job_delete(struct current_user *user, int jobid, int *errcode) printer_name = PRINTERNAME(snum); - message_send_all(MSG_PRINTER_NOTIFY, printer_name, - strlen(printer_name) + 1); + message_send_all(MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); return !print_job_exists(jobid); } @@ -627,8 +626,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, int *errcode) printer_name = PRINTERNAME(snum); - message_send_all(MSG_PRINTER_NOTIFY, printer_name, - strlen(printer_name) + 1); + message_send_all(MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); /* how do we tell if this succeeded? */ @@ -678,8 +676,7 @@ BOOL print_job_resume(struct current_user *user, int jobid, int *errcode) printer_name = PRINTERNAME(snum); - message_send_all(MSG_PRINTER_NOTIFY, printer_name, - strlen(printer_name) + 1); + message_send_all(MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); return True; } @@ -942,8 +939,7 @@ BOOL print_job_end(int jobid) printer_name = PRINTERNAME(snum); - message_send_all(MSG_PRINTER_NOTIFY, printer_name, - strlen(printer_name) + 1); + message_send_all(MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); return True; } @@ -1125,8 +1121,7 @@ BOOL print_queue_pause(struct current_user *user, int snum, int *errcode) printer_name = PRINTERNAME(snum); - message_send_all(MSG_PRINTER_NOTIFY, printer_name, - strlen(printer_name) + 1); + message_send_all(MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); return True; } @@ -1159,8 +1154,7 @@ BOOL print_queue_resume(struct current_user *user, int snum, int *errcode) printer_name = PRINTERNAME(snum); - message_send_all(MSG_PRINTER_NOTIFY, printer_name, - strlen(printer_name) + 1); + message_send_all(MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); return True; } @@ -1189,8 +1183,7 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) printer_name = PRINTERNAME(snum); - message_send_all(MSG_PRINTER_NOTIFY, printer_name, - strlen(printer_name) + 1); + message_send_all(MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); return True; } -- cgit From 2bd3a436fd6ed218bced476b502d24f317511fb2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Nov 2000 00:30:15 +0000 Subject: Fix for updating of print queues changed from a local box. Essentially, this makes sure that the change messages sent to ourselves are handled synchronously w.r.t. other smb packets incoming. Jeremy. (This used to be commit 78a13074455618308d048d1c69f62e660988eb90) --- source3/printing/printing.c | 58 +++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 15 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 1eb6c27555..0648715699 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -63,6 +63,8 @@ static pid_t local_pid; #define PRINT_SPOOL_PREFIX "smbprn." #define PRINT_DATABASE_VERSION 2 +static int get_queue_status(int, print_status_struct *); + /**************************************************************************** initialise the printing backend. Called once at startup. Does not survive a fork @@ -315,6 +317,7 @@ static void print_queue_update(int snum) int numlines, i, qcount; print_queue_struct *queue = NULL; print_status_struct status; + print_status_struct old_status; struct printjob *pjob; struct traverse_struct tstruct; fstring keystr, printer_name; @@ -409,13 +412,26 @@ static void print_queue_update(int snum) safe_free(tstruct.queue); - /* store the queue status structure */ - status.qcount = qcount; + /* + * Get the old print status. We will use this to compare the + * number of jobs. If they have changed we need to send a + * "changed" message to the smbds. + */ + + if( qcount != get_queue_status(snum, &old_status)) { + DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n", + old_status.qcount, qcount, printer_name )); + message_send_all(MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); + } + + /* store the new queue status structure */ slprintf(keystr, sizeof(keystr), "STATUS/%s", printer_name); - data.dptr = (void *)&status; - data.dsize = sizeof(status); key.dptr = keystr; key.dsize = strlen(keystr); + + status.qcount = qcount; + data.dptr = (void *)&status; + data.dsize = sizeof(status); tdb_store(tdb, key, data, TDB_REPLACE); /* Unlock for database update */ @@ -713,31 +729,43 @@ static BOOL print_cache_expired(int snum) } /**************************************************************************** - Determine the number of jobs in a queue. + Get the queue status - do not update if db is out of date. ****************************************************************************/ -static int print_queue_length(int snum) +static int get_queue_status(int snum, print_status_struct *status) { fstring keystr; TDB_DATA data, key; - print_status_struct status; - - /* make sure the database is up to date */ - if (print_cache_expired(snum)) print_queue_update(snum); - /* also fetch the queue status */ - ZERO_STRUCTP(&status); + ZERO_STRUCTP(status); slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum)); key.dptr = keystr; key.dsize = strlen(keystr); data = tdb_fetch(tdb, key); if (data.dptr) { - if (data.dsize == sizeof(status)) { - memcpy(&status, data.dptr, sizeof(status)); + if (data.dsize == sizeof(print_status_struct)) { + memcpy(status, data.dptr, sizeof(print_status_struct)); } free(data.dptr); } - return status.qcount; + return status->qcount; +} + +/**************************************************************************** + Determine the number of jobs in a queue. +****************************************************************************/ + +static int print_queue_length(int snum) +{ + fstring keystr; + TDB_DATA data, key; + print_status_struct status; + + /* make sure the database is up to date */ + if (print_cache_expired(snum)) print_queue_update(snum); + + /* also fetch the queue status */ + return get_queue_status(snum, &status); } /*************************************************************************** -- cgit From b2d1c4fdee162d676d010cbd1f7bbb1670731efe Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 6 Dec 2000 00:37:25 +0000 Subject: Sync-up with appliance-head printing code. Jeremy. (This used to be commit fe730614d70b331ec7b1a909940395c9713ea8ac) --- source3/printing/printing.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 0648715699..68c371547f 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -757,8 +757,6 @@ static int get_queue_status(int snum, print_status_struct *status) static int print_queue_length(int snum) { - fstring keystr; - TDB_DATA data, key; print_status_struct status; /* make sure the database is up to date */ -- cgit From cf5b71994d6cdb2f81c390579f4a0e676926c6b9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Dec 2000 19:26:04 +0000 Subject: file_lines_load/file_lines_pload can now optionally convert unix_to_dos() on read. Jeremy. (This used to be commit 76b8dd376d13eb4469417be217c966d54d333367) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 68c371547f..e8dc4d7f34 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -339,7 +339,7 @@ static void print_queue_update(int snum) print_run_command(snum, cmd, tmp_file, NULL); numlines = 0; - qlines = file_lines_load(tmp_file, &numlines); + qlines = file_lines_load(tmp_file, &numlines, True); unlink(tmp_file); /* turn the lpq output into a series of job structures */ -- cgit From 2e87e6e8c88bde725bbd73e9ca1b31384128a299 Mon Sep 17 00:00:00 2001 From: David O'Neill Date: Wed, 13 Dec 2000 21:24:06 +0000 Subject: Changes from APPLIANCE_HEAD: - trivial typo in definition of enum_printing[] (source/param/loadparm.c) - fixed printer status display bug. When no jobs existed in queue, the clients were not properly notified of printer status. This caused native tools for pausing/unpausing a print queue to not work. (source/printing/printing.c) (This used to be commit c533e77f1912618230a938458980a9339924fe06) --- source3/printing/printing.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index e8dc4d7f34..b670908049 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1058,10 +1058,28 @@ int print_queue_status(int snum, *queue = NULL; /* - * Count the number of entries. + * Fetch the queue status. We must do this first, as there may + * be no jobs in the queue. + */ + ZERO_STRUCTP(status); + slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum)); + key.dptr = keystr; + key.dsize = strlen(keystr); + data = tdb_fetch(tdb, key); + if (data.dptr) { + if (data.dsize == sizeof(*status)) { + memcpy(status, data.dptr, sizeof(*status)); + } + free(data.dptr); + } + + /* + * Now, fetch the print queue information. We first count the number + * of entries, and then only retrieve the queue if necessary. */ tsc.count = 0; tsc.snum = snum; + tdb_traverse(tdb, traverse_count_fn_queue, (void *)&tsc); if (tsc.count == 0) @@ -1084,19 +1102,6 @@ int print_queue_status(int snum, tdb_traverse(tdb, traverse_fn_queue, (void *)&tstruct); - /* also fetch the queue status */ - ZERO_STRUCTP(status); - slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum)); - key.dptr = keystr; - key.dsize = strlen(keystr); - data = tdb_fetch(tdb, key); - if (data.dptr) { - if (data.dsize == sizeof(*status)) { - memcpy(status, data.dptr, sizeof(*status)); - } - free(data.dptr); - } - /* Sort the queue by submission time otherwise they are displayed in hash order. */ -- cgit From 369f5fd1d7a6e6298bc3cbe01e3aaed0106f6cf4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 15 Dec 2000 01:02:11 +0000 Subject: Fixed memory leaks in lsa_XX calls. Fixed memory leaks in smbcacls. Merged in fixes from appliance-head and 2.2. Fixed multiple connection.tdb open problem. Jeremy. (This used to be commit 0a40bc83e14c69a09948ec09bb6fc5026c4f4c14) --- source3/printing/printing.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index b670908049..842b97f9c5 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -421,7 +421,7 @@ static void print_queue_update(int snum) if( qcount != get_queue_status(snum, &old_status)) { DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n", old_status.qcount, qcount, printer_name )); - message_send_all(MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); + message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); } /* store the new queue status structure */ @@ -592,7 +592,7 @@ BOOL print_job_delete(struct current_user *user, int jobid, int *errcode) printer_name = PRINTERNAME(snum); - message_send_all(MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); + message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); return !print_job_exists(jobid); } @@ -642,7 +642,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, int *errcode) printer_name = PRINTERNAME(snum); - message_send_all(MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); + message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); /* how do we tell if this succeeded? */ @@ -692,7 +692,7 @@ BOOL print_job_resume(struct current_user *user, int jobid, int *errcode) printer_name = PRINTERNAME(snum); - message_send_all(MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); + message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); return True; } @@ -965,7 +965,7 @@ BOOL print_job_end(int jobid) printer_name = PRINTERNAME(snum); - message_send_all(MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); + message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); return True; } @@ -1152,7 +1152,7 @@ BOOL print_queue_pause(struct current_user *user, int snum, int *errcode) printer_name = PRINTERNAME(snum); - message_send_all(MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); + message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); return True; } @@ -1185,7 +1185,7 @@ BOOL print_queue_resume(struct current_user *user, int snum, int *errcode) printer_name = PRINTERNAME(snum); - message_send_all(MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); + message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); return True; } @@ -1214,7 +1214,7 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) printer_name = PRINTERNAME(snum); - message_send_all(MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); + message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); return True; } -- cgit From 23807f2b308e80a1e325c8fd2bddeec3e2e15bc5 Mon Sep 17 00:00:00 2001 From: David O'Neill Date: Thu, 4 Jan 2001 19:27:08 +0000 Subject: Changes from APPLIANCE_HEAD: source/Makefile.in - changes to ctags and etags rules that somehow got lost along the way. source/include/proto.h - make proto source/smbd/sec_ctx.c source/smbd/password.c - merge debugs for debugging user groups and NT token stuff. source/lib/util_str.c - capitalise domain name returned from parse_domain_user() source/nsswitch/wb_client.c - fix broken conditional in debug statement. source/include/rpc_secdes.h source/include/rpc_spoolss.h source/printing/nt_printing.c source/lib/util_seaccess.c - fix printer permission bugs related to ACE masks for printers. This adds mapping of generic access rights to object specific rights for NT printers. Still need to work out whether or not to ignore ACEs with certain flags set, though. See comments in util_seaccess.c:check_ace() for details. source/printing/nt_printing.c source/printing/printing.c - use PRINTER_ACCESS_ADMINISTER instead of JOB_ACCESS_ADMINISTER until we sort out printer/printjob permission stuff. (This used to be commit 1dba9c5cd1e6389734c648f6903abcb7c8d5b2f0) --- source3/printing/printing.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 842b97f9c5..57d0c2b8a3 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -575,7 +575,7 @@ BOOL print_job_delete(struct current_user *user, int jobid, int *errcode) owns their job. */ if (!owner && - !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { + !print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { DEBUG(3, ("delete denied by security descriptor\n")); *errcode = ERROR_ACCESS_DENIED; return False; @@ -617,7 +617,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, int *errcode) owner = is_owner(user, jobid); if (!owner && - !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { + !print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { DEBUG(3, ("pause denied by security descriptor\n")); *errcode = ERROR_ACCESS_DENIED; return False; @@ -668,7 +668,7 @@ BOOL print_job_resume(struct current_user *user, int jobid, int *errcode) owner = is_owner(user, jobid); if (!is_owner(user, jobid) && - !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { + !print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { DEBUG(3, ("resume denied by security descriptor\n")); *errcode = ERROR_ACCESS_DENIED; return False; @@ -807,7 +807,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) return -1; } - if (print_queue_length(snum) > lp_maxprintjobs(snum)) { + if (lp_maxprintjobs(snum) && print_queue_length(snum) > lp_maxprintjobs(snum)) { errno = ENOSPC; return -1; } @@ -1202,7 +1202,8 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) njobs = print_queue_status(snum, &queue, &status); for (i=0;i Date: Mon, 8 Jan 2001 19:58:30 +0000 Subject: Changes merged from APPLIANCE_HEAD: source/printing/printing.c source/rpc_server/srv_spoolss_nt.c - convert args for print command to unix codepage. (This used to be commit 1c0ae957f8f1abee7d22a18b6df092eb2a884ae1) --- source3/printing/printing.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 57d0c2b8a3..cfe194ab17 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -168,7 +168,9 @@ static int print_run_command(int snum,char *command, pstring_sub(syscmd, "%p", p); standard_sub_snum(snum,syscmd); - + + /* Convert script args to unix-codepage */ + dos_to_unix(syscmd, True); ret = smbrun(syscmd,outfile,False); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); @@ -1202,8 +1204,7 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) njobs = print_queue_status(snum, &queue, &status); for (i=0;i Date: Thu, 11 Jan 2001 20:41:19 +0000 Subject: Changes from APPLIANCE_HEAD: testsuite/printing/psec.c - Use lock directory from smb.conf parameter when peeking at the ntdrivers.tdb file. source/rpc_parse/parse_sec.c - fix typo in debug message source/script/installbin.sh - create private directory as part of 'make install'. source/nsswitch/winbindd_cache.c source/nsswitch/winbindd_idmap.c source/passdb/secrets.c source/smbd/connection.c - always convert tdb key to unix code-page when generating. source/printing/nt_printing.c - always convert tdb key to unix code-page when generating. - don't prepend path to a filename that is NULL in add_a_printer_driver_3(). source/rpc_server/srv_spoolss_nt.c - always convert tdb key to unix code-page when generating. - don't prepend server name to a path/filename that is NULL in the fill_printer_driver_info functions. source/printing/printing.c - always convert tdb key to unix code-page when generating. - move access check for print_queue_purge() outside of job delete loop. source/smbd/unix_acls.c - fix for setting ACLs (this got missed earlier) source/lib/messages.c - trivial sync with appliance_head (This used to be commit 376601d17d53ef7bfaafa576bd770e554516e808) --- source3/printing/printing.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index cfe194ab17..3f8c542ec7 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -304,6 +304,7 @@ static void print_cache_flush(int snum) { fstring key; slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum)); + dos_to_unix(key, True); /* Convert key to unix-codepage */ tdb_store_int(tdb, key, -1); } @@ -324,8 +325,11 @@ static void print_queue_update(int snum) struct traverse_struct tstruct; fstring keystr, printer_name; TDB_DATA data, key; - + + /* Convert printer name (i.e. share name) to unix-codepage for all of the + * following tdb key generation */ fstrcpy(printer_name, lp_servicename(snum)); + dos_to_unix(printer_name, True); /* * Update the cache time FIRST ! Stops others doing this @@ -428,7 +432,7 @@ static void print_queue_update(int snum) /* store the new queue status structure */ slprintf(keystr, sizeof(keystr), "STATUS/%s", printer_name); - key.dptr = keystr; + key.dptr = keystr; key.dsize = strlen(keystr); status.qcount = qcount; @@ -722,6 +726,7 @@ static BOOL print_cache_expired(int snum) time_t t2, t = time(NULL); slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum)); + dos_to_unix(key, True); /* Convert key to unix-codepage */ t2 = tdb_fetch_int(tdb, key); if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) { DEBUG(3, ("print cache expired\n")); @@ -741,6 +746,7 @@ static int get_queue_status(int snum, print_status_struct *status) ZERO_STRUCTP(status); slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum)); + dos_to_unix(keystr, True); /* Convert key to unix-codepage */ key.dptr = keystr; key.dsize = strlen(keystr); data = tdb_fetch(tdb, key); @@ -1065,6 +1071,7 @@ int print_queue_status(int snum, */ ZERO_STRUCTP(status); slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum)); + dos_to_unix(keystr, True); /* Convert key to unix-codepage */ key.dptr = keystr; key.dsize = strlen(keystr); data = tdb_fetch(tdb, key); @@ -1203,8 +1210,9 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) int njobs, i; njobs = print_queue_status(snum, &queue, &status); - for (i=0;i Date: Wed, 17 Jan 2001 18:47:46 +0000 Subject: Changes from APPLIANCE_HEAD: source/rpc_server/srv_spoolss_nt.c - Unrolled construct_notify_jobs_info() loop to only fetch printer info_2 structure once rather than num_print_jobs times. - convert command to unix codepage. - remove lp_remove_service() call as it prevents lp_killservice() from working. - Modified some DEBUG and DEBUGADD statements. source/param/loadparm.c source/param/params.c - change printer, preload, auto services to FLAG_DOS_STRING, reverted earlier changes to szPrintername et al, add comments. source/printing/load.c - fix bug with lp_auto_services() and strtok() source/printing/nt_printing.c source/printing/printing.c - remove redundant test that used SERVICE(snum) source/printing/pcap.c - add unix_to_dos() calls, add notes wrt FIXMEs for xxx_printer_fn() functions. source/web/swat.c - added FIXME comment. source/smbd/service.c - added comment re: dos codepage (This used to be commit 7b774b72c2857af9519012106714a9e2cb099da3) --- source3/printing/printing.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 3f8c542ec7..3ce58b5b78 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -164,7 +164,6 @@ static int print_run_command(int snum,char *command, va_end(ap); p = PRINTERNAME(snum); - if (!p || !*p) p = SERVICE(snum); pstring_sub(syscmd, "%p", p); standard_sub_snum(snum,syscmd); -- cgit From a5b27e9cea2e7c89cabcfe44b89b269bc2c8ff48 Mon Sep 17 00:00:00 2001 From: David O'Neill Date: Fri, 19 Jan 2001 16:57:39 +0000 Subject: Changes from APPLIANCE_HEAD: source/printing/nt_printing.c - use se_create_child_secdesc() to create appropriate security descriptor when performing print job admin security checks. source/printing/printing.c - Use JOB_ACCESS_ADMINISTER instead of PRINTER_ACCESS_ADMINISTER in print_job_{delete,pause,resume}() - If stat'ing the job file fails, delete the job from printing.tdb - In print_job_end() check lpq cache time and do a print_queue_update() This prevents printing.tdb from growing when using NT/2K clients, and there isn't someone pressing F5 in a port monitor window. - In print_queue_resume() check lpq cache time and do a print_queue_update() Probably should do it for print_job_resume() too. (This used to be commit 0068b7741fd54706ef36ddbbc3092389d281e684) --- source3/printing/printing.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 3ce58b5b78..a22c8b749a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -580,7 +580,7 @@ BOOL print_job_delete(struct current_user *user, int jobid, int *errcode) owns their job. */ if (!owner && - !print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { + !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("delete denied by security descriptor\n")); *errcode = ERROR_ACCESS_DENIED; return False; @@ -622,7 +622,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, int *errcode) owner = is_owner(user, jobid); if (!owner && - !print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { + !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("pause denied by security descriptor\n")); *errcode = ERROR_ACCESS_DENIED; return False; @@ -673,7 +673,7 @@ BOOL print_job_resume(struct current_user *user, int jobid, int *errcode) owner = is_owner(user, jobid); if (!is_owner(user, jobid) && - !print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { + !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("resume denied by security descriptor\n")); *errcode = ERROR_ACCESS_DENIED; return False; @@ -921,12 +921,17 @@ BOOL print_job_end(int jobid) snum = print_job_snum(jobid); - if (sys_fstat(pjob->fd, &sbuf) == 0) + if (sys_fstat(pjob->fd, &sbuf) == 0) { pjob->size = sbuf.st_size; - - close(pjob->fd); - pjob->fd = -1; - + close(pjob->fd); + pjob->fd = -1; + } else { + /* Couldn't stat the job file, so something has gone wrong. Cleanup */ + unlink(pjob->filename); + tdb_delete(tdb, print_key(jobid)); + return False; + } + if (pjob->size == 0) { /* don't bother spooling empty files */ unlink(pjob->filename); @@ -965,9 +970,9 @@ BOOL print_job_end(int jobid) pjob->spooled = True; print_job_store(jobid, pjob); - /* force update the database */ - print_cache_flush(snum); - + /* make sure the database is up to date */ + if (print_cache_expired(snum)) print_queue_update(snum); + /* Send a printer notify message */ printer_name = PRINTERNAME(snum); @@ -1186,8 +1191,8 @@ BOOL print_queue_resume(struct current_user *user, int snum, int *errcode) return False; } - /* force update the database */ - print_cache_flush(snum); + /* make sure the database is up to date */ + if (print_cache_expired(snum)) print_queue_update(snum); /* Send a printer notify message */ @@ -1216,7 +1221,7 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) } } - print_cache_flush(snum); + print_queue_update(snum); safe_free(queue); /* Send a printer notify message */ -- cgit From 7599c82cceec73fe33b6daa4a908937aed768f80 Mon Sep 17 00:00:00 2001 From: David O'Neill Date: Mon, 22 Jan 2001 16:59:24 +0000 Subject: Changes from APPLIANCE_HEAD: source/smbd/lanman.c - cleanup and bug fix for win9x print queue purge. source/printing/printing.c - cleanup and bug fix for win9x print queue purge. - print_job_end() changed to cleanup spool file in the event of a failure returned from the print_run_command() (This used to be commit 0235fbef37b400a2bf875163878e497282cd1739) --- source3/printing/printing.c | 50 ++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 17 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index a22c8b749a..75d61accd1 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -534,6 +534,14 @@ static BOOL print_job_delete1(int jobid) snum = print_job_snum(jobid); + /* Hrm - we need to be able to cope with deleting a job before it + has reached the spooler. */ + + if (pjob->sysjob == -1) { + DEBUG(5, ("attempt to delete job %d not seen by lpr\n", + jobid)); + } + if (pjob->spooled && pjob->sysjob != -1) { /* need to delete the spooled entry */ fstring jobstr; @@ -906,7 +914,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) BOOL print_job_end(int jobid) { struct printjob *pjob = print_job_find(jobid); - int snum; + int snum, ret; SMB_STRUCT_STAT sbuf; pstring current_directory; pstring print_directory; @@ -958,7 +966,7 @@ BOOL print_job_end(int jobid) pstring_sub(jobname, "'", "_"); /* send it to the system spooler */ - print_run_command(snum, + ret = print_run_command(snum, lp_printcommand(snum), NULL, "%s", p, "%J", jobname, @@ -967,19 +975,23 @@ BOOL print_job_end(int jobid) chdir(wd); - pjob->spooled = True; - print_job_store(jobid, pjob); - - /* make sure the database is up to date */ - if (print_cache_expired(snum)) print_queue_update(snum); - - /* Send a printer notify message */ - - printer_name = PRINTERNAME(snum); - - message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); - - return True; + if (ret == 0) { + /* The print job has been sucessfully handed over to the back-end */ + + pjob->spooled = True; + print_job_store(jobid, pjob); + + /* make sure the database is up to date */ + if (print_cache_expired(snum)) print_queue_update(snum); + + return True; + } else { + /* The print job was not succesfully started. Cleanup */ + /* Still need to add proper error return propagation! 010122:JRR */ + unlink(pjob->filename); + tdb_delete(tdb, print_key(jobid)); + return False; + } } /* utility fn to enumerate the print queue */ @@ -1212,11 +1224,15 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) print_status_struct status; char *printer_name; int njobs, i; + BOOL can_job_admin; + can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER); njobs = print_queue_status(snum, &queue, &status); - if (print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { - for (i=0;i Date: Mon, 22 Jan 2001 19:46:22 +0000 Subject: Changes from APPLIANCE_HEAD: source/printing/printing.c - remove unused variable (This used to be commit 2d09b53b3a9201c2f52306fc12ab01a92e712db2) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 75d61accd1..3a676d29b6 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -918,7 +918,7 @@ BOOL print_job_end(int jobid) SMB_STRUCT_STAT sbuf; pstring current_directory; pstring print_directory; - char *wd, *p, *printer_name; + char *wd, *p; pstring jobname; if (!pjob) -- cgit From b9c5be4d79364db0fd3f9af186f165638cae1c54 Mon Sep 17 00:00:00 2001 From: David O'Neill Date: Tue, 23 Jan 2001 17:39:03 +0000 Subject: Changes from APPLIANCE_HEAD: source/rpc_server/srv_spoolss_nt.c - remove redundant srv_spoolss_sendnotify() calls from _spoolss_startdocprinter() and _spoolss_enddocprinter(), as its functionality is already covered in print_job_start() and print_job_end() source/printing/printing.c - force a print_queue_update() prior to print queue purge so that all jobs are purged. (This used to be commit 0ccc552203d6432cde844c5946b203b27f257b1a) --- source3/printing/printing.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 3a676d29b6..955bb0a9b2 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1226,6 +1226,9 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) int njobs, i; BOOL can_job_admin; + /* Force and update so the count is accurate (i.e. not a cached count) */ + print_queue_update(snum); + can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER); njobs = print_queue_status(snum, &queue, &status); @@ -1237,7 +1240,6 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) } } - print_queue_update(snum); safe_free(queue); /* Send a printer notify message */ -- cgit From eee29958f5cacc753f3fa324327e0d8b14ac3006 Mon Sep 17 00:00:00 2001 From: David O'Neill Date: Tue, 23 Jan 2001 20:25:25 +0000 Subject: Changes from APPLIANCE_HEAD: source/rpc_server/srv_spoolss_nt.c - add an access check to _spoolss_deleteprinter() to stop random users and passers by from deleting printers. source/lib/messages.c - converted global msg_all struct to a local in message_send_all() function. source/include/smb.h - added a success error code to the spoolss return codes. source/include/proto.h source/param/loadparm.c source/printing/printing.c - Added new parameter "total print jobs" to limit the total number of print jobs across all queues. Currently individual queues are limited by "max print jobs". (This used to be commit 02f154e729b0e8465d3e1e2ac794e6ab3844ce57) --- source3/printing/printing.c | 52 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 10 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 955bb0a9b2..e459721826 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -228,7 +228,7 @@ static void print_unix_job(int snum, print_queue_struct *q) struct traverse_struct { print_queue_struct *queue; - int qcount, snum, maxcount; + int qcount, snum, maxcount, total_jobs; }; /* utility fn to delete any jobs that are no longer active */ @@ -244,17 +244,20 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void if (strcmp(lp_servicename(ts->snum), pjob.qname)) { /* this isn't for the queue we are looking at */ + ts->total_jobs++; return 0; } if (!pjob.smbjob) { - /* remove a unix job if it isn't in the system queue - any more */ + /* remove a unix job if it isn't in the system queue any more */ for (i=0;iqcount;i++) { if (jobid == ts->queue[i].job + UNIX_JOB_START) break; } - if (i == ts->qcount) tdb_delete(tdb, key); + if (i == ts->qcount) + tdb_delete(tdb, key); + else + ts->total_jobs++; return 0; } @@ -263,9 +266,10 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void /* if a job is not spooled and the process doesn't exist then kill it. This cleans up after smbd deaths */ - if (!process_exists(pjob.pid)) { + if (!process_exists(pjob.pid)) tdb_delete(tdb, key); - } + else + ts->total_jobs++; return 0; } @@ -288,10 +292,13 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void A workaround is to not delete the job if it has been submitted less than lp_lpqcachetime() seconds ago. */ - if ((cur_t - pjob.starttime) > lp_lpqcachetime()) { + if ((cur_t - pjob.starttime) > lp_lpqcachetime()) tdb_delete(t, key); - } + else + ts->total_jobs++; } + else + ts->total_jobs++; return 0; } @@ -412,11 +419,14 @@ static void print_queue_update(int snum) tstruct.queue = queue; tstruct.qcount = qcount; tstruct.snum = snum; + tstruct.total_jobs = 0; tdb_traverse(tdb, traverse_fn_delete, (void *)&tstruct); safe_free(tstruct.queue); + tdb_store_int(tdb, "INFO/total_jobs", tstruct.total_jobs); + /* * Get the old print status. We will use this to compare the * number of jobs. If they have changed we need to send a @@ -745,7 +755,6 @@ static BOOL print_cache_expired(int snum) /**************************************************************************** Get the queue status - do not update if db is out of date. ****************************************************************************/ - static int get_queue_status(int snum, print_status_struct *status) { fstring keystr; @@ -769,7 +778,6 @@ static int get_queue_status(int snum, print_status_struct *status) /**************************************************************************** Determine the number of jobs in a queue. ****************************************************************************/ - static int print_queue_length(int snum) { print_status_struct status; @@ -781,6 +789,23 @@ static int print_queue_length(int snum) return get_queue_status(snum, &status); } +/**************************************************************************** + Determine the number of jobs in all queues. +****************************************************************************/ +static int get_total_jobs(int snum) +{ + int total_jobs; + + /* make sure the database is up to date */ + if (print_cache_expired(snum)) print_queue_update(snum); + + total_jobs = tdb_fetch_int(tdb, "INFO/total_jobs"); + if (total_jobs >0) + return total_jobs; + else + return 0; +} + /*************************************************************************** start spooling a job - return the jobid ***************************************************************************/ @@ -822,11 +847,18 @@ int print_job_start(struct current_user *user, int snum, char *jobname) return -1; } + /* Insure the maximum queue size is not violated */ if (lp_maxprintjobs(snum) && print_queue_length(snum) > lp_maxprintjobs(snum)) { errno = ENOSPC; return -1; } + /* Insure the maximum print jobs in the system is not violated */ + if (lp_totalprintjobs() && get_total_jobs(snum) > lp_totalprintjobs()) { + errno = ENOSPC; + return -1; + } + /* create the database entry */ ZERO_STRUCT(pjob); pjob.pid = local_pid; -- cgit From e31bf053633440bc3ceceb9208bb857fe94237a0 Mon Sep 17 00:00:00 2001 From: David O'Neill Date: Wed, 24 Jan 2001 16:46:08 +0000 Subject: Changes from APPLIANCE_HEAD: source/printing/printing.c - When deleting a job, remove the entry from the back-end database if the delete succeeded. This stops a spurious permission denied message appearing if the forced database update is within the lpq cache timeout and doesn't actually delete the job from the database. (This used to be commit be61c98832d0a8969e608fd22da2035e454ec788) --- source3/printing/printing.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index e459721826..46d872df7c 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -538,7 +538,7 @@ delete a print job - don't update queue static BOOL print_job_delete1(int jobid) { struct printjob *pjob = print_job_find(jobid); - int snum; + int snum, result = 0; if (!pjob) return False; @@ -553,17 +553,26 @@ static BOOL print_job_delete1(int jobid) } if (pjob->spooled && pjob->sysjob != -1) { - /* need to delete the spooled entry */ fstring jobstr; + + /* need to delete the spooled entry */ slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob); - print_run_command(snum, - lp_lprmcommand(snum), NULL, - "%j", jobstr, - "%T", http_timestring(pjob->starttime), - NULL); + result = print_run_command( + snum, + lp_lprmcommand(snum), NULL, + "%j", jobstr, + "%T", http_timestring(pjob->starttime), + NULL); } - return True; + /* Delete the tdb entry if the delete suceeded or the job hasn't + been spooled. */ + + if (result == 0) { + tdb_delete(tdb, print_key(jobid)); + } + + return (result == 0); } /**************************************************************************** -- cgit From 2506c61ab3bd667d54c5e004cc80ce5e40643b5d Mon Sep 17 00:00:00 2001 From: David O'Neill Date: Mon, 29 Jan 2001 21:34:08 +0000 Subject: Changes from APPLIANCE_HEAD: source/include/proto.h - make proto source/printing/nt_printing.c source/rpc_server/srv_spoolss_nt.c - Fix for the overwriting of printerdata entries when WinNT and Win2k are modifying printer parameters on PCL printers. Turns out that Win2k creates a printer with a NULL devmode entry and then expects to set it on *OPEN* (yes this is insane). So we cannot return a "default" devmode for a printer - and we must allow an open to set it. source/tdb/tdb.c - Show freelist in an easier format. Show total free. - When storing a new record, allocate memory for the key + data before the tdb_allocate() as if the malloc fails a (sparse) hole is left in the tdb. source/tdb/tdbtool.c - Show freelist in an easier format. Show total free. source/tdb/Makefile - cleaned up Makefile dependancies source/smbd/lanman.c - Fix for Win9x corrupting it's own parameter string. source/printing/printfsp.c source/printing/printing.c source/rpc_server/srv_spoolss_nt.c source/smbd/close.c - Added normal close parameter into print_fsp_end() which treats an abnormal close as error condition and deletes the spool file. (This used to be commit 025f7a092ad258ff774e3f5e53737f8210cc8af6) --- source3/printing/printing.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 46d872df7c..4dbb01e839 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -950,9 +950,11 @@ int print_job_start(struct current_user *user, int snum, char *jobname) /**************************************************************************** Print a file - called on closing the file. This spools the job. + If normal close is false then we're tearing down the jobs - treat as an + error. ****************************************************************************/ -BOOL print_job_end(int jobid) +BOOL print_job_end(int jobid, BOOL normal_close) { struct printjob *pjob = print_job_find(jobid); int snum, ret; @@ -970,12 +972,17 @@ BOOL print_job_end(int jobid) snum = print_job_snum(jobid); - if (sys_fstat(pjob->fd, &sbuf) == 0) { + if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) { pjob->size = sbuf.st_size; close(pjob->fd); pjob->fd = -1; } else { - /* Couldn't stat the job file, so something has gone wrong. Cleanup */ + + /* + * Not a normal close or we couldn't stat the job file, + * so something has gone wrong. Cleanup. + */ + unlink(pjob->filename); tdb_delete(tdb, print_key(jobid)); return False; -- cgit From c237db1c11d59c9715c65dc808817483e04903e2 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Thu, 15 Feb 2001 19:33:57 +0000 Subject: DEBUG merge from 2.2 about tdb init failure. Patch from David Collier-Brown to print permission error on spool file creation. (This used to be commit 8907a51743b7b9b9ad4168033fae4d44012cca37) --- source3/printing/printing.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 4dbb01e839..9ed33bc6ae 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -76,7 +76,9 @@ BOOL print_backend_init(void) if (tdb && local_pid == sys_getpid()) return True; tdb = tdb_open(lock_path("printing.tdb"), 0, 0, O_RDWR|O_CREAT, 0600); if (!tdb) { - DEBUG(0,("Failed to open printing backend database\n")); + DEBUG(0,("print_backend_init: Failed to open printing backend database. Error = [%s]\n", + tdb_errorstr(tdb))); + return False; } local_pid = sys_getpid(); @@ -920,7 +922,23 @@ int print_job_start(struct current_user *user, int snum, char *jobname) goto next_jobnum; } pjob.fd = sys_open(pjob.filename,O_WRONLY|O_CREAT|O_EXCL,0600); - if (pjob.fd == -1) goto fail; + if (pjob.fd == -1) { + if (errno == EACCES) { + /* Common setup error, force a report. */ + DEBUG(0, ("print_job_start: insufficient permissions " + "to open spool file %s.\n", + pjob.filename)); + } + else { + /* Normal case, report at level 3 and above.*/ + DEBUG(3, ("print_job_start: can't open spool " + "file %s,\n", + pjob.filename)); + DEBUGADD(3, ("errno = %d (%s).\n", errno, + strerror(errno))); + } + goto fail; + } print_job_store(jobid, &pjob); -- cgit From 201753ddc623a18f4ddd0d9a19391ea0471d4c49 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Feb 2001 01:31:55 +0000 Subject: Fixed file descriptor leak in error processing of print jobs. NT sends "delete on close" to cancel a print job copied from the command line. Deal with this. Merged JohnR's fixes for print job errors. Jeremy. (This used to be commit 2060d74e48d62c99a1689ee02ac435b71918ddf0) --- source3/printing/printing.c | 91 +++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 52 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 9ed33bc6ae..49681d9040 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -38,6 +38,9 @@ extern int DEBUGLEVEL; jobids are assigned when a job starts spooling. */ +#define NEXT_JOBID(j) ((j+1) % PRINT_MAX_JOBID > 0 ? (j+1) % PRINT_MAX_JOBID : 1) + + struct printjob { pid_t pid; /* which process launched the job */ int sysjob; /* the system (lp) job number */ @@ -588,9 +591,11 @@ static BOOL is_owner(struct current_user *user, int jobid) if (!pjob || !user) return False; if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { - return strequal(pjob->user, vuser->user.smb_name); + return strequal(pjob->user, + unix_to_dos(vuser->user.smb_name,False)); } else { - return strequal(pjob->user, uidtoname(user->uid)); + return strequal(pjob->user, + unix_to_dos(uidtoname(user->uid),False)); } } @@ -884,9 +889,9 @@ int print_job_start(struct current_user *user, int snum, char *jobname) fstrcpy(pjob.jobname, jobname); if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { - fstrcpy(pjob.user, vuser->user.smb_name); + fstrcpy(pjob.user, unix_to_dos(vuser->user.smb_name,False)); } else { - fstrcpy(pjob.user, uidtoname(user->uid)); + fstrcpy(pjob.user, unix_to_dos(uidtoname(user->uid),False)); } fstrcpy(pjob.qname, lp_servicename(snum)); @@ -898,10 +903,8 @@ int print_job_start(struct current_user *user, int snum, char *jobname) next_jobid = tdb_fetch_int(tdb, "INFO/nextjob"); if (next_jobid == -1) next_jobid = 1; - for (jobid = next_jobid+1; jobid != next_jobid; ) { + for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) { if (!print_job_exists(jobid)) break; - jobid = (jobid + 1) % PRINT_MAX_JOBID; - if (jobid == 0) jobid = 1; } if (jobid == next_jobid || !print_job_store(jobid, &pjob)) { jobid = -1; @@ -922,23 +925,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) goto next_jobnum; } pjob.fd = sys_open(pjob.filename,O_WRONLY|O_CREAT|O_EXCL,0600); - if (pjob.fd == -1) { - if (errno == EACCES) { - /* Common setup error, force a report. */ - DEBUG(0, ("print_job_start: insufficient permissions " - "to open spool file %s.\n", - pjob.filename)); - } - else { - /* Normal case, report at level 3 and above.*/ - DEBUG(3, ("print_job_start: can't open spool " - "file %s,\n", - pjob.filename)); - DEBUGADD(3, ("errno = %d (%s).\n", errno, - strerror(errno))); - } - goto fail; - } + if (pjob.fd == -1) goto fail; print_job_store(jobid, &pjob); @@ -1000,12 +987,14 @@ BOOL print_job_end(int jobid, BOOL normal_close) * Not a normal close or we couldn't stat the job file, * so something has gone wrong. Cleanup. */ - - unlink(pjob->filename); - tdb_delete(tdb, print_key(jobid)); - return False; + close(pjob->fd); + pjob->fd = -1; + goto fail; } - + + /* Technically, this is not quit right. If the printer has a separator + * page turned on, the NT spooler prints the separator page even if the + * print job is 0 bytes. 010215 JRR */ if (pjob->size == 0) { /* don't bother spooling empty files */ unlink(pjob->filename); @@ -1016,17 +1005,14 @@ BOOL print_job_end(int jobid, BOOL normal_close) /* we print from the directory path to give the best chance of parsing the lpq output */ wd = sys_getwd(current_directory); - if (!wd) - return False; + if (!wd) goto fail; pstrcpy(print_directory, pjob->filename); p = strrchr(print_directory,'/'); - if (!p) - return False; + if (!p) goto fail; *p++ = 0; - if (chdir(print_directory) != 0) - return False; + if (chdir(print_directory) != 0) goto fail; pstrcpy(jobname, pjob->jobname); pstring_sub(jobname, "'", "_"); @@ -1041,23 +1027,24 @@ BOOL print_job_end(int jobid, BOOL normal_close) chdir(wd); - if (ret == 0) { - /* The print job has been sucessfully handed over to the back-end */ - - pjob->spooled = True; - print_job_store(jobid, pjob); - - /* make sure the database is up to date */ - if (print_cache_expired(snum)) print_queue_update(snum); - - return True; - } else { - /* The print job was not succesfully started. Cleanup */ - /* Still need to add proper error return propagation! 010122:JRR */ - unlink(pjob->filename); - tdb_delete(tdb, print_key(jobid)); - return False; - } + if (ret) goto fail; + + /* The print job has been sucessfully handed over to the back-end */ + + pjob->spooled = True; + print_job_store(jobid, pjob); + + /* make sure the database is up to date */ + if (print_cache_expired(snum)) print_queue_update(snum); + + return True; + +fail: + /* The print job was not succesfully started. Cleanup */ + /* Still need to add proper error return propagation! 010122:JRR */ + unlink(pjob->filename); + tdb_delete(tdb, print_key(jobid)); + return False; } /* utility fn to enumerate the print queue */ -- cgit From ffa09ecfc1a77f03174ec0460d566190f2413a4d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Feb 2001 17:39:36 +0000 Subject: lib/select.c: Fix for Linux 2.0.x kernel that causes select to return true on a pipe and then a blocking read to fail. Make the pipe read/write non blocking. printing/printing.c: Added a mutex around the code that enumerates all the jobs in a print queue. Allows only one smbd to be doing this at any one time. This fixes a capacity problem discovered at HP with <10,000 jobs in a print queue. Jeremy. (This used to be commit 0d3ae603a2b86d476458ee2a7d4f7d22636c3f66) --- source3/printing/printing.c | 132 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 115 insertions(+), 17 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 49681d9040..b0b0482cd3 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -319,9 +319,64 @@ static void print_cache_flush(int snum) tdb_store_int(tdb, key, -1); } +/**************************************************************************** + Check if someone already thinks they are doing the update. +****************************************************************************/ + +static pid_t get_updating_pid(fstring printer_name) +{ + fstring keystr; + TDB_DATA data, key; + pid_t updating_pid; + + slprintf(keystr, sizeof(keystr), "UPDATING/%s", printer_name); + key.dptr = keystr; + key.dsize = strlen(keystr); + + data = tdb_fetch(tdb, key); + if (!data.dptr || data.dsize != sizeof(pid_t)) + return (pid_t)-1; + + memcpy(&updating_pid, data.dptr, sizeof(pid_t)); + free(data.dptr); + + if (process_exists(updating_pid)) + return updating_pid; + + return (pid_t)-1; +} + +/**************************************************************************** + Set the fact that we're doing the update, or have finished doing the update + in th tdb. +****************************************************************************/ + +static void set_updating_pid(fstring printer_name, BOOL delete) +{ + fstring keystr; + TDB_DATA key; + TDB_DATA data; + pid_t updating_pid = getpid(); + + slprintf(keystr, sizeof(keystr), "UPDATING/%s", printer_name); + key.dptr = keystr; + key.dsize = strlen(keystr); + + if (delete) { + tdb_delete(tdb, key); + return; + } + + data.dptr = (void *)&updating_pid; + data.dsize = sizeof(pid_t); + + tdb_store(tdb, key, data, TDB_REPLACE); +} + /**************************************************************************** update the internal database from the system print queue for a queue ****************************************************************************/ + static void print_queue_update(int snum) { char *path = lp_pathname(snum); @@ -334,21 +389,71 @@ static void print_queue_update(int snum) print_status_struct old_status; struct printjob *pjob; struct traverse_struct tstruct; - fstring keystr, printer_name; + fstring keystr, printer_name, cachestr; TDB_DATA data, key; - + /* Convert printer name (i.e. share name) to unix-codepage for all of the * following tdb key generation */ fstrcpy(printer_name, lp_servicename(snum)); dos_to_unix(printer_name, True); /* - * Update the cache time FIRST ! Stops others doing this - * if the lpq takes a long time. + * Check to see if someone else is doing this update. + * This is essentially a mutex on the update. */ - slprintf(keystr, sizeof(keystr), "CACHE/%s", printer_name); - tdb_store_int(tdb, keystr, (int)time(NULL)); + if (get_updating_pid(printer_name) == -1) { + /* Lock the queue for the database update */ + + slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name); + tdb_lock_bystring(tdb, keystr); + + /* + * Ensure that no one else got in here. + * If the updating pid is still -1 then we are + * the winner. + */ + + if (get_updating_pid(printer_name) != -1) { + /* + * Someone else is doing the update, exit. + */ + tdb_unlock_bystring(tdb, keystr); + return; + } + + /* + * We're going to do the update ourselves. + */ + + /* Tell others we're doing the update. */ + set_updating_pid(printer_name, False); + + /* + * Allow others to enter and notice we're doing + * the update. + */ + + tdb_unlock_bystring(tdb, keystr); + + /* + * Update the cache time FIRST ! Stops others even + * attempting to get the lock and doing this + * if the lpq takes a long time. + */ + + slprintf(cachestr, sizeof(cachestr), "CACHE/%s", printer_name); + tdb_store_int(tdb, cachestr, (int)time(NULL)); + + } + else + { + /* + * Someone else is already doing the update, defer to + * them. + */ + return; + } slprintf(tmp_file, sizeof(tmp_file), "%s/smblpq.%d", path, local_pid); @@ -379,11 +484,6 @@ static void print_queue_update(int snum) DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ? "s" : "", printer_name)); - /* Lock the queue for the database update */ - - slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name); - tdb_lock_bystring(tdb, keystr); - /* any job in the internal database that is marked as spooled and doesn't exist in the system queue is considered finished @@ -446,7 +546,7 @@ static void print_queue_update(int snum) /* store the new queue status structure */ slprintf(keystr, sizeof(keystr), "STATUS/%s", printer_name); - key.dptr = keystr; + key.dptr = keystr; key.dsize = strlen(keystr); status.qcount = qcount; @@ -454,11 +554,6 @@ static void print_queue_update(int snum) data.dsize = sizeof(status); tdb_store(tdb, key, data, TDB_REPLACE); - /* Unlock for database update */ - - slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name); - tdb_unlock_bystring(tdb, keystr); - /* * Update the cache time again. We want to do this call * as little as possible... @@ -466,6 +561,9 @@ static void print_queue_update(int snum) slprintf(keystr, sizeof(keystr), "CACHE/%s", printer_name); tdb_store_int(tdb, keystr, (int)time(NULL)); + + /* Delete our pid from the db. */ + set_updating_pid(printer_name, True); } /**************************************************************************** -- cgit From ed77fca1990f96dba6fe9204e551056395c6ed29 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 23 Feb 2001 03:59:37 +0000 Subject: include/rpc_spoolss.h: Added JOB_STATUS_XXX defines. include/smb.h: Added LPQ_xx enums to correspond with the NT JOB_STATUS_XXX. We need these to be different as we're storing LPQ_xx enums in the tdb already. rpc_server/srv_spoolss_nt.c: Don't need to return status strings as we're now returning status codes. smbd/lanman.c: Change the RAP status codes to have "RAP" in the name. printing/printing.c: Keep track of the status of a job. Allow a job to be deleted from one smbd when being submitted by another. Made logic in mutex clearer. Jeremy. (This used to be commit 71029da7dd74eb91dd6953752bdf238f319d985d) --- source3/printing/printing.c | 100 ++++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 50 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index b0b0482cd3..e771e93600 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -402,58 +402,50 @@ static void print_queue_update(int snum) * This is essentially a mutex on the update. */ - if (get_updating_pid(printer_name) == -1) { - /* Lock the queue for the database update */ + if (get_updating_pid(printer_name) != -1) + return; - slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name); - tdb_lock_bystring(tdb, keystr); + /* Lock the queue for the database update */ - /* - * Ensure that no one else got in here. - * If the updating pid is still -1 then we are - * the winner. - */ + slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name); + tdb_lock_bystring(tdb, keystr); - if (get_updating_pid(printer_name) != -1) { - /* - * Someone else is doing the update, exit. - */ - tdb_unlock_bystring(tdb, keystr); - return; - } + /* + * Ensure that no one else got in here. + * If the updating pid is still -1 then we are + * the winner. + */ + if (get_updating_pid(printer_name) != -1) { /* - * We're going to do the update ourselves. + * Someone else is doing the update, exit. */ + tdb_unlock_bystring(tdb, keystr); + return; + } - /* Tell others we're doing the update. */ - set_updating_pid(printer_name, False); + /* + * We're going to do the update ourselves. + */ - /* - * Allow others to enter and notice we're doing - * the update. - */ + /* Tell others we're doing the update. */ + set_updating_pid(printer_name, False); - tdb_unlock_bystring(tdb, keystr); + /* + * Allow others to enter and notice we're doing + * the update. + */ - /* - * Update the cache time FIRST ! Stops others even - * attempting to get the lock and doing this - * if the lpq takes a long time. - */ + tdb_unlock_bystring(tdb, keystr); - slprintf(cachestr, sizeof(cachestr), "CACHE/%s", printer_name); - tdb_store_int(tdb, cachestr, (int)time(NULL)); + /* + * Update the cache time FIRST ! Stops others even + * attempting to get the lock and doing this + * if the lpq takes a long time. + */ - } - else - { - /* - * Someone else is already doing the update, defer to - * them. - */ - return; - } + slprintf(cachestr, sizeof(cachestr), "CACHE/%s", printer_name); + tdb_store_int(tdb, cachestr, (int)time(NULL)); slprintf(tmp_file, sizeof(tmp_file), "%s/smblpq.%d", path, local_pid); @@ -645,6 +637,13 @@ static BOOL print_job_delete1(int jobid) if (!pjob) return False; + /* + * If already deleting just return. + */ + + if (pjob->status == LPQ_DELETING) + return True; + snum = print_job_snum(jobid); /* Hrm - we need to be able to cope with deleting a job before it @@ -655,6 +654,11 @@ static BOOL print_job_delete1(int jobid) jobid)); } + /* Set the tdb entry to be deleting. */ + + pjob->status = LPQ_DELETING; + print_job_store(jobid, pjob); + if (pjob->spooled && pjob->sysjob != -1) { fstring jobstr; @@ -668,13 +672,6 @@ static BOOL print_job_delete1(int jobid) NULL); } - /* Delete the tdb entry if the delete suceeded or the job hasn't - been spooled. */ - - if (result == 0) { - tdb_delete(tdb, print_key(jobid)); - } - return (result == 0); } @@ -979,7 +976,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) pjob.sysjob = -1; pjob.fd = -1; pjob.starttime = time(NULL); - pjob.status = LPQ_QUEUED; + pjob.status = LPQ_SPOOLING; pjob.size = 0; pjob.spooled = False; pjob.smbjob = True; @@ -1093,8 +1090,10 @@ BOOL print_job_end(int jobid, BOOL normal_close) /* Technically, this is not quit right. If the printer has a separator * page turned on, the NT spooler prints the separator page even if the * print job is 0 bytes. 010215 JRR */ - if (pjob->size == 0) { - /* don't bother spooling empty files */ + if (pjob->size == 0 || pjob->status == LPQ_DELETING) { + /* don't bother spooling empty files or something being deleted. */ + DEBUG(5,("print_job_end: canceling spool of %s (%s)\n", + pjob->filename, pjob->size ? "deleted" : "zero length" )); unlink(pjob->filename); tdb_delete(tdb, print_key(jobid)); return True; @@ -1130,6 +1129,7 @@ BOOL print_job_end(int jobid, BOOL normal_close) /* The print job has been sucessfully handed over to the back-end */ pjob->spooled = True; + pjob->status = LPQ_QUEUED; print_job_store(jobid, pjob); /* make sure the database is up to date */ -- cgit From da3053048c3d224a20d6383ac6682d31059cd46c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 11 Mar 2001 00:32:10 +0000 Subject: Merge of new 2.2 code into HEAD (Gerald I hate you :-) :-). Allows new SAMR RPC code to merge with new passdb code. Currently rpcclient doesn't compile. I'm working on it... Jeremy. (This used to be commit 0be41d5158ea4e645e93e8cd30617c038416e549) --- source3/printing/printing.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index e771e93600..241135f744 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1,4 +1,3 @@ -#define OLD_NTDOMAIN 1 /* Unix SMB/Netbios implementation. Version 3.0 @@ -792,14 +791,12 @@ BOOL print_job_resume(struct current_user *user, int jobid, int *errcode) char *printer_name; int snum, ret; fstring jobstr; - BOOL owner; if (!pjob || !user) return False; if (!pjob->spooled || pjob->sysjob == -1) return False; snum = print_job_snum(jobid); - owner = is_owner(user, jobid); if (!is_owner(user, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { @@ -1401,4 +1398,3 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) return True; } -#undef OLD_NTDOMAIN -- cgit From 65d35749b721b76ae826a9423bdefd2f673f35c6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Mar 2001 05:55:30 +0000 Subject: Added Michael Sweet's CUPS patch to call directly into the CUPS backend. Parameterises the printing functions so other backends can be plugged directly in (this is a good thing :-). Jeremy. (This used to be commit c0345bbaed5d1aac777f1a33ff84ad1899f2ed6d) --- source3/printing/printing.c | 186 +++++++------------------------------------- 1 file changed, 29 insertions(+), 157 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 241135f744..84ed1a3993 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -19,10 +19,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "includes.h" +#include "printing.h" extern int DEBUGLEVEL; +/* Current printer interface */ +struct printif *current_printif = &generic_printif; + /* the printing backend revolves around a tdb database that stores the SMB view of the print queue @@ -37,34 +40,10 @@ extern int DEBUGLEVEL; jobids are assigned when a job starts spooling. */ -#define NEXT_JOBID(j) ((j+1) % PRINT_MAX_JOBID > 0 ? (j+1) % PRINT_MAX_JOBID : 1) - - -struct printjob { - pid_t pid; /* which process launched the job */ - int sysjob; /* the system (lp) job number */ - int fd; /* file descriptor of open file if open */ - time_t starttime; /* when the job started spooling */ - int status; /* the status of this job */ - size_t size; /* the size of the job so far */ - BOOL spooled; /* has it been sent to the spooler yet? */ - BOOL smbjob; /* set if the job is a SMB job */ - fstring filename; /* the filename used to spool the file */ - fstring jobname; /* the job name given to us by the client */ - fstring user; /* the user who started the job */ - fstring qname; /* name of the print queue the job was sent to */ -}; - /* the open printing.tdb database */ static TDB_CONTEXT *tdb; static pid_t local_pid; -#define PRINT_MAX_JOBID 10000 -#define UNIX_JOB_START PRINT_MAX_JOBID - -#define PRINT_SPOOL_PREFIX "smbprn." -#define PRINT_DATABASE_VERSION 2 - static int get_queue_status(int, print_status_struct *); /**************************************************************************** @@ -92,6 +71,13 @@ BOOL print_backend_init(void) } tdb_unlock_bystring(tdb, sversion); + /* select the appropriate printing interface... */ +#ifdef HAVE_LIBCUPS + if (strcmp(lp_printcapname(), "cups") == 0) + current_printif = &cups_printif; +#endif /* HAVE_LIBCUPS */ + + /* do NT print initialization... */ return nt_printing_init(); } @@ -137,51 +123,6 @@ static BOOL print_job_store(int jobid, struct printjob *pjob) return (tdb_store(tdb, print_key(jobid), d, TDB_REPLACE) == 0); } -/**************************************************************************** -run a given print command -a null terminated list of value/substitute pairs is provided -for local substitution strings -****************************************************************************/ -static int print_run_command(int snum,char *command, - char *outfile, - ...) -{ - pstring syscmd; - char *p, *arg; - int ret; - va_list ap; - - if (!command || !*command) return -1; - - if (!VALID_SNUM(snum)) { - DEBUG(0,("Invalid snum %d for command %s\n", snum, command)); - return -1; - } - - pstrcpy(syscmd, command); - - va_start(ap, outfile); - while ((arg = va_arg(ap, char *))) { - char *value = va_arg(ap,char *); - pstring_sub(syscmd, arg, value); - } - va_end(ap); - - p = PRINTERNAME(snum); - - pstring_sub(syscmd, "%p", p); - standard_sub_snum(snum,syscmd); - - /* Convert script args to unix-codepage */ - dos_to_unix(syscmd, True); - ret = smbrun(syscmd,outfile,False); - - DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); - - return ret; -} - - /**************************************************************************** parse a file name from the system spooler to generate a jobid ****************************************************************************/ @@ -378,11 +319,7 @@ update the internal database from the system print queue for a queue static void print_queue_update(int snum) { - char *path = lp_pathname(snum); - char *cmd = lp_lpqcommand(snum); - char **qlines; - pstring tmp_file; - int numlines, i, qcount; + int i, qcount; print_queue_struct *queue = NULL; print_status_struct status; print_status_struct old_status; @@ -446,31 +383,10 @@ static void print_queue_update(int snum) slprintf(cachestr, sizeof(cachestr), "CACHE/%s", printer_name); tdb_store_int(tdb, cachestr, (int)time(NULL)); - slprintf(tmp_file, sizeof(tmp_file), "%s/smblpq.%d", path, local_pid); - - unlink(tmp_file); - print_run_command(snum, cmd, tmp_file, NULL); - - numlines = 0; - qlines = file_lines_load(tmp_file, &numlines, True); - unlink(tmp_file); - - /* turn the lpq output into a series of job structures */ - qcount = 0; + /* get the current queue using the appropriate interface */ ZERO_STRUCT(status); - if (numlines) - queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(numlines+1)); - - if (queue) { - for (i=0; iqueue_get))(snum, &queue, &status); DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ? "s" : "", printer_name)); @@ -658,17 +574,14 @@ static BOOL print_job_delete1(int jobid) pjob->status = LPQ_DELETING; print_job_store(jobid, pjob); - if (pjob->spooled && pjob->sysjob != -1) { - fstring jobstr; - - /* need to delete the spooled entry */ - slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob); - result = print_run_command( - snum, - lp_lprmcommand(snum), NULL, - "%j", jobstr, - "%T", http_timestring(pjob->starttime), - NULL); + if (pjob->spooled && pjob->sysjob != -1) + result = (*(current_printif->job_delete))(snum, pjob); + + /* Delete the tdb entry if the delete suceeded or the job hasn't + been spooled. */ + + if (result == 0) { + tdb_delete(tdb, print_key(jobid)); } return (result == 0); @@ -739,17 +652,14 @@ BOOL print_job_pause(struct current_user *user, int jobid, int *errcode) struct printjob *pjob = print_job_find(jobid); int snum, ret = -1; char *printer_name; - fstring jobstr; - BOOL owner; if (!pjob || !user) return False; if (!pjob->spooled || pjob->sysjob == -1) return False; snum = print_job_snum(jobid); - owner = is_owner(user, jobid); - if (!owner && + if (!is_owner(user, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("pause denied by security descriptor\n")); *errcode = ERROR_ACCESS_DENIED; @@ -757,11 +667,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, int *errcode) } /* need to pause the spooled entry */ - slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob); - ret = print_run_command(snum, - lp_lppausecommand(snum), NULL, - "%j", jobstr, - NULL); + ret = (*(current_printif->job_pause))(snum, pjob); if (ret != 0) { *errcode = ERROR_INVALID_PARAMETER; @@ -790,7 +696,6 @@ BOOL print_job_resume(struct current_user *user, int jobid, int *errcode) struct printjob *pjob = print_job_find(jobid); char *printer_name; int snum, ret; - fstring jobstr; if (!pjob || !user) return False; @@ -805,11 +710,7 @@ BOOL print_job_resume(struct current_user *user, int jobid, int *errcode) return False; } - slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob); - ret = print_run_command(snum, - lp_lpresumecommand(snum), NULL, - "%j", jobstr, - NULL); + ret = (*(current_printif->job_resume))(snum, pjob); if (ret != 0) { *errcode = ERROR_INVALID_PARAMETER; @@ -1056,10 +957,6 @@ BOOL print_job_end(int jobid, BOOL normal_close) struct printjob *pjob = print_job_find(jobid); int snum, ret; SMB_STRUCT_STAT sbuf; - pstring current_directory; - pstring print_directory; - char *wd, *p; - pstring jobname; if (!pjob) return False; @@ -1096,30 +993,7 @@ BOOL print_job_end(int jobid, BOOL normal_close) return True; } - /* we print from the directory path to give the best chance of - parsing the lpq output */ - wd = sys_getwd(current_directory); - if (!wd) goto fail; - - pstrcpy(print_directory, pjob->filename); - p = strrchr(print_directory,'/'); - if (!p) goto fail; - *p++ = 0; - - if (chdir(print_directory) != 0) goto fail; - - pstrcpy(jobname, pjob->jobname); - pstring_sub(jobname, "'", "_"); - - /* send it to the system spooler */ - ret = print_run_command(snum, - lp_printcommand(snum), NULL, - "%s", p, - "%J", jobname, - "%f", p, - NULL); - - chdir(wd); + ret = (*(current_printif->job_submit))(snum, pjob); if (ret) goto fail; @@ -1310,8 +1184,7 @@ BOOL print_queue_pause(struct current_user *user, int snum, int *errcode) return False; } - ret = print_run_command(snum, lp_queuepausecommand(snum), NULL, - NULL); + ret = (*(current_printif->queue_pause))(snum); if (ret != 0) { *errcode = ERROR_INVALID_PARAMETER; @@ -1343,8 +1216,7 @@ BOOL print_queue_resume(struct current_user *user, int snum, int *errcode) return False; } - ret = print_run_command(snum, lp_queueresumecommand(snum), NULL, - NULL); + ret = (*(current_printif->queue_resume))(snum); if (ret != 0) { *errcode = ERROR_INVALID_PARAMETER; -- cgit From 071a770ed444f2ed35d96a3b371dd587bd64f993 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 26 Mar 2001 22:15:40 +0000 Subject: Fix from Dave Collier Brown to log a debug at level zero on common misconfigure. Jeremy. (This used to be commit 4a3d2a13d3b0acab69c27b5b6522575b949eb5e6) --- source3/printing/printing.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 84ed1a3993..e886bd75a2 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -918,7 +918,19 @@ int print_job_start(struct current_user *user, int snum, char *jobname) goto next_jobnum; } pjob.fd = sys_open(pjob.filename,O_WRONLY|O_CREAT|O_EXCL,0600); - if (pjob.fd == -1) goto fail; + + if (pjob.fd == -1) { + if (errno == EACCES) { + /* Common setup error, force a report. */ + DEBUG(0, ("print_job_start: insufficient permissions \ +to open spool file %s.\n", pjob.filename)); + } else { + /* Normal case, report at level 3 and above. */ + DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename)); + DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno))); + } + goto fail; + } print_job_store(jobid, &pjob); -- cgit From f9a15ce1a69f905e94db7650f0a4805720cd9c88 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 8 Apr 2001 20:22:39 +0000 Subject: Got "medieval on our ass" about adding the -1 to slprintf. Jeremy. (This used to be commit 94747b4639ed9b19f7d0fb896e43aa392a84989a) --- source3/printing/printing.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index e886bd75a2..753d0f7f96 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -254,7 +254,7 @@ check if the print queue has been updated recently enough static void print_cache_flush(int snum) { fstring key; - slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum)); + slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum)); dos_to_unix(key, True); /* Convert key to unix-codepage */ tdb_store_int(tdb, key, -1); } @@ -269,7 +269,7 @@ static pid_t get_updating_pid(fstring printer_name) TDB_DATA data, key; pid_t updating_pid; - slprintf(keystr, sizeof(keystr), "UPDATING/%s", printer_name); + slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name); key.dptr = keystr; key.dsize = strlen(keystr); @@ -298,7 +298,7 @@ static void set_updating_pid(fstring printer_name, BOOL delete) TDB_DATA data; pid_t updating_pid = getpid(); - slprintf(keystr, sizeof(keystr), "UPDATING/%s", printer_name); + slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name); key.dptr = keystr; key.dsize = strlen(keystr); @@ -380,7 +380,7 @@ static void print_queue_update(int snum) * if the lpq takes a long time. */ - slprintf(cachestr, sizeof(cachestr), "CACHE/%s", printer_name); + slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name); tdb_store_int(tdb, cachestr, (int)time(NULL)); /* get the current queue using the appropriate interface */ @@ -452,7 +452,7 @@ static void print_queue_update(int snum) } /* store the new queue status structure */ - slprintf(keystr, sizeof(keystr), "STATUS/%s", printer_name); + slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name); key.dptr = keystr; key.dsize = strlen(keystr); @@ -466,7 +466,7 @@ static void print_queue_update(int snum) * as little as possible... */ - slprintf(keystr, sizeof(keystr), "CACHE/%s", printer_name); + slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name); tdb_store_int(tdb, keystr, (int)time(NULL)); /* Delete our pid from the db. */ @@ -751,7 +751,7 @@ static BOOL print_cache_expired(int snum) fstring key; time_t t2, t = time(NULL); - slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum)); + slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum)); dos_to_unix(key, True); /* Convert key to unix-codepage */ t2 = tdb_fetch_int(tdb, key); if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) { @@ -770,7 +770,7 @@ static int get_queue_status(int snum, print_status_struct *status) TDB_DATA data, key; ZERO_STRUCTP(status); - slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum)); + slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", lp_servicename(snum)); dos_to_unix(keystr, True); /* Convert key to unix-codepage */ key.dptr = keystr; key.dsize = strlen(keystr); @@ -912,7 +912,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) a symlink security hole - it allows us to use O_EXCL There may be old spool files owned by other users lying around. */ - slprintf(pjob.filename, sizeof(pjob.filename), "%s/%s%d", + slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%d", path, PRINT_SPOOL_PREFIX, jobid); if (unlink(pjob.filename) == -1 && errno != ENOENT) { goto next_jobnum; @@ -1120,7 +1120,7 @@ int print_queue_status(int snum, * be no jobs in the queue. */ ZERO_STRUCTP(status); - slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum)); + slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", lp_servicename(snum)); dos_to_unix(keystr, True); /* Convert key to unix-codepage */ key.dptr = keystr; key.dsize = strlen(keystr); -- cgit From 6f78636a56106c510545dc1c8218b3a90a486c67 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 18 Apr 2001 05:12:46 +0000 Subject: Removed mktemp from HEAD - same as done in 2.2. Jeremy. (This used to be commit 121b59669fbcd1aaedb08011ff36169fc6561c55) --- source3/printing/printing.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 753d0f7f96..d98c7c4d4c 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -386,7 +386,7 @@ static void print_queue_update(int snum) /* get the current queue using the appropriate interface */ ZERO_STRUCT(status); - qcount = (*(current_printif->queue_get))(snum, &queue, &status); + qcount = (*(current_printif->queue_get))(snum, &queue, &status); DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ? "s" : "", printer_name)); @@ -575,7 +575,7 @@ static BOOL print_job_delete1(int jobid) print_job_store(jobid, pjob); if (pjob->spooled && pjob->sysjob != -1) - result = (*(current_printif->job_delete))(snum, pjob); + result = (*(current_printif->job_delete))(snum, pjob); /* Delete the tdb entry if the delete suceeded or the job hasn't been spooled. */ @@ -667,7 +667,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, int *errcode) } /* need to pause the spooled entry */ - ret = (*(current_printif->job_pause))(snum, pjob); + ret = (*(current_printif->job_pause))(snum, pjob); if (ret != 0) { *errcode = ERROR_INVALID_PARAMETER; @@ -892,7 +892,6 @@ int print_job_start(struct current_user *user, int snum, char *jobname) /* lock the database */ tdb_lock_bystring(tdb, "INFO/nextjob"); - next_jobnum: next_jobid = tdb_fetch_int(tdb, "INFO/nextjob"); if (next_jobid == -1) next_jobid = 1; @@ -906,18 +905,10 @@ int print_job_start(struct current_user *user, int snum, char *jobname) tdb_store_int(tdb, "INFO/nextjob", jobid); - /* we have a job entry - now create the spool file - - we unlink first to cope with old spool files and also to beat - a symlink security hole - it allows us to use O_EXCL - There may be old spool files owned by other users lying around. - */ - slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%d", - path, PRINT_SPOOL_PREFIX, jobid); - if (unlink(pjob.filename) == -1 && errno != ENOENT) { - goto next_jobnum; - } - pjob.fd = sys_open(pjob.filename,O_WRONLY|O_CREAT|O_EXCL,0600); + /* we have a job entry - now create the spool file */ + slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%sXXXXXX", + path, PRINT_SPOOL_PREFIX); + pjob.fd = smb_mkstemp(pjob.filename); if (pjob.fd == -1) { if (errno == EACCES) { -- cgit From 05fc3e578c895f632b351969d09cd00feb7599c7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Jun 2001 05:13:59 +0000 Subject: use LDSHFLAGS not -shared in several places (This used to be commit 8ec9c87b5d1a7dae17d5b1a30f58effaf5e69e4b) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index d98c7c4d4c..5fd2fc5680 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -55,7 +55,7 @@ BOOL print_backend_init(void) char *sversion = "INFO/version"; if (tdb && local_pid == sys_getpid()) return True; - tdb = tdb_open(lock_path("printing.tdb"), 0, 0, O_RDWR|O_CREAT, 0600); + tdb = tdb_open_log(lock_path("printing.tdb"), 0, 0, O_RDWR|O_CREAT, 0600); if (!tdb) { DEBUG(0,("print_backend_init: Failed to open printing backend database. Error = [%s]\n", tdb_errorstr(tdb))); -- cgit From eb57553512d22fa2de4233cf7161a4cbb55ce04a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 28 Jun 2001 19:23:43 +0000 Subject: Properly instrument print_job_start()/print_job_end() so every fail case logs a debug. We need this to track fail cases. Jeremy (This used to be commit fe5cac150d7491a7dfdaf2a54998178bbfe5a303) --- source3/printing/printing.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 5fd2fc5680..aab4c2f43f 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -845,6 +845,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) SMB_BIG_UINT dspace, dsize; if (sys_fsusage(path, &dspace, &dsize) == 0 && dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) { + DEBUG(3, ("print_job_start: disk space check failed.\n")); errno = ENOSPC; return -1; } @@ -852,18 +853,23 @@ int print_job_start(struct current_user *user, int snum, char *jobname) /* for autoloaded printers, check that the printcap entry still exists */ if (lp_autoloaded(snum) && !pcap_printername_ok(lp_servicename(snum), NULL)) { + DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_servicename(snum) )); errno = ENOENT; return -1; } /* Insure the maximum queue size is not violated */ if (lp_maxprintjobs(snum) && print_queue_length(snum) > lp_maxprintjobs(snum)) { + DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per queue (%d).\n", + print_queue_length(snum), lp_maxprintjobs(snum) )); errno = ENOSPC; return -1; } /* Insure the maximum print jobs in the system is not violated */ if (lp_totalprintjobs() && get_total_jobs(snum) > lp_totalprintjobs()) { + DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per system (%d).\n", + print_queue_length(snum), lp_totalprintjobs() )); errno = ENOSPC; return -1; } @@ -893,12 +899,16 @@ int print_job_start(struct current_user *user, int snum, char *jobname) tdb_lock_bystring(tdb, "INFO/nextjob"); next_jobid = tdb_fetch_int(tdb, "INFO/nextjob"); - if (next_jobid == -1) next_jobid = 1; + if (next_jobid == -1) + next_jobid = 1; for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) { - if (!print_job_exists(jobid)) break; + if (!print_job_exists(jobid)) + break; } if (jobid == next_jobid || !print_job_store(jobid, &pjob)) { + DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or print_job_store failed.\n", + jobid, next_jobid )); jobid = -1; goto fail; } @@ -946,6 +956,8 @@ to open spool file %s.\n", pjob.filename)); } tdb_unlock_bystring(tdb, "INFO/nextjob"); + + DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) )); return -1; } @@ -981,6 +993,7 @@ BOOL print_job_end(int jobid, BOOL normal_close) */ close(pjob->fd); pjob->fd = -1; + DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid )); goto fail; } @@ -998,7 +1011,8 @@ BOOL print_job_end(int jobid, BOOL normal_close) ret = (*(current_printif->job_submit))(snum, pjob); - if (ret) goto fail; + if (ret) + goto fail; /* The print job has been sucessfully handed over to the back-end */ @@ -1007,11 +1021,13 @@ BOOL print_job_end(int jobid, BOOL normal_close) print_job_store(jobid, pjob); /* make sure the database is up to date */ - if (print_cache_expired(snum)) print_queue_update(snum); + if (print_cache_expired(snum)) + print_queue_update(snum); return True; fail: + /* The print job was not succesfully started. Cleanup */ /* Still need to add proper error return propagation! 010122:JRR */ unlink(pjob->filename); -- cgit From 87fbb7092b8f8b2f0db0f361c3d625e19de57cd9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 4 Jul 2001 07:15:53 +0000 Subject: The big character set handling changeover! This commit gets rid of all our old codepage handling and replaces it with iconv. All internal strings in Samba are now in "unix" charset, which may be multi-byte. See internals.doc and my posting to samba-technical for a more complete explanation. (This used to be commit debb471267960e56005a741817ebd227ecfc512a) --- source3/printing/printing.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index aab4c2f43f..d0a07ccb4c 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -255,7 +255,6 @@ static void print_cache_flush(int snum) { fstring key; slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum)); - dos_to_unix(key, True); /* Convert key to unix-codepage */ tdb_store_int(tdb, key, -1); } @@ -328,10 +327,7 @@ static void print_queue_update(int snum) fstring keystr, printer_name, cachestr; TDB_DATA data, key; - /* Convert printer name (i.e. share name) to unix-codepage for all of the - * following tdb key generation */ fstrcpy(printer_name, lp_servicename(snum)); - dos_to_unix(printer_name, True); /* * Check to see if someone else is doing this update. @@ -598,11 +594,9 @@ static BOOL is_owner(struct current_user *user, int jobid) if (!pjob || !user) return False; if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { - return strequal(pjob->user, - unix_to_dos(vuser->user.smb_name,False)); + return strequal(pjob->user, vuser->user.smb_name); } else { - return strequal(pjob->user, - unix_to_dos(uidtoname(user->uid),False)); + return strequal(pjob->user, uidtoname(user->uid)); } } @@ -752,7 +746,6 @@ static BOOL print_cache_expired(int snum) time_t t2, t = time(NULL); slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum)); - dos_to_unix(key, True); /* Convert key to unix-codepage */ t2 = tdb_fetch_int(tdb, key); if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) { DEBUG(3, ("print cache expired\n")); @@ -771,7 +764,6 @@ static int get_queue_status(int snum, print_status_struct *status) ZERO_STRUCTP(status); slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", lp_servicename(snum)); - dos_to_unix(keystr, True); /* Convert key to unix-codepage */ key.dptr = keystr; key.dsize = strlen(keystr); data = tdb_fetch(tdb, key); @@ -888,9 +880,9 @@ int print_job_start(struct current_user *user, int snum, char *jobname) fstrcpy(pjob.jobname, jobname); if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { - fstrcpy(pjob.user, unix_to_dos(vuser->user.smb_name,False)); + fstrcpy(pjob.user, vuser->user.smb_name); } else { - fstrcpy(pjob.user, unix_to_dos(uidtoname(user->uid),False)); + fstrcpy(pjob.user, uidtoname(user->uid)); } fstrcpy(pjob.qname, lp_servicename(snum)); @@ -1128,7 +1120,6 @@ int print_queue_status(int snum, */ ZERO_STRUCTP(status); slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", lp_servicename(snum)); - dos_to_unix(keystr, True); /* Convert key to unix-codepage */ key.dptr = keystr; key.dsize = strlen(keystr); data = tdb_fetch(tdb, key); -- cgit From a92134c5a41b2687134617e86e083ef38d7ed2e7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 16 Jul 2001 23:39:26 +0000 Subject: Fix for incorrect creation of print job names, based on a patch by José M.Rodríguez Jeremy. (This used to be commit 7ebf284ef7597ee347deb5245d6ba222a102f55d) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source3/printing/printing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index d0a07ccb4c..fdb9018ede 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -908,8 +908,8 @@ int print_job_start(struct current_user *user, int snum, char *jobname) tdb_store_int(tdb, "INFO/nextjob", jobid); /* we have a job entry - now create the spool file */ - slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%sXXXXXX", - path, PRINT_SPOOL_PREFIX); + slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.6d.XXXXXX", + path, PRINT_SPOOL_PREFIX, jobid); pjob.fd = smb_mkstemp(pjob.filename); if (pjob.fd == -1) { -- cgit From 047a7c88d7d004f1581f585dd31caea388ab6f0d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 10 Aug 2001 05:41:53 +0000 Subject: Replaced the duplicate DOS constants with appropriate ones from doserr.h to emphasise the fact that the spoolss pipe returns DOS error codes instead of 32-bit nt status codes. (This used to be commit 5f5ed41ee872d842e944cd2e84a80de714ad4385) --- source3/printing/printing.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index fdb9018ede..17bea61f86 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -617,7 +617,7 @@ BOOL print_job_delete(struct current_user *user, int jobid, int *errcode) if (!owner && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("delete denied by security descriptor\n")); - *errcode = ERROR_ACCESS_DENIED; + *errcode = ERRnoaccess; return False; } @@ -656,7 +656,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, int *errcode) if (!is_owner(user, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("pause denied by security descriptor\n")); - *errcode = ERROR_ACCESS_DENIED; + *errcode = ERRnoaccess; return False; } @@ -664,7 +664,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, int *errcode) ret = (*(current_printif->job_pause))(snum, pjob); if (ret != 0) { - *errcode = ERROR_INVALID_PARAMETER; + *errcode = ERRinvalidparam; return False; } @@ -700,14 +700,14 @@ BOOL print_job_resume(struct current_user *user, int jobid, int *errcode) if (!is_owner(user, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("resume denied by security descriptor\n")); - *errcode = ERROR_ACCESS_DENIED; + *errcode = ERRnoaccess; return False; } ret = (*(current_printif->job_resume))(snum, pjob); if (ret != 0) { - *errcode = ERROR_INVALID_PARAMETER; + *errcode = ERRinvalidparam; return False; } @@ -1190,14 +1190,14 @@ BOOL print_queue_pause(struct current_user *user, int snum, int *errcode) int ret; if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { - *errcode = ERROR_ACCESS_DENIED; + *errcode = ERRnoaccess; return False; } ret = (*(current_printif->queue_pause))(snum); if (ret != 0) { - *errcode = ERROR_INVALID_PARAMETER; + *errcode = ERRinvalidparam; return False; } @@ -1222,14 +1222,14 @@ BOOL print_queue_resume(struct current_user *user, int snum, int *errcode) int ret; if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { - *errcode = ERROR_ACCESS_DENIED; + *errcode = ERRnoaccess; return False; } ret = (*(current_printif->queue_resume))(snum); if (ret != 0) { - *errcode = ERROR_INVALID_PARAMETER; + *errcode = ERRinvalidparam; return False; } -- cgit From 4b2016305b7c43c61198f25175531d149db5e989 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Aug 2001 19:38:53 +0000 Subject: Merge in the NT drivers changes from 2.2. Jeremy. (This used to be commit a3781ad38ff6c70238e7e9b83324477e5c9780d5) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 17bea61f86..f1eaf3723c 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -55,7 +55,7 @@ BOOL print_backend_init(void) char *sversion = "INFO/version"; if (tdb && local_pid == sys_getpid()) return True; - tdb = tdb_open_log(lock_path("printing.tdb"), 0, 0, O_RDWR|O_CREAT, 0600); + tdb = tdb_open_log(lock_path("printing.tdb"), 0, USE_TDB_MMAP_FLAG, O_RDWR|O_CREAT, 0600); if (!tdb) { DEBUG(0,("print_backend_init: Failed to open printing backend database. Error = [%s]\n", tdb_errorstr(tdb))); -- cgit From d1f53e404496dff10df7dc5e5b58ed676982c955 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 23 Aug 2001 19:06:20 +0000 Subject: Fixed detection of CUPS. We need to check for the presence of the cups header files as well as libcups. (This used to be commit 2dbb41a7b88e7fad63579111aaab4a1cd28c54d5) --- source3/printing/printing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index f1eaf3723c..370abd4fdf 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -72,10 +72,10 @@ BOOL print_backend_init(void) tdb_unlock_bystring(tdb, sversion); /* select the appropriate printing interface... */ -#ifdef HAVE_LIBCUPS +#ifdef HAVE_CUPS if (strcmp(lp_printcapname(), "cups") == 0) current_printif = &cups_printif; -#endif /* HAVE_LIBCUPS */ +#endif /* HAVE_CUPS */ /* do NT print initialization... */ return nt_printing_init(); -- cgit From fbc1f326f445a2826a10155fe0122c779bb1f80e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Sep 2001 10:38:13 +0000 Subject: more NTSTATUS/WERROR conversion (This used to be commit ad648c5cd8ebe4be8304379117f403d7673dcbc8) --- source3/printing/printing.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 370abd4fdf..8be46488dd 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -603,7 +603,7 @@ static BOOL is_owner(struct current_user *user, int jobid) /**************************************************************************** delete a print job ****************************************************************************/ -BOOL print_job_delete(struct current_user *user, int jobid, int *errcode) +BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode) { int snum = print_job_snum(jobid); char *printer_name; @@ -617,7 +617,7 @@ BOOL print_job_delete(struct current_user *user, int jobid, int *errcode) if (!owner && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("delete denied by security descriptor\n")); - *errcode = ERRnoaccess; + *errcode = WERR_ACCESS_DENIED; return False; } @@ -641,7 +641,7 @@ BOOL print_job_delete(struct current_user *user, int jobid, int *errcode) /**************************************************************************** pause a job ****************************************************************************/ -BOOL print_job_pause(struct current_user *user, int jobid, int *errcode) +BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode) { struct printjob *pjob = print_job_find(jobid); int snum, ret = -1; @@ -685,7 +685,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, int *errcode) /**************************************************************************** resume a job ****************************************************************************/ -BOOL print_job_resume(struct current_user *user, int jobid, int *errcode) +BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode) { struct printjob *pjob = print_job_find(jobid); char *printer_name; @@ -1184,20 +1184,20 @@ int print_queue_snum(char *qname) /**************************************************************************** pause a queue ****************************************************************************/ -BOOL print_queue_pause(struct current_user *user, int snum, int *errcode) +BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode) { char *printer_name; int ret; if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { - *errcode = ERRnoaccess; + *errcode = WERR_ACCESS_DENIED; return False; } ret = (*(current_printif->queue_pause))(snum); if (ret != 0) { - *errcode = ERRinvalidparam; + *errcode = WERR_INVALID_PARAM; return False; } @@ -1216,20 +1216,20 @@ BOOL print_queue_pause(struct current_user *user, int snum, int *errcode) /**************************************************************************** resume a queue ****************************************************************************/ -BOOL print_queue_resume(struct current_user *user, int snum, int *errcode) +BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode) { char *printer_name; int ret; if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { - *errcode = ERRnoaccess; + *errcode = WERR_ACCESS_DENIED; return False; } ret = (*(current_printif->queue_resume))(snum); if (ret != 0) { - *errcode = ERRinvalidparam; + *errcode = WERR_INVALID_PARAM; return False; } @@ -1248,7 +1248,7 @@ BOOL print_queue_resume(struct current_user *user, int snum, int *errcode) /**************************************************************************** purge a queue - implemented by deleting all jobs that we can delete ****************************************************************************/ -BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) +BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode) { print_queue_struct *queue; print_status_struct status; -- cgit From 19fea3242cf6234786b6cbb60631e0071f31ff9f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Sep 2001 07:13:01 +0000 Subject: the next stage in the NTSTATUS/WERROR change. smbd and nmbd now compile, but the client code still needs some work (This used to be commit dcd6e735f709a9231860ceb9682db40ff26c9a66) --- source3/printing/printing.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 8be46488dd..e0eb2a06d7 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -656,7 +656,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode) if (!is_owner(user, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("pause denied by security descriptor\n")); - *errcode = ERRnoaccess; + *errcode = WERR_ACCESS_DENIED; return False; } @@ -664,7 +664,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode) ret = (*(current_printif->job_pause))(snum, pjob); if (ret != 0) { - *errcode = ERRinvalidparam; + *errcode = WERR_INVALID_PARAM; return False; } @@ -700,14 +700,14 @@ BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode) if (!is_owner(user, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("resume denied by security descriptor\n")); - *errcode = ERRnoaccess; + *errcode = WERR_ACCESS_DENIED; return False; } ret = (*(current_printif->job_resume))(snum, pjob); if (ret != 0) { - *errcode = ERRinvalidparam; + *errcode = WERR_INVALID_PARAM; return False; } -- cgit From 9a9ac2739bbdc993ecdfa78298bdd9c059328378 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Sep 2001 22:08:19 +0000 Subject: got rid of USE_TDB_MMAP_FLAG as its not needed any more (This used to be commit c26e0d3f27a05ecc8bd2390f9aab7f9451524e47) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index e0eb2a06d7..301422c1c2 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -55,7 +55,7 @@ BOOL print_backend_init(void) char *sversion = "INFO/version"; if (tdb && local_pid == sys_getpid()) return True; - tdb = tdb_open_log(lock_path("printing.tdb"), 0, USE_TDB_MMAP_FLAG, O_RDWR|O_CREAT, 0600); + tdb = tdb_open_log(lock_path("printing.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); if (!tdb) { DEBUG(0,("print_backend_init: Failed to open printing backend database. Error = [%s]\n", tdb_errorstr(tdb))); -- cgit From dc1fc3ee8ec2199bc73bb5d7ec711c6800f61d65 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 Oct 2001 04:29:50 +0000 Subject: Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header. (This used to be commit 2d0922b0eabfdc0aaf1d0797482fef47ed7fde8e) --- source3/printing/printing.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 301422c1c2..9135cb2d5e 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -21,8 +21,6 @@ #include "printing.h" -extern int DEBUGLEVEL; - /* Current printer interface */ struct printif *current_printif = &generic_printif; -- cgit From 3f1d1008428f9563d33dff96d1304e30dae3d0f2 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Tue, 16 Oct 2001 23:16:00 +0000 Subject: very simple asynchronous "lpq" thread patch To speed up operations with the lpq command, it's now run in a separate asynchronous process. Opening the Printers folder on NT is now fast ;-) I think even faster than with a ** server Jeremy, you should look at that patch to include it in 2.2.3 J.F. (This used to be commit 8ef9dff3074e7979579ce66a204e8ec7bf62a587) --- source3/printing/printing.c | 52 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 9135cb2d5e..db67585332 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -311,10 +311,10 @@ static void set_updating_pid(fstring printer_name, BOOL delete) } /**************************************************************************** -update the internal database from the system print queue for a queue +update the internal database from the system print queue for a queue in the background ****************************************************************************/ -static void print_queue_update(int snum) +static void print_queue_update_background(int snum) { int i, qcount; print_queue_struct *queue = NULL; @@ -467,6 +467,54 @@ static void print_queue_update(int snum) set_updating_pid(printer_name, True); } +/**************************************************************************** +this is the receive function of the background lpq updater +****************************************************************************/ +static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len) +{ + int snum; + snum=*((int *)buf); + print_queue_update_background(snum); +} + +/**************************************************************************** +main thread of the background lpq updater +****************************************************************************/ +void start_background_queue(void) +{ + DEBUG(3,("Starting background LPQ thread\n")); + if(sys_fork()==0) { + DEBUG(5,("background LPQ thread started\n")); + + claim_connection(NULL,"smbd lpq backend",MAXSTATUS,False); + + if (!locking_init(0)) { + exit(1); + } + + if (!print_backend_init()) { + exit(1); + } + + message_register(MSG_PRINTER_UPDATE, print_queue_receive); + + DEBUG(5,("background LPQ thread waiting for messages\n")); + while (1) { + pause(); + DEBUG(10,("background LPQ thread got a message\n")); + message_dispatch(); + } + } +} + +/**************************************************************************** +update the internal database from the system print queue for a queue +****************************************************************************/ +static void print_queue_update(int snum) +{ + message_send_all(conn_tdb_ctx(), MSG_PRINTER_UPDATE, &snum, sizeof(snum), False); +} + /**************************************************************************** check if a jobid is valid. It is valid if it exists in the database ****************************************************************************/ -- cgit From ca4c584fb553c650753e6c621d58c1fa71e8adc8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 16 Oct 2001 23:52:14 +0000 Subject: Optimisation to send only to correct processid. Jeremy (This used to be commit 3807c747a4522c719fe67b876e4a3bd92bffcf7f) --- source3/printing/printing.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index db67585332..acdaed46ae 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -477,14 +477,24 @@ static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len) print_queue_update_background(snum); } +static pid_t background_lpq_updater_pid; + /**************************************************************************** main thread of the background lpq updater ****************************************************************************/ void start_background_queue(void) { - DEBUG(3,("Starting background LPQ thread\n")); - if(sys_fork()==0) { - DEBUG(5,("background LPQ thread started\n")); + DEBUG(3,("start_background_queue: Starting background LPQ thread\n")); + background_lpq_updater_pid = sys_fork(); + + if (background_lpq_updater_pid == -1) { + DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) )); + exit(1); + } + + if(background_lpq_updater_pid == 0) { + /* Child. */ + DEBUG(5,("start_background_queue: background LPQ thread started\n")); claim_connection(NULL,"smbd lpq backend",MAXSTATUS,False); @@ -498,10 +508,10 @@ void start_background_queue(void) message_register(MSG_PRINTER_UPDATE, print_queue_receive); - DEBUG(5,("background LPQ thread waiting for messages\n")); + DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n")); while (1) { pause(); - DEBUG(10,("background LPQ thread got a message\n")); + DEBUG(10,("start_background_queue: background LPQ thread got a message\n")); message_dispatch(); } } @@ -512,7 +522,7 @@ update the internal database from the system print queue for a queue ****************************************************************************/ static void print_queue_update(int snum) { - message_send_all(conn_tdb_ctx(), MSG_PRINTER_UPDATE, &snum, sizeof(snum), False); + message_send_pid(background_lpq_updater_pid, MSG_PRINTER_UPDATE, &snum, sizeof(snum), False); } /**************************************************************************** -- cgit From 547263873017bd7e042f8826b68a3136c4e3b2f8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Dec 2001 00:54:33 +0000 Subject: Improved efficiency of enumerating print queue's under a particular extreme condition... Jeremy. (This used to be commit 425bb0f40526b4eb17a3033892ca907b1d5293a4) --- source3/printing/printing.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index acdaed46ae..4f50b402c1 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -804,7 +804,9 @@ static BOOL print_cache_expired(int snum) slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum)); t2 = tdb_fetch_int(tdb, key); if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) { - DEBUG(3, ("print cache expired\n")); + DEBUG(3, ("print cache expired for queue %s \ +(last_cache = %d, time now = %d, qcachetime = %d)\n", lp_servicename(snum), + (int)t2, (int)t, (int)lp_lpqcachetime() )); return True; } return False; @@ -835,15 +837,21 @@ static int get_queue_status(int snum, print_status_struct *status) /**************************************************************************** Determine the number of jobs in a queue. ****************************************************************************/ -static int print_queue_length(int snum) + +int print_queue_length(int snum, print_status_struct *pstatus) { print_status_struct status; - + int len; + /* make sure the database is up to date */ - if (print_cache_expired(snum)) print_queue_update(snum); - + if (print_cache_expired(snum)) + print_queue_update(snum); + /* also fetch the queue status */ - return get_queue_status(snum, &status); + len = get_queue_status(snum, &status); + if (pstatus) + *pstatus = status; + return len; } /**************************************************************************** @@ -873,6 +881,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) struct printjob pjob; int next_jobid; user_struct *vuser; + int njobs; errno = 0; @@ -907,9 +916,9 @@ int print_job_start(struct current_user *user, int snum, char *jobname) } /* Insure the maximum queue size is not violated */ - if (lp_maxprintjobs(snum) && print_queue_length(snum) > lp_maxprintjobs(snum)) { + if (lp_maxprintjobs(snum) && (njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) { DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per queue (%d).\n", - print_queue_length(snum), lp_maxprintjobs(snum) )); + njobs, lp_maxprintjobs(snum) )); errno = ENOSPC; return -1; } @@ -917,7 +926,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) /* Insure the maximum print jobs in the system is not violated */ if (lp_totalprintjobs() && get_total_jobs(snum) > lp_totalprintjobs()) { DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per system (%d).\n", - print_queue_length(snum), lp_totalprintjobs() )); + njobs, lp_totalprintjobs() )); errno = ENOSPC; return -1; } -- cgit From 105f8a1a0fcce360c427a69fd4201c625cedc7d8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Dec 2001 02:11:03 +0000 Subject: Use print_queue_length() by preference if we don't need a queue as it doesn't do a traversal. Jeremy. (This used to be commit 4bf4ee3f14a690592fa2e1b800fc0344522e6b30) --- source3/printing/printing.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 4f50b402c1..f65355cb48 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -848,6 +848,7 @@ int print_queue_length(int snum, print_status_struct *pstatus) print_queue_update(snum); /* also fetch the queue status */ + memset(&status, 0, sizeof(status)); len = get_queue_status(snum, &status); if (pstatus) *pstatus = status; -- cgit From 7cb202e33cf3dd301729cea5adff3b7b1ca58ce3 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 18 Dec 2001 05:08:48 +0000 Subject: Fixed uninitialised variable warning. (This used to be commit 5095941dcb312d75c232d15232d5998ca05b632f) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index f65355cb48..fe16ee7283 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -882,7 +882,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) struct printjob pjob; int next_jobid; user_struct *vuser; - int njobs; + int njobs = 0; errno = 0; -- cgit From df28dee653ea2f685c7779fed80fe639784699f5 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Fri, 21 Dec 2001 00:37:09 +0000 Subject: Factor out a broadcast_printer_notify() routine. (This used to be commit d32598c953e7a500f707a02608c44203bc5941ec) --- source3/printing/printing.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index fe16ee7283..0a97cb52b3 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -246,6 +246,16 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void return 0; } +/** + * Send PRINTER NOTIFY to all processes. + **/ +void broadcast_printer_notify(const char *printer_name) +{ + /* include NUL */ + message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, + strlen(printer_name) + 1, False, NULL); +} + /**************************************************************************** check if the print queue has been updated recently enough ****************************************************************************/ @@ -442,7 +452,7 @@ static void print_queue_update_background(int snum) if( qcount != get_queue_status(snum, &old_status)) { DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n", old_status.qcount, qcount, printer_name )); - message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); + broadcast_printer_notify(printer_name); } /* store the new queue status structure */ @@ -688,7 +698,7 @@ BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode) printer_name = PRINTERNAME(snum); - message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); + broadcast_printer_notify(printer_name); return !print_job_exists(jobid); } @@ -731,7 +741,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode) printer_name = PRINTERNAME(snum); - message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); + broadcast_printer_notify(printer_name); /* how do we tell if this succeeded? */ @@ -774,7 +784,7 @@ BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode) printer_name = PRINTERNAME(snum); - message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); + broadcast_printer_notify(printer_name); return True; } @@ -1274,7 +1284,7 @@ BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode) printer_name = PRINTERNAME(snum); - message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); + broadcast_printer_notify(printer_name); return True; } @@ -1306,7 +1316,7 @@ BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode) printer_name = PRINTERNAME(snum); - message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); + broadcast_printer_notify(printer_name); return True; } @@ -1342,7 +1352,7 @@ BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode) printer_name = PRINTERNAME(snum); - message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False); + broadcast_printer_notify(printer_name); return True; } -- cgit From eca99f5c226f9518d1ab5c0ba3e586e3d59564d7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Jan 2002 22:48:48 +0000 Subject: Fixed nasty cast of tdb_delete in traversals. Jeremy. (This used to be commit a0cdec3acc82d1ce0292fadd4b8dac23638450f3) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 0a97cb52b3..ab966bd9f2 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -64,7 +64,7 @@ BOOL print_backend_init(void) /* handle a Samba upgrade */ tdb_lock_bystring(tdb, sversion); if (tdb_fetch_int(tdb, sversion) != PRINT_DATABASE_VERSION) { - tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL); + tdb_traverse(tdb, tdb_traverse_delete_fn, NULL); tdb_store_int(tdb, sversion, PRINT_DATABASE_VERSION); } tdb_unlock_bystring(tdb, sversion); -- cgit From 91536cc901088232074ad8dd7ae16e0f6026f25e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Jan 2002 04:13:30 +0000 Subject: Fixed all uses of tdb_fetch/store/_int to use explicit int32 little endian in tdb's. All except winbindd_idmap.... Hmmmmmm. Jeremy. (This used to be commit ec71f1732b6b27bd2d65b250a6f3720a235dc38d) --- source3/printing/printing.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index ab966bd9f2..08115cdb79 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -45,9 +45,10 @@ static pid_t local_pid; static int get_queue_status(int, print_status_struct *); /**************************************************************************** -initialise the printing backend. Called once at startup. -Does not survive a fork + Initialise the printing backend. Called once at startup. + Does not survive a fork ****************************************************************************/ + BOOL print_backend_init(void) { char *sversion = "INFO/version"; @@ -63,9 +64,9 @@ BOOL print_backend_init(void) /* handle a Samba upgrade */ tdb_lock_bystring(tdb, sversion); - if (tdb_fetch_int(tdb, sversion) != PRINT_DATABASE_VERSION) { + if (tdb_fetch_int32(tdb, sversion) != PRINT_DATABASE_VERSION) { tdb_traverse(tdb, tdb_traverse_delete_fn, NULL); - tdb_store_int(tdb, sversion, PRINT_DATABASE_VERSION); + tdb_store_int32(tdb, sversion, PRINT_DATABASE_VERSION); } tdb_unlock_bystring(tdb, sversion); @@ -263,7 +264,7 @@ static void print_cache_flush(int snum) { fstring key; slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum)); - tdb_store_int(tdb, key, -1); + tdb_store_int32(tdb, key, -1); } /**************************************************************************** @@ -385,7 +386,7 @@ static void print_queue_update_background(int snum) */ slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name); - tdb_store_int(tdb, cachestr, (int)time(NULL)); + tdb_store_int32(tdb, cachestr, (int)time(NULL)); /* get the current queue using the appropriate interface */ ZERO_STRUCT(status); @@ -441,7 +442,7 @@ static void print_queue_update_background(int snum) safe_free(tstruct.queue); - tdb_store_int(tdb, "INFO/total_jobs", tstruct.total_jobs); + tdb_store_int32(tdb, "INFO/total_jobs", tstruct.total_jobs); /* * Get the old print status. We will use this to compare the @@ -471,7 +472,7 @@ static void print_queue_update_background(int snum) */ slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name); - tdb_store_int(tdb, keystr, (int)time(NULL)); + tdb_store_int32(tdb, keystr, (int)time(NULL)); /* Delete our pid from the db. */ set_updating_pid(printer_name, True); @@ -812,7 +813,7 @@ static BOOL print_cache_expired(int snum) time_t t2, t = time(NULL); slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum)); - t2 = tdb_fetch_int(tdb, key); + t2 = tdb_fetch_int32(tdb, key); if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) { DEBUG(3, ("print cache expired for queue %s \ (last_cache = %d, time now = %d, qcachetime = %d)\n", lp_servicename(snum), @@ -875,7 +876,7 @@ static int get_total_jobs(int snum) /* make sure the database is up to date */ if (print_cache_expired(snum)) print_queue_update(snum); - total_jobs = tdb_fetch_int(tdb, "INFO/total_jobs"); + total_jobs = tdb_fetch_int32(tdb, "INFO/total_jobs"); if (total_jobs >0) return total_jobs; else @@ -966,7 +967,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) /* lock the database */ tdb_lock_bystring(tdb, "INFO/nextjob"); - next_jobid = tdb_fetch_int(tdb, "INFO/nextjob"); + next_jobid = tdb_fetch_int32(tdb, "INFO/nextjob"); if (next_jobid == -1) next_jobid = 1; @@ -981,7 +982,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) goto fail; } - tdb_store_int(tdb, "INFO/nextjob", jobid); + tdb_store_int32(tdb, "INFO/nextjob", jobid); /* we have a job entry - now create the spool file */ slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.6d.XXXXXX", -- cgit From 9e007457e4aa0ed8656782be1b8af42fc217614b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 14 Jan 2002 19:34:28 +0000 Subject: Removed MAXSTATUS which was set incorrectly - thus causing tdb traversal of the connections db on smbd startup. This should fix the Solaris large load bug.... (fingers crossed). Jeremy. (This used to be commit 5b2b9c25af28543e67762805d1387524cbb6c39d) --- source3/printing/printing.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 08115cdb79..339ca721c6 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -507,15 +507,13 @@ void start_background_queue(void) /* Child. */ DEBUG(5,("start_background_queue: background LPQ thread started\n")); - claim_connection(NULL,"smbd lpq backend",MAXSTATUS,False); + claim_connection(NULL,"smbd lpq backend",0,False); - if (!locking_init(0)) { + if (!locking_init(0)) exit(1); - } - if (!print_backend_init()) { + if (!print_backend_init()) exit(1); - } message_register(MSG_PRINTER_UPDATE, print_queue_receive); -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/printing/printing.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 339ca721c6..10466cd5f2 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. printing backend routines Copyright (C) Andrew Tridgell 1992-2000 -- cgit From 2f8452fd49dd34da5cd07629dcba937861dd0731 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 25 Feb 2002 23:18:05 +0000 Subject: Merge of printing performance fixes from appliance. (This used to be commit c8dc59dfe877f63bea6976b7d7fd448e0c8722ba) --- source3/printing/printing.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 10466cd5f2..f783f8d590 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -163,7 +163,7 @@ static void print_unix_job(int snum, print_queue_struct *q) fstrcpy(pj.filename, ""); fstrcpy(pj.jobname, q->file); fstrcpy(pj.user, q->user); - fstrcpy(pj.qname, lp_servicename(snum)); + pj.snum = snum; print_job_store(jobid, &pj); } @@ -185,7 +185,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void memcpy(&jobid, key.dptr, sizeof(jobid)); memcpy(&pjob, data.dptr, sizeof(pjob)); - if (strcmp(lp_servicename(ts->snum), pjob.qname)) { + if (ts->snum != pjob.snum) { /* this isn't for the queue we are looking at */ ts->total_jobs++; return 0; @@ -552,7 +552,7 @@ int print_job_snum(int jobid) struct printjob *pjob = print_job_find(jobid); if (!pjob) return -1; - return lp_servicenumber(pjob->qname); + return pjob->snum; } /**************************************************************************** @@ -959,7 +959,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) fstrcpy(pjob.user, uidtoname(user->uid)); } - fstrcpy(pjob.qname, lp_servicename(snum)); + pjob.snum = snum; /* lock the database */ tdb_lock_bystring(tdb, "INFO/nextjob"); @@ -1113,7 +1113,7 @@ static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void * memcpy(&pjob, data.dptr, sizeof(pjob)); /* maybe it isn't for this queue */ - if (ts->snum != print_queue_snum(pjob.qname)) return 0; + if (ts->snum != pjob.snum) return 0; if (ts->qcount >= ts->maxcount) return 0; @@ -1148,7 +1148,7 @@ static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, memcpy(&pjob, data.dptr, sizeof(pjob)); /* maybe it isn't for this queue */ - if (ts->snum != print_queue_snum(pjob.qname)) return 0; + if (ts->snum != pjob.snum) return 0; ts->count++; -- cgit From 2ff93902451a234e78490a1b18c2fae43d997b01 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 26 Feb 2002 03:12:09 +0000 Subject: Fixup the sending of printer change messages from job changes. Jeremy. (This used to be commit 28d4e7a3e2bd8f15ef807b821e4300a72bbc6904) --- source3/printing/printing.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index f783f8d590..7d4a52c351 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -246,16 +246,6 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void return 0; } -/** - * Send PRINTER NOTIFY to all processes. - **/ -void broadcast_printer_notify(const char *printer_name) -{ - /* include NUL */ - message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, - strlen(printer_name) + 1, False, NULL); -} - /**************************************************************************** check if the print queue has been updated recently enough ****************************************************************************/ @@ -320,6 +310,20 @@ static void set_updating_pid(fstring printer_name, BOOL delete) tdb_store(tdb, key, data, TDB_REPLACE); } +/**************************************************************************** + Send a message saying the queue changed. +****************************************************************************/ + +static void send_queue_message(const char *printer_name, uint32 high, uint32 low) +{ + char msg[8 + sizeof(fstring)]; + SIVAL(msg,0,low); + SIVAL(msg,4,high); + fstrcpy(&msg[8], printer_name); + + message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, msg, 8 + strlen(printer_name) + 1, False, NULL); +} + /**************************************************************************** update the internal database from the system print queue for a queue in the background ****************************************************************************/ @@ -452,7 +456,7 @@ static void print_queue_update_background(int snum) if( qcount != get_queue_status(snum, &old_status)) { DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n", old_status.qcount, qcount, printer_name )); - broadcast_printer_notify(printer_name); + send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB); } /* store the new queue status structure */ @@ -696,7 +700,7 @@ BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode) printer_name = PRINTERNAME(snum); - broadcast_printer_notify(printer_name); + send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB); return !print_job_exists(jobid); } @@ -739,7 +743,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode) printer_name = PRINTERNAME(snum); - broadcast_printer_notify(printer_name); + send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB); /* how do we tell if this succeeded? */ @@ -782,7 +786,7 @@ BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode) printer_name = PRINTERNAME(snum); - broadcast_printer_notify(printer_name); + send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB); return True; } @@ -1282,7 +1286,7 @@ BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode) printer_name = PRINTERNAME(snum); - broadcast_printer_notify(printer_name); + send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB); return True; } @@ -1314,7 +1318,7 @@ BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode) printer_name = PRINTERNAME(snum); - broadcast_printer_notify(printer_name); + send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB); return True; } @@ -1350,7 +1354,7 @@ BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode) printer_name = PRINTERNAME(snum); - broadcast_printer_notify(printer_name); + send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB); return True; } -- cgit From 024e69da0b4bbbe4112d3ce5526f90eb0b85bba0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Mar 2002 21:51:59 +0000 Subject: Fix for machines that have their time changed forward, then back. Ensure that any cached lpq information gathered during that time doesn't stay around for longer than 1 hour. Jeremy. (This used to be commit 39fca711a5cf15a03d6c79639b202712d1749a64) --- source3/printing/printing.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 7d4a52c351..81a44d7e69 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -811,14 +811,26 @@ int print_job_write(int jobid, const char *buf, int size) static BOOL print_cache_expired(int snum) { fstring key; - time_t t2, t = time(NULL); + time_t last_qscan_time, time_now = time(NULL); - slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum)); - t2 = tdb_fetch_int32(tdb, key); - if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) { + slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum)); + last_qscan_time = (time_t)tdb_fetch_int32(tdb, key); + + /* + * Invalidate the queue for 3 reasons. + * (1). last queue scan time == -1. + * (2). Current time - last queue scan time > allowed cache time. + * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default). + * This last test picks up machines for which the clock has been moved + * forward, an lpq scan done and then the clock moved back. Otherwise + * that last lpq scan would stay around for a loooong loooong time... :-). JRA. + */ + + if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() || + last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) { DEBUG(3, ("print cache expired for queue %s \ -(last_cache = %d, time now = %d, qcachetime = %d)\n", lp_servicename(snum), - (int)t2, (int)t, (int)lp_lpqcachetime() )); +(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", lp_servicename(snum), + (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() )); return True; } return False; -- cgit From 57bd576445e42a55887c41d270f2230f5136b873 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 14 Mar 2002 01:53:04 +0000 Subject: getpid() -> sys_getpid() (This used to be commit a3cea5e9ae3b53ecbc45e61a39cbce0ca1b916aa) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 81a44d7e69..758c855188 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -293,7 +293,7 @@ static void set_updating_pid(fstring printer_name, BOOL delete) fstring keystr; TDB_DATA key; TDB_DATA data; - pid_t updating_pid = getpid(); + pid_t updating_pid = sys_getpid(); slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name); key.dptr = keystr; -- cgit From 65c007b583e2107f5ad1ba6733d3e578a143863e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 15 Mar 2002 08:14:10 +0000 Subject: syncing up printing code with SAMBA_2_2 (already done some merges in the reverse). * add in new printer change notify code from SAMBA_2_2 * add in se_map_standard() from 2.2 in _spoolss_open_printer_ex() * sync up the _print_queue_struct in smb.h (why did someone change the user/file names in fs_user/fs_file (or vice-versa) ? ) * sync up some cli_spoolss_XXX functions (This used to be commit 5760315c1de4033fdc22684c940f18010010924f) --- source3/printing/printing.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 758c855188..97eaaebcc4 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -161,8 +161,8 @@ static void print_unix_job(int snum, print_queue_struct *q) pj.spooled = True; pj.smbjob = False; fstrcpy(pj.filename, ""); - fstrcpy(pj.jobname, q->file); - fstrcpy(pj.user, q->user); + fstrcpy(pj.jobname, q->fs_file); + fstrcpy(pj.user, q->fs_user); pj.snum = snum; print_job_store(jobid, &pj); @@ -217,7 +217,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void } for (i=0;iqcount;i++) { - int qid = print_parse_jobid(ts->queue[i].file); + int qid = print_parse_jobid(ts->queue[i].fs_file); if (jobid == qid) break; } @@ -410,7 +410,7 @@ static void print_queue_update_background(int snum) fill in any system job numbers as we go */ for (i=0; iqueue[i].status = pjob.status; ts->queue[i].priority = 1; ts->queue[i].time = pjob.starttime; - fstrcpy(ts->queue[i].user, pjob.user); - fstrcpy(ts->queue[i].file, pjob.jobname); + fstrcpy(ts->queue[i].fs_user, pjob.user); + fstrcpy(ts->queue[i].fs_file, pjob.jobname); ts->qcount++; -- cgit From 72eb7dbd40b4faf3438951c297fb1fbf6f9011ac Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 19 Mar 2002 02:35:12 +0000 Subject: Merge in JohnR's page count fixes. Jeremy. (This used to be commit 2e3133fbe5531b9bbc9bf46a04b27fa58e555f5a) --- source3/printing/printing.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 97eaaebcc4..7e1f59f590 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -796,12 +796,21 @@ write to a print file ****************************************************************************/ int print_job_write(int jobid, const char *buf, int size) { - int fd; + int return_code; + struct printjob *pjob = print_job_find(jobid); - fd = print_job_fd(jobid); - if (fd == -1) return -1; + if (!pjob) + return -1; + /* don't allow another process to get this info - it is meaningless */ + if (pjob->pid != local_pid) + return -1; - return write(fd, buf, size); + return_code = write(pjob->fd, buf, size); + if (return_code>0) { + pjob->size += size; + print_job_store(jobid, pjob); + } + return return_code; } /**************************************************************************** @@ -1043,6 +1052,23 @@ to open spool file %s.\n", pjob.filename)); return -1; } +/**************************************************************************** + Update the number of pages spooled to jobid +****************************************************************************/ + +void print_job_endpage(int jobid) +{ + struct printjob *pjob = print_job_find(jobid); + if (!pjob) + return; + /* don't allow another process to get this info - it is meaningless */ + if (pjob->pid != local_pid) + return; + + pjob->page_count++; + print_job_store(jobid, pjob); +} + /**************************************************************************** Print a file - called on closing the file. This spools the job. If normal close is false then we're tearing down the jobs - treat as an @@ -1137,6 +1163,7 @@ static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void * ts->queue[i].job = jobid; ts->queue[i].size = pjob.size; + ts->queue[i].page_count = pjob.page_count; ts->queue[i].status = pjob.status; ts->queue[i].priority = 1; ts->queue[i].time = pjob.starttime; -- cgit From 60a7d07d63196d140fed14a75c1c5360f3546905 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 20 Mar 2002 21:55:57 +0000 Subject: Print queue entries *must* have queue names, not numbers - numbers are not identical between different smbds (mr potter, come here and take your medicine.... :-). Jeremy. (This used to be commit 230941d2fbb746d39c00e482e7f600c68aa45efa) --- source3/printing/printing.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 7e1f59f590..febdd0eec5 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -163,7 +163,7 @@ static void print_unix_job(int snum, print_queue_struct *q) fstrcpy(pj.filename, ""); fstrcpy(pj.jobname, q->fs_file); fstrcpy(pj.user, q->fs_user); - pj.snum = snum; + fstrcpy(pj.queuename, lp_servicename(snum)); print_job_store(jobid, &pj); } @@ -185,7 +185,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void memcpy(&jobid, key.dptr, sizeof(jobid)); memcpy(&pjob, data.dptr, sizeof(pjob)); - if (ts->snum != pjob.snum) { + if (!strequal(lp_servicename(ts->snum), pjob.queuename)) { /* this isn't for the queue we are looking at */ ts->total_jobs++; return 0; @@ -556,7 +556,7 @@ int print_job_snum(int jobid) struct printjob *pjob = print_job_find(jobid); if (!pjob) return -1; - return pjob->snum; + return find_service(pjob->queuename); } /**************************************************************************** @@ -624,6 +624,10 @@ static BOOL print_job_delete1(int jobid) return True; snum = print_job_snum(jobid); + if (snum == -1) { + DEBUG(5,("print_job_delete1: unknown service number for jobid %d\n", jobid)); + return False; + } /* Hrm - we need to be able to cope with deleting a job before it has reached the spooler. */ @@ -676,7 +680,12 @@ BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode) int snum = print_job_snum(jobid); char *printer_name; BOOL owner; - + + if (snum == -1) { + DEBUG(5,("print_job_delete: unknown service number for jobid %d\n", jobid)); + return False; + } + owner = is_owner(user, jobid); /* Check access against security descriptor or whether the user @@ -720,6 +729,14 @@ BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode) if (!pjob->spooled || pjob->sysjob == -1) return False; snum = print_job_snum(jobid); + if (snum == -1) { + DEBUG(5,("print_job_pause: unknown service number for jobid %d\n", jobid)); + return False; + } + if (snum == -1) { + DEBUG(5,("print_job_resume: unknown service number for jobid %d\n", jobid)); + return False; + } if (!is_owner(user, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { @@ -984,7 +1001,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) fstrcpy(pjob.user, uidtoname(user->uid)); } - pjob.snum = snum; + fstrcpy(pjob.queuename, lp_servicename(snum)); /* lock the database */ tdb_lock_bystring(tdb, "INFO/nextjob"); @@ -1088,6 +1105,10 @@ BOOL print_job_end(int jobid, BOOL normal_close) return False; snum = print_job_snum(jobid); + if (snum == -1) { + DEBUG(5,("print_job_end: unknown service number for jobid %d\n", jobid)); + return False; + } if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) { pjob->size = sbuf.st_size; @@ -1155,7 +1176,8 @@ static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void * memcpy(&pjob, data.dptr, sizeof(pjob)); /* maybe it isn't for this queue */ - if (ts->snum != pjob.snum) return 0; + if (!strequal(lp_servicename(ts->snum), pjob.queuename)) + return 0; if (ts->qcount >= ts->maxcount) return 0; @@ -1191,7 +1213,8 @@ static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, memcpy(&pjob, data.dptr, sizeof(pjob)); /* maybe it isn't for this queue */ - if (ts->snum != pjob.snum) return 0; + if (!strequal(lp_servicename(ts->snum), pjob.queuename)) + return 0; ts->count++; -- cgit From e67f1be9f0c3193d122e3e429af4fb242121b169 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 20 Mar 2002 22:39:30 +0000 Subject: Ensure we don't do lp_servicename()'s in tdb traverse as this allocates lots of memory. Jeremy. (This used to be commit fbc8c6a1096ec829f48b403239f105065bf155b1) --- source3/printing/printing.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index febdd0eec5..ad5acb1505 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -115,10 +115,12 @@ store a job structure back to the database static BOOL print_job_store(int jobid, struct printjob *pjob) { TDB_DATA d; + BOOL ret; + d.dptr = (void *)pjob; d.dsize = sizeof(*pjob); - - return (tdb_store(tdb, print_key(jobid), d, TDB_REPLACE) == 0); + ret = (tdb_store(tdb, print_key(jobid), d, TDB_REPLACE) == 0); + return ret; } /**************************************************************************** @@ -185,7 +187,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void memcpy(&jobid, key.dptr, sizeof(jobid)); memcpy(&pjob, data.dptr, sizeof(pjob)); - if (!strequal(lp_servicename(ts->snum), pjob.queuename)) { + if (ts->snum != lp_servicenumber(pjob.queuename)) { /* this isn't for the queue we are looking at */ ts->total_jobs++; return 0; @@ -1176,7 +1178,7 @@ static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void * memcpy(&pjob, data.dptr, sizeof(pjob)); /* maybe it isn't for this queue */ - if (!strequal(lp_servicename(ts->snum), pjob.queuename)) + if (ts->snum != lp_servicenumber(pjob.queuename)) return 0; if (ts->qcount >= ts->maxcount) return 0; @@ -1213,7 +1215,7 @@ static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, memcpy(&pjob, data.dptr, sizeof(pjob)); /* maybe it isn't for this queue */ - if (!strequal(lp_servicename(ts->snum), pjob.queuename)) + if (ts->snum != lp_servicenumber(pjob.queuename)) return 0; ts->count++; -- cgit From 2699f9b9df3f974a34e40761141361e997638b6c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 22 Apr 2002 18:48:45 +0000 Subject: printing merge from HEAD (This used to be commit d3aed37dd87d425f51bcdc4e5151f0b0fe8f9c6b) --- source3/printing/printing.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index ad5acb1505..d7ac1f49c7 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -55,8 +55,8 @@ BOOL print_backend_init(void) if (tdb && local_pid == sys_getpid()) return True; tdb = tdb_open_log(lock_path("printing.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); if (!tdb) { - DEBUG(0,("print_backend_init: Failed to open printing backend database. Error = [%s]\n", - tdb_errorstr(tdb))); + DEBUG(0,("print_backend_init: Failed to open printing backend database %s\n", + lock_path("printing.tdb") )); return False; } local_pid = sys_getpid(); @@ -536,7 +536,10 @@ update the internal database from the system print queue for a queue ****************************************************************************/ static void print_queue_update(int snum) { - message_send_pid(background_lpq_updater_pid, MSG_PRINTER_UPDATE, &snum, sizeof(snum), False); + if (background_lpq_updater_pid > 0) { + message_send_pid(background_lpq_updater_pid, MSG_PRINTER_UPDATE, + &snum, sizeof(snum), False); + } } /**************************************************************************** -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/printing/printing.c | 1037 +++++++++++++++++++++++++++++-------------- 1 file changed, 708 insertions(+), 329 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index d7ac1f49c7..7bfce43af6 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1,7 +1,9 @@ /* - Unix SMB/CIFS implementation. + Unix SMB/Netbios implementation. + Version 3.0 printing backend routines Copyright (C) Andrew Tridgell 1992-2000 + Copyright (C) Jeremy Allison 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,7 +23,7 @@ #include "printing.h" /* Current printer interface */ -struct printif *current_printif = &generic_printif; +static struct printif *current_printif = &generic_printif; /* the printing backend revolves around a tdb database that stores the @@ -37,12 +39,175 @@ struct printif *current_printif = &generic_printif; jobids are assigned when a job starts spooling. */ -/* the open printing.tdb database */ -static TDB_CONTEXT *tdb; static pid_t local_pid; +/* Mapping between printer names and queue id's in job id's. */ +struct printer_queueid_map { + struct printer_queueid_map *next, *prev; + char *printername; + uint32 queueid; +}; + +static struct printer_queueid_map *printer_queueid_map_head; +static uint32 last_queueid; + +#define QUEUEID_BITS 12 +#define QUEUEID_MASK ((1<<(QUEUEID_BITS))-1) +#define QUEUEID_TO_JOBID(queueid) (((queueid) & QUEUEID_MASK) << 20 ) + +/**************************************************************************** + Create an association between a printer name and a queueid. Used to encode + the printer queueid in jobid's. + This could be converted to use an internal tdb if searching the list is + too slow. JRA. +****************************************************************************/ + +BOOL create_printer_queueid(const char *printername) +{ + struct printer_queueid_map *p; + + for (p = printer_queueid_map_head; p; p = p->next) { + if (strequal(p->printername, printername)) + return True; + } + + p = (struct printer_queueid_map *)malloc(sizeof(*p)); + if (!p) { + DEBUG(0,("create_printer_queueid: malloc fail !\n")); + return False; + } + ZERO_STRUCTP(p); + p->printername = strdup(printername); + if (!p->printername) { + DEBUG(0,("create_printer_queueid: malloc fail !\n")); + SAFE_FREE(p); + return False; + } + p->queueid = (++last_queueid); + if (p->queueid > QUEUEID_MASK) { + DEBUG(0,("create_printer_queueid: malloc fail !\n")); + SAFE_FREE(p->printername); + SAFE_FREE(p); + return False; + } + DLIST_ADD(printer_queueid_map_head, p); + return True; +} + +void set_register_printer_fn(void) +{ + extern BOOL (*register_printer_fn)(const char *); + register_printer_fn = create_printer_queueid; +} + +/**************************************************************************** + Lookups. +****************************************************************************/ + +static uint32 get_printer_queueid_byname(const char *printername) +{ + struct printer_queueid_map *p; + + for (p = printer_queueid_map_head; p; p = p->next) { + if (strequal(p->printername, printername)) + return p->queueid; + } + return 0; +} + +/**************************************************************************** + Lookups. +****************************************************************************/ + +static const char *get_printer_name_byjobid(uint32 jobid) +{ + struct printer_queueid_map *p; + uint32 queueid = (((jobid)>>20) & QUEUEID_MASK); + + for (p = printer_queueid_map_head; p; p = p->next) { + if (p->queueid == queueid) + return p->printername; + } + return NULL; +} + static int get_queue_status(int, print_status_struct *); +#define MAX_PRINT_DBS_OPEN 1 + +struct tdb_print_db { + struct tdb_print_db *next, *prev; + TDB_CONTEXT *tdb; + fstring printer_name; +}; + +static struct tdb_print_db *print_db_head; + +/**************************************************************************** + Function to find or create the printer specific job tdb given a printername. + Limits the number of tdb's open to MAX_PRINT_DBS_OPEN. +****************************************************************************/ + +static struct tdb_print_db *get_print_db_byname(const char *printername) +{ + struct tdb_print_db *p, *last_entry; + int num_open = 0; + pstring printdb_path; + + for (p = print_db_head, last_entry = print_db_head; p; p = p->next) { + if (p->tdb && strequal(p->printer_name, printername)) { + DLIST_PROMOTE(print_db_head, p); + return p; + } + num_open++; + last_entry = p; + } + /* Not found. */ + if (num_open >= MAX_PRINT_DBS_OPEN) { + /* Recycle the last entry. */ + DLIST_PROMOTE(print_db_head, last_entry); + if (print_db_head->tdb) { + if (tdb_close(print_db_head->tdb)) { + DEBUG(0,("get_print_db: Failed to close tdb for printer %s\n", + print_db_head->printer_name )); + return NULL; + } + } + p = print_db_head; + ZERO_STRUCTP(p); + } else { + /* Create one. */ + p = (struct tdb_print_db *)malloc(sizeof(struct tdb_print_db)); + if (!p) { + DEBUG(0,("get_print_db: malloc fail !\n")); + return NULL; + } + ZERO_STRUCTP(p); + DLIST_ADD(print_db_head, p); + } + + pstrcpy(printdb_path, lock_path(printername)); + pstrcat(printdb_path, ".tdb"); + p->tdb = tdb_open_log(printdb_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); + if (!p->tdb) { + DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n", + printdb_path )); + DLIST_REMOVE(print_db_head, p); + SAFE_FREE(p); + return NULL; + } + fstrcpy(p->printer_name, printername); + return p; +} + +static struct tdb_print_db *get_print_db_byjobid( uint32 jobid) +{ + const char *printername = get_printer_name_byjobid(jobid); + if (!printername) + return NULL; + return get_print_db_byname(printername); +} + /**************************************************************************** Initialise the printing backend. Called once at startup. Does not survive a fork @@ -50,24 +215,29 @@ static int get_queue_status(int, print_status_struct *); BOOL print_backend_init(void) { + struct printer_queueid_map *p; char *sversion = "INFO/version"; - if (tdb && local_pid == sys_getpid()) return True; - tdb = tdb_open_log(lock_path("printing.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); - if (!tdb) { - DEBUG(0,("print_backend_init: Failed to open printing backend database %s\n", - lock_path("printing.tdb") )); - return False; - } + if (local_pid == sys_getpid()) + return True; + + unlink(lock_path("printing.tdb")); local_pid = sys_getpid(); /* handle a Samba upgrade */ - tdb_lock_bystring(tdb, sversion); - if (tdb_fetch_int32(tdb, sversion) != PRINT_DATABASE_VERSION) { - tdb_traverse(tdb, tdb_traverse_delete_fn, NULL); - tdb_store_int32(tdb, sversion, PRINT_DATABASE_VERSION); + + for (p = printer_queueid_map_head; p; p = p->next) { + struct tdb_print_db *pdb = get_print_db_byname(p->printername); + + if (!pdb) + continue; + tdb_lock_bystring(pdb->tdb, sversion); + if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) { + tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL); + tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION); + } + tdb_unlock_bystring(pdb->tdb, sversion); } - tdb_unlock_bystring(tdb, sversion); /* select the appropriate printing interface... */ #ifdef HAVE_CUPS @@ -80,11 +250,30 @@ BOOL print_backend_init(void) } /**************************************************************************** -useful function to generate a tdb key + Shut down printing backend. Called once at shutdown to close the tdb. +****************************************************************************/ + +void printing_end(void) +{ + struct tdb_print_db *p; + + for (p = print_db_head; p; ) { + struct tdb_print_db *next_p = p->next; + if (p->tdb) + tdb_close(p->tdb); + DLIST_REMOVE(print_db_head, p); + SAFE_FREE(p); + p = next_p; + } +} + +/**************************************************************************** + Useful function to generate a tdb key. ****************************************************************************/ -static TDB_DATA print_key(int jobid) + +static TDB_DATA print_key(uint32 jobid) { - static int j; + static uint32 j; TDB_DATA ret; j = jobid; @@ -94,58 +283,248 @@ static TDB_DATA print_key(int jobid) } /**************************************************************************** -useful function to find a print job in the database + Useful function to find a print job in the database. ****************************************************************************/ -static struct printjob *print_job_find(int jobid) + +static struct printjob *print_job_find(uint32 jobid) { static struct printjob pjob; TDB_DATA ret; + struct tdb_print_db *pdb = get_print_db_byjobid(jobid); + + if (!pdb) + return NULL; - ret = tdb_fetch(tdb, print_key(jobid)); - if (!ret.dptr || ret.dsize != sizeof(pjob)) return NULL; + ret = tdb_fetch(pdb->tdb, print_key(jobid)); + if (!ret.dptr || ret.dsize != sizeof(pjob)) + return NULL; memcpy(&pjob, ret.dptr, sizeof(pjob)); - free(ret.dptr); + SAFE_FREE(ret.dptr); return &pjob; } +/* Convert a unix jobid to a smb jobid */ + +static uint32 sysjob_to_jobid_value; + +static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, + TDB_DATA data, void *state) +{ + struct printjob *pjob = (struct printjob *)data.dptr; + int *sysjob = (int *)state; + + if (key.dsize != sizeof(uint32)) + return 0; + + if (*sysjob == pjob->sysjob) { + uint32 *jobid = (uint32 *)key.dptr; + + sysjob_to_jobid_value = *jobid; + return 1; + } + + return 0; +} + /**************************************************************************** -store a job structure back to the database + This is a *horribly expensive call as we have to iterate through all the + current printer tdb's. Don't do this often ! JRA. ****************************************************************************/ -static BOOL print_job_store(int jobid, struct printjob *pjob) + +uint32 sysjob_to_jobid(int unix_jobid) +{ + struct printer_queueid_map *p; + sysjob_to_jobid_value = (uint32)-1; + + for (p = printer_queueid_map_head; p; p = p->next) { + struct tdb_print_db *pdb = get_print_db_byname(p->printername); + if (pdb) + tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid); + if (sysjob_to_jobid_value != (uint32)-1) + return sysjob_to_jobid_value; + } + return (uint32)-1; +} + +/**************************************************************************** + Send notifications based on what has changed after a pjob_store. +****************************************************************************/ + +static struct { + uint32 lpq_status; + uint32 spoolss_status; +} lpq_to_spoolss_status_map[] = { + { LPQ_QUEUED, JOB_STATUS_QUEUED }, + { LPQ_PAUSED, JOB_STATUS_PAUSED }, + { LPQ_SPOOLING, JOB_STATUS_SPOOLING }, + { LPQ_PRINTING, JOB_STATUS_PRINTING }, + { LPQ_DELETING, JOB_STATUS_DELETING }, + { LPQ_OFFLINE, JOB_STATUS_OFFLINE }, + { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT }, + { LPQ_PRINTED, JOB_STATUS_PRINTED }, + { LPQ_DELETED, JOB_STATUS_DELETED }, + { LPQ_BLOCKED, JOB_STATUS_BLOCKED }, + { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION }, + { -1, 0 } +}; + +/* Convert a lpq status value stored in printing.tdb into the + appropriate win32 API constant. */ + +static uint32 map_to_spoolss_status(uint32 lpq_status) { - TDB_DATA d; + int i = 0; + + while (lpq_to_spoolss_status_map[i].lpq_status != -1) { + if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status) + return lpq_to_spoolss_status_map[i].spoolss_status; + i++; + } + + return 0; +} + +static void pjob_store_notify(uint32 jobid, struct printjob *old_data, + struct printjob *new_data) +{ + BOOL new_job = False; + int snum = print_job_snum(jobid); + + if (snum == -1) + return; + + if (!old_data) + new_job = True; + + /* Notify the job name first */ + + if (new_job || !strequal(old_data->jobname, new_data->jobname)) + notify_job_name(snum, jobid, new_data->jobname); + + /* Job attributes that can't be changed. We only send + notification for these on a new job. */ + + if (new_job) { + notify_job_submitted(snum, jobid, new_data->starttime); + notify_job_username(snum, jobid, new_data->user); + } + + /* Job attributes of a new job or attributes that can be + modified. */ + + if (new_job || old_data->status != new_data->status) + notify_job_status(snum, jobid, map_to_spoolss_status(new_data->status)); + + if (new_job || old_data->size != new_data->size) + notify_job_total_bytes(snum, jobid, new_data->size); + + if (new_job || old_data->page_count != new_data->page_count) + notify_job_total_pages(snum, jobid, new_data->page_count); +} + +/**************************************************************************** + Store a job structure back to the database. +****************************************************************************/ + +static BOOL pjob_store(uint32 jobid, struct printjob *pjob) +{ + TDB_DATA old_data, new_data; BOOL ret; + struct tdb_print_db *pdb = get_print_db_byjobid(jobid); + + if (!pdb) + return False; + + /* Get old data */ + + old_data = tdb_fetch(pdb->tdb, print_key(jobid)); + + /* Store new data */ + + new_data.dptr = (void *)pjob; + new_data.dsize = sizeof(*pjob); + ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0); + + /* Send notify updates for what has changed */ + + if (ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob))) { + pjob_store_notify( + jobid, (struct printjob *)old_data.dptr, + (struct printjob *)new_data.dptr); + free(old_data.dptr); + } - d.dptr = (void *)pjob; - d.dsize = sizeof(*pjob); - ret = (tdb_store(tdb, print_key(jobid), d, TDB_REPLACE) == 0); return ret; } /**************************************************************************** -parse a file name from the system spooler to generate a jobid + Remove a job structure from the database. +****************************************************************************/ + +static void pjob_delete(uint32 jobid) +{ + int snum; + struct printjob *pjob = print_job_find(jobid); + uint32 job_status = 0; + struct tdb_print_db *pdb = get_print_db_byjobid(jobid); + + if (!pdb) + return; + + if (!pjob) { + DEBUG(5, ("pjob_delete(): we were asked to delete nonexistent job %u\n", + (unsigned int)jobid)); + return; + } + + /* Send a notification that a job has been deleted */ + + job_status = map_to_spoolss_status(pjob->status); + + /* We must cycle through JOB_STATUS_DELETING and + JOB_STATUS_DELETED for the port monitor to delete the job + properly. */ + + snum = print_job_snum(jobid); + job_status |= JOB_STATUS_DELETING; + notify_job_status(snum, jobid, job_status); + + job_status |= JOB_STATUS_DELETED; + notify_job_status(snum, jobid, job_status); + + /* Remove from printing.tdb */ + + tdb_delete(pdb->tdb, print_key(jobid)); +} + +/**************************************************************************** + Parse a file name from the system spooler to generate a jobid. ****************************************************************************/ -static int print_parse_jobid(char *fname) + +static uint32 print_parse_jobid(char *fname) { int jobid; - if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0) return -1; + if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0) + return (uint32)-1; fname += strlen(PRINT_SPOOL_PREFIX); jobid = atoi(fname); - if (jobid <= 0) return -1; + if (jobid <= 0) + return (uint32)-1; - return jobid; + return (uint32)jobid; } - /**************************************************************************** -list a unix job in the print database + List a unix job in the print database. ****************************************************************************/ + static void print_unix_job(int snum, print_queue_struct *q) { - int jobid = q->job + UNIX_JOB_START; + uint32 queueid = get_printer_queueid_byname(PRINTERNAME(snum)); + uint32 jobid = (q->job + UNIX_JOB_START) | QUEUEID_TO_JOBID(queueid); struct printjob pj, *old_pj; /* Preserve the timestamp on an existing unix print job */ @@ -165,9 +544,9 @@ static void print_unix_job(int snum, print_queue_struct *q) fstrcpy(pj.filename, ""); fstrcpy(pj.jobname, q->fs_file); fstrcpy(pj.user, q->fs_user); - fstrcpy(pj.queuename, lp_servicename(snum)); + fstrcpy(pj.queuename, lp_const_servicename(snum)); - print_job_store(jobid, &pj); + pjob_store(jobid, &pj); } @@ -176,31 +555,40 @@ struct traverse_struct { int qcount, snum, maxcount, total_jobs; }; -/* utility fn to delete any jobs that are no longer active */ +/**************************************************************************** + Utility fn to delete any jobs that are no longer active. +****************************************************************************/ + static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) { + uint32 queueid; struct traverse_struct *ts = (struct traverse_struct *)state; struct printjob pjob; - int i, jobid; + uint32 jobid; + int i; - if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0; + if (data.dsize != sizeof(pjob) || key.dsize != sizeof(jobid)) + return 0; memcpy(&jobid, key.dptr, sizeof(jobid)); memcpy(&pjob, data.dptr, sizeof(pjob)); if (ts->snum != lp_servicenumber(pjob.queuename)) { - /* this isn't for the queue we are looking at */ - ts->total_jobs++; + /* this isn't for the queue we are looking at - this cannot happen with the split tdb's. JRA */ return 0; } + queueid = get_printer_queueid_byname(pjob.queuename); + if (!pjob.smbjob) { /* remove a unix job if it isn't in the system queue any more */ for (i=0;iqcount;i++) { - if (jobid == ts->queue[i].job + UNIX_JOB_START) break; + uint32 u_jobid = ((ts->queue[i].job + UNIX_JOB_START) | QUEUEID_TO_JOBID(queueid)); + if (jobid == u_jobid) + break; } if (i == ts->qcount) - tdb_delete(tdb, key); + pjob_delete(jobid); else ts->total_jobs++; return 0; @@ -212,15 +600,16 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void exist then kill it. This cleans up after smbd deaths */ if (!process_exists(pjob.pid)) - tdb_delete(tdb, key); + pjob_delete(jobid); else ts->total_jobs++; return 0; } for (i=0;iqcount;i++) { - int qid = print_parse_jobid(ts->queue[i].fs_file); - if (jobid == qid) break; + uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file) | QUEUEID_TO_JOBID(queueid); + if (jobid == curr_jobid) + break; } /* The job isn't in the system queue - we have to assume it has @@ -238,7 +627,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void submitted less than lp_lpqcachetime() seconds ago. */ if ((cur_t - pjob.starttime) > lp_lpqcachetime()) - tdb_delete(t, key); + pjob_delete(jobid); else ts->total_jobs++; } @@ -249,13 +638,19 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void } /**************************************************************************** -check if the print queue has been updated recently enough + Check if the print queue has been updated recently enough. ****************************************************************************/ + static void print_cache_flush(int snum) { fstring key; - slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum)); - tdb_store_int32(tdb, key, -1); + const char *printername = lp_const_servicename(snum); + struct tdb_print_db *pdb = get_print_db_byname(printername); + + if (!pdb) + return; + slprintf(key, sizeof(key)-1, "CACHE/%s", printername); + tdb_store_int32(pdb->tdb, key, -1); } /**************************************************************************** @@ -267,17 +662,20 @@ static pid_t get_updating_pid(fstring printer_name) fstring keystr; TDB_DATA data, key; pid_t updating_pid; + struct tdb_print_db *pdb = get_print_db_byname(printer_name); + if (!pdb) + return (pid_t)-1; slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name); key.dptr = keystr; key.dsize = strlen(keystr); - data = tdb_fetch(tdb, key); + data = tdb_fetch(pdb->tdb, key); if (!data.dptr || data.dsize != sizeof(pid_t)) return (pid_t)-1; memcpy(&updating_pid, data.dptr, sizeof(pid_t)); - free(data.dptr); + SAFE_FREE(data.dptr); if (process_exists(updating_pid)) return updating_pid; @@ -287,7 +685,7 @@ static pid_t get_updating_pid(fstring printer_name) /**************************************************************************** Set the fact that we're doing the update, or have finished doing the update - in th tdb. + in the tdb. ****************************************************************************/ static void set_updating_pid(fstring printer_name, BOOL delete) @@ -296,41 +694,31 @@ static void set_updating_pid(fstring printer_name, BOOL delete) TDB_DATA key; TDB_DATA data; pid_t updating_pid = sys_getpid(); + struct tdb_print_db *pdb = get_print_db_byname(printer_name); + + if (!pdb) + return; slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name); key.dptr = keystr; key.dsize = strlen(keystr); if (delete) { - tdb_delete(tdb, key); + tdb_delete(pdb->tdb, key); return; } data.dptr = (void *)&updating_pid; data.dsize = sizeof(pid_t); - tdb_store(tdb, key, data, TDB_REPLACE); -} - -/**************************************************************************** - Send a message saying the queue changed. -****************************************************************************/ - -static void send_queue_message(const char *printer_name, uint32 high, uint32 low) -{ - char msg[8 + sizeof(fstring)]; - SIVAL(msg,0,low); - SIVAL(msg,4,high); - fstrcpy(&msg[8], printer_name); - - message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, msg, 8 + strlen(printer_name) + 1, False, NULL); + tdb_store(pdb->tdb, key, data, TDB_REPLACE); } /**************************************************************************** -update the internal database from the system print queue for a queue in the background + Update the internal database from the system print queue for a queue. ****************************************************************************/ -static void print_queue_update_background(int snum) +static void print_queue_update(int snum) { int i, qcount; print_queue_struct *queue = NULL; @@ -340,9 +728,13 @@ static void print_queue_update_background(int snum) struct traverse_struct tstruct; fstring keystr, printer_name, cachestr; TDB_DATA data, key; + struct tdb_print_db *pdb; + + fstrcpy(printer_name, lp_const_servicename(snum)); + pdb = get_print_db_byname(printer_name); + if (!pdb) + return; - fstrcpy(printer_name, lp_servicename(snum)); - /* * Check to see if someone else is doing this update. * This is essentially a mutex on the update. @@ -354,7 +746,7 @@ static void print_queue_update_background(int snum) /* Lock the queue for the database update */ slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name); - tdb_lock_bystring(tdb, keystr); + tdb_lock_bystring(pdb->tdb, keystr); /* * Ensure that no one else got in here. @@ -366,7 +758,7 @@ static void print_queue_update_background(int snum) /* * Someone else is doing the update, exit. */ - tdb_unlock_bystring(tdb, keystr); + tdb_unlock_bystring(pdb->tdb, keystr); return; } @@ -382,7 +774,7 @@ static void print_queue_update_background(int snum) * the update. */ - tdb_unlock_bystring(tdb, keystr); + tdb_unlock_bystring(pdb->tdb, keystr); /* * Update the cache time FIRST ! Stops others even @@ -391,7 +783,7 @@ static void print_queue_update_background(int snum) */ slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name); - tdb_store_int32(tdb, cachestr, (int)time(NULL)); + tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL)); /* get the current queue using the appropriate interface */ ZERO_STRUCT(status); @@ -412,9 +804,9 @@ static void print_queue_update_background(int snum) fill in any system job numbers as we go */ for (i=0; isysjob = queue[i].job; pjob->status = queue[i].status; - print_job_store(jobid, pjob); + pjob_store(jobid, pjob); } /* now delete any queued entries that don't appear in the @@ -443,23 +835,15 @@ static void print_queue_update_background(int snum) tstruct.snum = snum; tstruct.total_jobs = 0; - tdb_traverse(tdb, traverse_fn_delete, (void *)&tstruct); - - safe_free(tstruct.queue); + tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct); - tdb_store_int32(tdb, "INFO/total_jobs", tstruct.total_jobs); + SAFE_FREE(tstruct.queue); - /* - * Get the old print status. We will use this to compare the - * number of jobs. If they have changed we need to send a - * "changed" message to the smbds. - */ + tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs); - if( qcount != get_queue_status(snum, &old_status)) { + if( qcount != get_queue_status(snum, &old_status)) DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n", - old_status.qcount, qcount, printer_name )); - send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB); - } + old_status.qcount, qcount, printer_name )); /* store the new queue status structure */ slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name); @@ -469,7 +853,7 @@ static void print_queue_update_background(int snum) status.qcount = qcount; data.dptr = (void *)&status; data.dsize = sizeof(status); - tdb_store(tdb, key, data, TDB_REPLACE); + tdb_store(pdb->tdb, key, data, TDB_REPLACE); /* * Update the cache time again. We want to do this call @@ -477,149 +861,103 @@ static void print_queue_update_background(int snum) */ slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name); - tdb_store_int32(tdb, keystr, (int)time(NULL)); + tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL)); /* Delete our pid from the db. */ set_updating_pid(printer_name, True); } /**************************************************************************** -this is the receive function of the background lpq updater + Check if a jobid is valid. It is valid if it exists in the database. ****************************************************************************/ -static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len) -{ - int snum; - snum=*((int *)buf); - print_queue_update_background(snum); -} - -static pid_t background_lpq_updater_pid; -/**************************************************************************** -main thread of the background lpq updater -****************************************************************************/ -void start_background_queue(void) +BOOL print_job_exists(uint32 jobid) { - DEBUG(3,("start_background_queue: Starting background LPQ thread\n")); - background_lpq_updater_pid = sys_fork(); - - if (background_lpq_updater_pid == -1) { - DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) )); - exit(1); - } - - if(background_lpq_updater_pid == 0) { - /* Child. */ - DEBUG(5,("start_background_queue: background LPQ thread started\n")); - - claim_connection(NULL,"smbd lpq backend",0,False); - - if (!locking_init(0)) - exit(1); - - if (!print_backend_init()) - exit(1); - - message_register(MSG_PRINTER_UPDATE, print_queue_receive); - - DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n")); - while (1) { - pause(); - DEBUG(10,("start_background_queue: background LPQ thread got a message\n")); - message_dispatch(); - } - } -} - -/**************************************************************************** -update the internal database from the system print queue for a queue -****************************************************************************/ -static void print_queue_update(int snum) -{ - if (background_lpq_updater_pid > 0) { - message_send_pid(background_lpq_updater_pid, MSG_PRINTER_UPDATE, - &snum, sizeof(snum), False); - } + struct tdb_print_db *pdb = get_print_db_byjobid(jobid); + if (!pdb) + return False; + return tdb_exists(pdb->tdb, print_key(jobid)); } /**************************************************************************** -check if a jobid is valid. It is valid if it exists in the database + Work out which service a jobid is for. + Note that we have to look up by queue name to ensure that it works for + other than the process that started the job. ****************************************************************************/ -BOOL print_job_exists(int jobid) -{ - return tdb_exists(tdb, print_key(jobid)); -} - -/**************************************************************************** -work out which service a jobid is for -note that we have to look up by queue name to ensure that it works for -other than the process that started the job -****************************************************************************/ -int print_job_snum(int jobid) +int print_job_snum(uint32 jobid) { struct printjob *pjob = print_job_find(jobid); - if (!pjob) return -1; + if (!pjob) + return -1; return find_service(pjob->queuename); } /**************************************************************************** -give the fd used for a jobid + Give the fd used for a jobid. ****************************************************************************/ -int print_job_fd(int jobid) + +int print_job_fd(uint32 jobid) { struct printjob *pjob = print_job_find(jobid); - if (!pjob) return -1; + if (!pjob) + return -1; /* don't allow another process to get this info - it is meaningless */ - if (pjob->pid != local_pid) return -1; + if (pjob->pid != local_pid) + return -1; return pjob->fd; } /**************************************************************************** -give the filename used for a jobid -only valid for the process doing the spooling and when the job -has not been spooled + Give the filename used for a jobid. + Only valid for the process doing the spooling and when the job + has not been spooled. ****************************************************************************/ -char *print_job_fname(int jobid) + +char *print_job_fname(uint32 jobid) { struct printjob *pjob = print_job_find(jobid); - if (!pjob || pjob->spooled || pjob->pid != local_pid) return NULL; + if (!pjob || pjob->spooled || pjob->pid != local_pid) + return NULL; return pjob->filename; } - /**************************************************************************** -set the place in the queue for a job + Set the place in the queue for a job. ****************************************************************************/ -BOOL print_job_set_place(int jobid, int place) + +BOOL print_job_set_place(uint32 jobid, int place) { DEBUG(2,("print_job_set_place not implemented yet\n")); return False; } /**************************************************************************** -set the name of a job. Only possible for owner + Set the name of a job. Only possible for owner. ****************************************************************************/ -BOOL print_job_set_name(int jobid, char *name) + +BOOL print_job_set_name(uint32 jobid, char *name) { struct printjob *pjob = print_job_find(jobid); - if (!pjob || pjob->pid != local_pid) return False; + if (!pjob || pjob->pid != local_pid) + return False; fstrcpy(pjob->jobname, name); - return print_job_store(jobid, pjob); + return pjob_store(jobid, pjob); } - /**************************************************************************** -delete a print job - don't update queue + Delete a print job - don't update queue. ****************************************************************************/ -static BOOL print_job_delete1(int jobid) + +static BOOL print_job_delete1(uint32 jobid) { struct printjob *pjob = print_job_find(jobid); int snum, result = 0; - if (!pjob) return False; + if (!pjob) + return False; /* * If already deleting just return. @@ -630,7 +968,7 @@ static BOOL print_job_delete1(int jobid) snum = print_job_snum(jobid); if (snum == -1) { - DEBUG(5,("print_job_delete1: unknown service number for jobid %d\n", jobid)); + DEBUG(5,("print_job_delete1: unknown service number for jobid %u\n", (unsigned int)jobid)); return False; } @@ -638,14 +976,13 @@ static BOOL print_job_delete1(int jobid) has reached the spooler. */ if (pjob->sysjob == -1) { - DEBUG(5, ("attempt to delete job %d not seen by lpr\n", - jobid)); + DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid)); } /* Set the tdb entry to be deleting. */ pjob->status = LPQ_DELETING; - print_job_store(jobid, pjob); + pjob_store(jobid, pjob); if (pjob->spooled && pjob->sysjob != -1) result = (*(current_printif->job_delete))(snum, pjob); @@ -653,22 +990,23 @@ static BOOL print_job_delete1(int jobid) /* Delete the tdb entry if the delete suceeded or the job hasn't been spooled. */ - if (result == 0) { - tdb_delete(tdb, print_key(jobid)); - } + if (result == 0) + pjob_delete(jobid); return (result == 0); } /**************************************************************************** -return true if the current user owns the print job + Return true if the current user owns the print job. ****************************************************************************/ -static BOOL is_owner(struct current_user *user, int jobid) + +static BOOL is_owner(struct current_user *user, uint32 jobid) { struct printjob *pjob = print_job_find(jobid); user_struct *vuser; - if (!pjob || !user) return False; + if (!pjob || !user) + return False; if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { return strequal(pjob->user, vuser->user.smb_name); @@ -678,12 +1016,12 @@ static BOOL is_owner(struct current_user *user, int jobid) } /**************************************************************************** -delete a print job + Delete a print job. ****************************************************************************/ -BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode) + +BOOL print_job_delete(struct current_user *user, uint32 jobid, WERROR *errcode) { int snum = print_job_snum(jobid); - char *printer_name; BOOL owner; if (snum == -1) { @@ -703,43 +1041,35 @@ BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode) return False; } - if (!print_job_delete1(jobid)) return False; + if (!print_job_delete1(jobid)) + return False; /* force update the database and say the delete failed if the job still exists */ print_queue_update(snum); - /* Send a printer notify message */ - - printer_name = PRINTERNAME(snum); - - send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB); - return !print_job_exists(jobid); } - /**************************************************************************** -pause a job + Pause a job. ****************************************************************************/ -BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode) + +BOOL print_job_pause(struct current_user *user, uint32 jobid, WERROR *errcode) { struct printjob *pjob = print_job_find(jobid); int snum, ret = -1; - char *printer_name; - if (!pjob || !user) return False; + if (!pjob || !user) + return False; - if (!pjob->spooled || pjob->sysjob == -1) return False; + if (!pjob->spooled || pjob->sysjob == -1) + return False; snum = print_job_snum(jobid); if (snum == -1) { - DEBUG(5,("print_job_pause: unknown service number for jobid %d\n", jobid)); - return False; - } - if (snum == -1) { - DEBUG(5,("print_job_resume: unknown service number for jobid %d\n", jobid)); + DEBUG(5,("print_job_pause: unknown service number for jobid %u\n", (unsigned int)jobid)); return False; } @@ -763,9 +1093,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode) /* Send a printer notify message */ - printer_name = PRINTERNAME(snum); - - send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB); + notify_job_status(snum, jobid, JOB_STATUS_PAUSED); /* how do we tell if this succeeded? */ @@ -773,19 +1101,25 @@ BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode) } /**************************************************************************** -resume a job + Resume a job. ****************************************************************************/ -BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode) + +BOOL print_job_resume(struct current_user *user, uint32 jobid, WERROR *errcode) { struct printjob *pjob = print_job_find(jobid); - char *printer_name; int snum, ret; - if (!pjob || !user) return False; + if (!pjob || !user) + return False; - if (!pjob->spooled || pjob->sysjob == -1) return False; + if (!pjob->spooled || pjob->sysjob == -1) + return False; snum = print_job_snum(jobid); + if (snum == -1) { + DEBUG(5,("print_job_resume: unknown service number for jobid %u\n", (unsigned int)jobid)); + return False; + } if (!is_owner(user, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { @@ -806,17 +1140,16 @@ BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode) /* Send a printer notify message */ - printer_name = PRINTERNAME(snum); - - send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB); + notify_job_status(snum, jobid, JOB_STATUS_QUEUED); return True; } /**************************************************************************** -write to a print file + Write to a print file. ****************************************************************************/ -int print_job_write(int jobid, const char *buf, int size) + +int print_job_write(uint32 jobid, const char *buf, int size) { int return_code; struct printjob *pjob = print_job_find(jobid); @@ -830,7 +1163,7 @@ int print_job_write(int jobid, const char *buf, int size) return_code = write(pjob->fd, buf, size); if (return_code>0) { pjob->size += size; - print_job_store(jobid, pjob); + pjob_store(jobid, pjob); } return return_code; } @@ -843,9 +1176,14 @@ static BOOL print_cache_expired(int snum) { fstring key; time_t last_qscan_time, time_now = time(NULL); + const char *printername = lp_const_servicename(snum); + struct tdb_print_db *pdb = get_print_db_byname(printername); + + if (!pdb) + return False; - slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum)); - last_qscan_time = (time_t)tdb_fetch_int32(tdb, key); + slprintf(key, sizeof(key), "CACHE/%s", printername); + last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key); /* * Invalidate the queue for 3 reasons. @@ -860,7 +1198,7 @@ static BOOL print_cache_expired(int snum) if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) { DEBUG(3, ("print cache expired for queue %s \ -(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", lp_servicename(snum), +(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername, (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() )); return True; } @@ -870,21 +1208,26 @@ static BOOL print_cache_expired(int snum) /**************************************************************************** Get the queue status - do not update if db is out of date. ****************************************************************************/ + static int get_queue_status(int snum, print_status_struct *status) { fstring keystr; TDB_DATA data, key; + const char *printername = lp_const_servicename(snum); + struct tdb_print_db *pdb = get_print_db_byname(printername); + if (!pdb) + return 0; ZERO_STRUCTP(status); - slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", lp_servicename(snum)); + slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername); key.dptr = keystr; key.dsize = strlen(keystr); - data = tdb_fetch(tdb, key); + data = tdb_fetch(pdb->tdb, key); if (data.dptr) { if (data.dsize == sizeof(print_status_struct)) { memcpy(status, data.dptr, sizeof(print_status_struct)); } - free(data.dptr); + SAFE_FREE(data.dptr); } return status->qcount; } @@ -911,44 +1254,61 @@ int print_queue_length(int snum, print_status_struct *pstatus) } /**************************************************************************** - Determine the number of jobs in all queues. + Determine the number of jobs in all queues. This is very expensive. Don't + call ! JRA. ****************************************************************************/ -static int get_total_jobs(int snum) + +static int get_total_jobs(void) { int total_jobs; + struct printer_queueid_map *p; - /* make sure the database is up to date */ - if (print_cache_expired(snum)) print_queue_update(snum); + for (p = printer_queueid_map_head; p; p = p->next) { + int jobs; + struct tdb_print_db *pdb = get_print_db_byname(p->printername); + if (!pdb) + continue; - total_jobs = tdb_fetch_int32(tdb, "INFO/total_jobs"); - if (total_jobs >0) - return total_jobs; - else - return 0; + /* make sure the database is up to date */ + if (print_cache_expired(lp_servicenumber(p->printername))) + print_queue_update(lp_servicenumber(p->printername)); + + jobs = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs"); + if (jobs > 0) + total_jobs += jobs; + } + return total_jobs; } /*************************************************************************** -start spooling a job - return the jobid + Start spooling a job - return the jobid. ***************************************************************************/ -int print_job_start(struct current_user *user, int snum, char *jobname) + +uint32 print_job_start(struct current_user *user, int snum, char *jobname) { - int jobid; + uint32 jobid; char *path; struct printjob pjob; int next_jobid; user_struct *vuser; int njobs = 0; + const char *printername = lp_const_servicename(snum); + struct tdb_print_db *pdb = get_print_db_byname(printername); + uint32 queueid = queueid = get_printer_queueid_byname(printername); errno = 0; + if (!pdb) + return (uint32)-1; + if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) { DEBUG(3, ("print_job_start: job start denied by security descriptor\n")); - return -1; + return (uint32)-1; } if (!print_time_access_check(snum)) { DEBUG(3, ("print_job_start: job start denied by time check\n")); - return -1; + return (uint32)-1; } path = lp_pathname(snum); @@ -960,15 +1320,15 @@ int print_job_start(struct current_user *user, int snum, char *jobname) dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) { DEBUG(3, ("print_job_start: disk space check failed.\n")); errno = ENOSPC; - return -1; + return (uint32)-1; } } /* for autoloaded printers, check that the printcap entry still exists */ - if (lp_autoloaded(snum) && !pcap_printername_ok(lp_servicename(snum), NULL)) { - DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_servicename(snum) )); + if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) { + DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) )); errno = ENOENT; - return -1; + return (uint32)-1; } /* Insure the maximum queue size is not violated */ @@ -976,15 +1336,15 @@ int print_job_start(struct current_user *user, int snum, char *jobname) DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per queue (%d).\n", njobs, lp_maxprintjobs(snum) )); errno = ENOSPC; - return -1; + return (uint32)-1; } /* Insure the maximum print jobs in the system is not violated */ - if (lp_totalprintjobs() && get_total_jobs(snum) > lp_totalprintjobs()) { + if (lp_totalprintjobs() && get_total_jobs() > lp_totalprintjobs()) { DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per system (%d).\n", njobs, lp_totalprintjobs() )); errno = ENOSPC; - return -1; + return (uint32)-1; } /* create the database entry */ @@ -1006,31 +1366,38 @@ int print_job_start(struct current_user *user, int snum, char *jobname) fstrcpy(pjob.user, uidtoname(user->uid)); } - fstrcpy(pjob.queuename, lp_servicename(snum)); + fstrcpy(pjob.queuename, lp_const_servicename(snum)); /* lock the database */ - tdb_lock_bystring(tdb, "INFO/nextjob"); + tdb_lock_bystring(pdb->tdb, "INFO/nextjob"); - next_jobid = tdb_fetch_int32(tdb, "INFO/nextjob"); + next_jobid = tdb_fetch_int32(pdb->tdb, "INFO/nextjob"); if (next_jobid == -1) next_jobid = 1; for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) { - if (!print_job_exists(jobid)) + if (!print_job_exists(jobid | QUEUEID_TO_JOBID(queueid))) break; } - if (jobid == next_jobid || !print_job_store(jobid, &pjob)) { - DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or print_job_store failed.\n", + if (jobid == next_jobid || !pjob_store(jobid | QUEUEID_TO_JOBID(queueid), &pjob)) { + DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or pjob_store failed.\n", jobid, next_jobid )); jobid = -1; goto fail; } - tdb_store_int32(tdb, "INFO/nextjob", jobid); + if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) { + DEBUG(3, ("print_job_start: failed to store INFO/nextjob.\n")); + jobid = -1; + goto fail; + } + + /* Ensure the queuid is added to the jobid. */ + jobid |= QUEUEID_TO_JOBID(queueid); /* we have a job entry - now create the spool file */ - slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.6d.XXXXXX", - path, PRINT_SPOOL_PREFIX, jobid); + slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", + path, PRINT_SPOOL_PREFIX, (unsigned int)jobid); pjob.fd = smb_mkstemp(pjob.filename); if (pjob.fd == -1) { @@ -1046,9 +1413,9 @@ to open spool file %s.\n", pjob.filename)); goto fail; } - print_job_store(jobid, &pjob); + pjob_store(jobid, &pjob); - tdb_unlock_bystring(tdb, "INFO/nextjob"); + tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); /* * If the printer is marked as postscript output a leading @@ -1064,11 +1431,10 @@ to open spool file %s.\n", pjob.filename)); return jobid; fail: - if (jobid != -1) { - tdb_delete(tdb, print_key(jobid)); - } + if (jobid != -1) + pjob_delete(jobid); - tdb_unlock_bystring(tdb, "INFO/nextjob"); + tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) )); return -1; @@ -1078,7 +1444,7 @@ to open spool file %s.\n", pjob.filename)); Update the number of pages spooled to jobid ****************************************************************************/ -void print_job_endpage(int jobid) +void print_job_endpage(uint32 jobid) { struct printjob *pjob = print_job_find(jobid); if (!pjob) @@ -1088,7 +1454,7 @@ void print_job_endpage(int jobid) return; pjob->page_count++; - print_job_store(jobid, pjob); + pjob_store(jobid, pjob); } /**************************************************************************** @@ -1097,7 +1463,7 @@ void print_job_endpage(int jobid) error. ****************************************************************************/ -BOOL print_job_end(int jobid, BOOL normal_close) +BOOL print_job_end(uint32 jobid, BOOL normal_close) { struct printjob *pjob = print_job_find(jobid); int snum, ret; @@ -1111,7 +1477,7 @@ BOOL print_job_end(int jobid, BOOL normal_close) snum = print_job_snum(jobid); if (snum == -1) { - DEBUG(5,("print_job_end: unknown service number for jobid %d\n", jobid)); + DEBUG(5,("print_job_end: unknown service number for jobid %u\n", (unsigned int)jobid)); return False; } @@ -1131,7 +1497,7 @@ BOOL print_job_end(int jobid, BOOL normal_close) goto fail; } - /* Technically, this is not quit right. If the printer has a separator + /* Technically, this is not quite right. If the printer has a separator * page turned on, the NT spooler prints the separator page even if the * print job is 0 bytes. 010215 JRR */ if (pjob->size == 0 || pjob->status == LPQ_DELETING) { @@ -1139,7 +1505,7 @@ BOOL print_job_end(int jobid, BOOL normal_close) DEBUG(5,("print_job_end: canceling spool of %s (%s)\n", pjob->filename, pjob->size ? "deleted" : "zero length" )); unlink(pjob->filename); - tdb_delete(tdb, print_key(jobid)); + pjob_delete(jobid); return True; } @@ -1152,7 +1518,7 @@ BOOL print_job_end(int jobid, BOOL normal_close) pjob->spooled = True; pjob->status = LPQ_QUEUED; - print_job_store(jobid, pjob); + pjob_store(jobid, pjob); /* make sure the database is up to date */ if (print_cache_expired(snum)) @@ -1165,18 +1531,23 @@ fail: /* The print job was not succesfully started. Cleanup */ /* Still need to add proper error return propagation! 010122:JRR */ unlink(pjob->filename); - tdb_delete(tdb, print_key(jobid)); + pjob_delete(jobid); return False; } -/* utility fn to enumerate the print queue */ +/**************************************************************************** + Utility fn to enumerate the print queue. +****************************************************************************/ + static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) { struct traverse_struct *ts = (struct traverse_struct *)state; struct printjob pjob; - int i, jobid; + int i; + uint32 jobid; - if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0; + if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) + return 0; memcpy(&jobid, key.dptr, sizeof(jobid)); memcpy(&pjob, data.dptr, sizeof(pjob)); @@ -1184,7 +1555,8 @@ static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void * if (ts->snum != lp_servicenumber(pjob.queuename)) return 0; - if (ts->qcount >= ts->maxcount) return 0; + if (ts->qcount >= ts->maxcount) + return 0; i = ts->qcount; @@ -1206,18 +1578,22 @@ struct traverse_count_struct { int snum, count; }; -/* utility fn to count the number of entries in the print queue */ +/**************************************************************************** + Utility fn to count the number of entries in the print queue. +****************************************************************************/ + static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) { struct traverse_count_struct *ts = (struct traverse_count_struct *)state; struct printjob pjob; - int jobid; + uint32 jobid; - if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0; + if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) + return 0; memcpy(&jobid, key.dptr, sizeof(jobid)); memcpy(&pjob, data.dptr, sizeof(pjob)); - /* maybe it isn't for this queue */ + /* maybe it isn't for this queue - this cannot happen with the tdb/printer code. JRA */ if (ts->snum != lp_servicenumber(pjob.queuename)) return 0; @@ -1226,25 +1602,32 @@ static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, return 0; } -/* Sort print jobs by submittal time */ +/**************************************************************************** + Sort print jobs by submittal time. +****************************************************************************/ static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2) { /* Silly cases */ - if (!j1 && !j2) return 0; - if (!j1) return -1; - if (!j2) return 1; + if (!j1 && !j2) + return 0; + if (!j1) + return -1; + if (!j2) + return 1; /* Sort on job start time */ - if (j1->time == j2->time) return 0; + if (j1->time == j2->time) + return 0; return (j1->time > j2->time) ? 1 : -1; } /**************************************************************************** -get a printer queue listing + Get a printer queue listing. ****************************************************************************/ + int print_queue_status(int snum, print_queue_struct **queue, print_status_struct *status) @@ -1253,26 +1636,32 @@ int print_queue_status(int snum, struct traverse_count_struct tsc; fstring keystr; TDB_DATA data, key; - - /* make sure the database is up to date */ - if (print_cache_expired(snum)) print_queue_update(snum); + const char *printername = lp_const_servicename(snum); + struct tdb_print_db *pdb = get_print_db_byname(printername); *queue = NULL; + if (!pdb) + return 0; + + /* make sure the database is up to date */ + if (print_cache_expired(snum)) + print_queue_update(snum); + /* * Fetch the queue status. We must do this first, as there may * be no jobs in the queue. */ ZERO_STRUCTP(status); - slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", lp_servicename(snum)); + slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername); key.dptr = keystr; key.dsize = strlen(keystr); - data = tdb_fetch(tdb, key); + data = tdb_fetch(pdb->tdb, key); if (data.dptr) { if (data.dsize == sizeof(*status)) { memcpy(status, data.dptr, sizeof(*status)); } - free(data.dptr); + SAFE_FREE(data.dptr); } /* @@ -1282,15 +1671,14 @@ int print_queue_status(int snum, tsc.count = 0; tsc.snum = snum; - tdb_traverse(tdb, traverse_count_fn_queue, (void *)&tsc); + tdb_traverse(pdb->tdb, traverse_count_fn_queue, (void *)&tsc); if (tsc.count == 0) return 0; /* Allocate the queue size. */ if ((tstruct.queue = (print_queue_struct *) - malloc(sizeof(print_queue_struct)*tsc.count)) - == NULL) + malloc(sizeof(print_queue_struct)*tsc.count)) == NULL) return 0; /* @@ -1302,7 +1690,7 @@ int print_queue_status(int snum, tstruct.maxcount = tsc.count; tstruct.snum = snum; - tdb_traverse(tdb, traverse_fn_queue, (void *)&tstruct); + tdb_traverse(pdb->tdb, traverse_fn_queue, (void *)&tstruct); /* Sort the queue by submission time otherwise they are displayed in hash order. */ @@ -1314,24 +1702,24 @@ int print_queue_status(int snum, return tstruct.qcount; } - /**************************************************************************** -turn a queue name into a snum + Turn a queue name into a snum. ****************************************************************************/ -int print_queue_snum(char *qname) + +int print_queue_snum(const char *qname) { int snum = lp_servicenumber(qname); - if (snum == -1 || !lp_print_ok(snum)) return -1; + if (snum == -1 || !lp_print_ok(snum)) + return -1; return snum; } - /**************************************************************************** - pause a queue + Pause a queue. ****************************************************************************/ + BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode) { - char *printer_name; int ret; if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { @@ -1351,19 +1739,17 @@ BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode) /* Send a printer notify message */ - printer_name = PRINTERNAME(snum); - - send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB); + notify_printer_status(snum, PRINTER_STATUS_PAUSED); return True; } /**************************************************************************** - resume a queue + Resume a queue. ****************************************************************************/ + BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode) { - char *printer_name; int ret; if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { @@ -1379,25 +1765,24 @@ BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode) } /* make sure the database is up to date */ - if (print_cache_expired(snum)) print_queue_update(snum); + if (print_cache_expired(snum)) + print_queue_update(snum); /* Send a printer notify message */ - printer_name = PRINTERNAME(snum); - - send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB); + notify_printer_status(snum, PRINTER_STATUS_OK); return True; } /**************************************************************************** - purge a queue - implemented by deleting all jobs that we can delete + Purge a queue - implemented by deleting all jobs that we can delete. ****************************************************************************/ + BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode) { print_queue_struct *queue; print_status_struct status; - char *printer_name; int njobs, i; BOOL can_job_admin; @@ -1415,13 +1800,7 @@ BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode) } } - safe_free(queue); - - /* Send a printer notify message */ - - printer_name = PRINTERNAME(snum); - - send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB); + SAFE_FREE(queue); return True; } -- cgit From b2edf254eda92f775e7d3d9b6793b4d77f9000b6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 17 Aug 2002 17:00:51 +0000 Subject: sync 3.0 branch with head (This used to be commit 3928578b52cfc949be5e0ef444fce1558d75f290) --- source3/printing/printing.c | 399 ++++++++++++++++++++------------------------ 1 file changed, 178 insertions(+), 221 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 7bfce43af6..cb689c05d6 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -39,98 +39,97 @@ static struct printif *current_printif = &generic_printif; jobids are assigned when a job starts spooling. */ -static pid_t local_pid; - -/* Mapping between printer names and queue id's in job id's. */ -struct printer_queueid_map { - struct printer_queueid_map *next, *prev; - char *printername; - uint32 queueid; -}; - -static struct printer_queueid_map *printer_queueid_map_head; -static uint32 last_queueid; - -#define QUEUEID_BITS 12 -#define QUEUEID_MASK ((1<<(QUEUEID_BITS))-1) -#define QUEUEID_TO_JOBID(queueid) (((queueid) & QUEUEID_MASK) << 20 ) +/*************************************************************************** + Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32 + bit RPC jobids.... JRA. +***************************************************************************/ -/**************************************************************************** - Create an association between a printer name and a queueid. Used to encode - the printer queueid in jobid's. - This could be converted to use an internal tdb if searching the list is - too slow. JRA. -****************************************************************************/ +static TDB_CONTEXT *rap_tdb; +static uint16 next_rap_jobid; -BOOL create_printer_queueid(const char *printername) +uint16 pjobid_to_rap(int snum, uint32 jobid) { - struct printer_queueid_map *p; + uint16 rap_jobid; + TDB_DATA data, key; + char jinfo[8]; - for (p = printer_queueid_map_head; p; p = p->next) { - if (strequal(p->printername, printername)) - return True; + if (!rap_tdb) { + /* Create the in-memory tdb. */ + rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644); + if (!rap_tdb) + return 0; } - p = (struct printer_queueid_map *)malloc(sizeof(*p)); - if (!p) { - DEBUG(0,("create_printer_queueid: malloc fail !\n")); - return False; - } - ZERO_STRUCTP(p); - p->printername = strdup(printername); - if (!p->printername) { - DEBUG(0,("create_printer_queueid: malloc fail !\n")); - SAFE_FREE(p); - return False; - } - p->queueid = (++last_queueid); - if (p->queueid > QUEUEID_MASK) { - DEBUG(0,("create_printer_queueid: malloc fail !\n")); - SAFE_FREE(p->printername); - SAFE_FREE(p); - return False; + SIVAL(&jinfo,0,(int32)snum); + SIVAL(&jinfo,4,jobid); + + key.dptr = (char *)&jinfo; + key.dsize = sizeof(jinfo); + data = tdb_fetch(rap_tdb, key); + if (data.dptr && data.dsize == sizeof(uint16)) { + memcpy(&rap_jobid, data.dptr, sizeof(uint16)); + SAFE_FREE(data.dptr); + return rap_jobid; } - DLIST_ADD(printer_queueid_map_head, p); - return True; + /* Not found - create and store mapping. */ + rap_jobid = ++next_rap_jobid; + if (rap_jobid == 0) + rap_jobid = ++next_rap_jobid; + data.dptr = (char *)&rap_jobid; + data.dsize = sizeof(rap_jobid); + tdb_store(rap_tdb, key, data, TDB_REPLACE); + tdb_store(rap_tdb, data, key, TDB_REPLACE); + return rap_jobid; } -void set_register_printer_fn(void) +BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid) { - extern BOOL (*register_printer_fn)(const char *); - register_printer_fn = create_printer_queueid; -} - -/**************************************************************************** - Lookups. -****************************************************************************/ + TDB_DATA data, key; + char jinfo[8]; -static uint32 get_printer_queueid_byname(const char *printername) -{ - struct printer_queueid_map *p; + if (!rap_tdb) + return False; - for (p = printer_queueid_map_head; p; p = p->next) { - if (strequal(p->printername, printername)) - return p->queueid; + key.dptr = (char *)&rap_jobid; + key.dsize = sizeof(rap_jobid); + data = tdb_fetch(rap_tdb, key); + if (data.dptr && data.dsize == sizeof(jinfo)) { + *psnum = IVAL(&jinfo,0); + *pjobid = IVAL(&jinfo,4); + SAFE_FREE(data.dptr); + return True; } - return 0; + return False; } -/**************************************************************************** - Lookups. -****************************************************************************/ - -static const char *get_printer_name_byjobid(uint32 jobid) +static void rap_jobid_delete(int snum, uint32 jobid) { - struct printer_queueid_map *p; - uint32 queueid = (((jobid)>>20) & QUEUEID_MASK); + TDB_DATA key, data; + uint16 rap_jobid; + char jinfo[8]; - for (p = printer_queueid_map_head; p; p = p->next) { - if (p->queueid == queueid) - return p->printername; - } - return NULL; + if (!rap_tdb) + return; + + SIVAL(&jinfo,0,(int32)snum); + SIVAL(&jinfo,4,jobid); + + key.dptr = (char *)&jinfo; + key.dsize = sizeof(jinfo); + data = tdb_fetch(rap_tdb, key); + if (!data.dptr || (data.dsize != sizeof(uint16))) + return; + + memcpy(&rap_jobid, data.dptr, sizeof(uint16)); + SAFE_FREE(data.dptr); + data.dptr = (char *)&rap_jobid; + data.dsize = sizeof(rap_jobid); + tdb_delete(rap_tdb, key); + tdb_delete(rap_tdb, data); } +static pid_t local_pid; + static int get_queue_status(int, print_status_struct *); #define MAX_PRINT_DBS_OPEN 1 @@ -186,9 +185,14 @@ static struct tdb_print_db *get_print_db_byname(const char *printername) DLIST_ADD(print_db_head, p); } - pstrcpy(printdb_path, lock_path(printername)); + pstrcpy(printdb_path, lock_path("printing/")); + pstrcat(printdb_path, printername); pstrcat(printdb_path, ".tdb"); + + become_root(); p->tdb = tdb_open_log(printdb_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); + unbecome_root(); + if (!p->tdb) { DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n", printdb_path )); @@ -200,14 +204,6 @@ static struct tdb_print_db *get_print_db_byname(const char *printername) return p; } -static struct tdb_print_db *get_print_db_byjobid( uint32 jobid) -{ - const char *printername = get_printer_name_byjobid(jobid); - if (!printername) - return NULL; - return get_print_db_byname(printername); -} - /**************************************************************************** Initialise the printing backend. Called once at startup. Does not survive a fork @@ -215,20 +211,28 @@ static struct tdb_print_db *get_print_db_byjobid( uint32 jobid) BOOL print_backend_init(void) { - struct printer_queueid_map *p; char *sversion = "INFO/version"; + pstring printing_path; + int services = lp_numservices(); + int snum; if (local_pid == sys_getpid()) return True; unlink(lock_path("printing.tdb")); + pstrcpy(printing_path,lock_path("printing")); + mkdir(printing_path,0755); + local_pid = sys_getpid(); /* handle a Samba upgrade */ - for (p = printer_queueid_map_head; p; p = p->next) { - struct tdb_print_db *pdb = get_print_db_byname(p->printername); + for (snum = 0; snum < services; snum++) { + struct tdb_print_db *pdb; + if (!lp_print_ok(snum)) + continue; + pdb = get_print_db_byname(lp_const_servicename(snum)); if (!pdb) continue; tdb_lock_bystring(pdb->tdb, sversion); @@ -286,11 +290,11 @@ static TDB_DATA print_key(uint32 jobid) Useful function to find a print job in the database. ****************************************************************************/ -static struct printjob *print_job_find(uint32 jobid) +static struct printjob *print_job_find(int snum, uint32 jobid) { static struct printjob pjob; TDB_DATA ret; - struct tdb_print_db *pdb = get_print_db_byjobid(jobid); + struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); if (!pdb) return NULL; @@ -334,11 +338,16 @@ static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, uint32 sysjob_to_jobid(int unix_jobid) { - struct printer_queueid_map *p; + int services = lp_numservices(); + int snum; + sysjob_to_jobid_value = (uint32)-1; - for (p = printer_queueid_map_head; p; p = p->next) { - struct tdb_print_db *pdb = get_print_db_byname(p->printername); + for (snum = 0; snum < services; snum++) { + struct tdb_print_db *pdb; + if (!lp_print_ok(snum)) + continue; + pdb = get_print_db_byname(lp_const_servicename(snum)); if (pdb) tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid); if (sysjob_to_jobid_value != (uint32)-1) @@ -385,14 +394,10 @@ static uint32 map_to_spoolss_status(uint32 lpq_status) return 0; } -static void pjob_store_notify(uint32 jobid, struct printjob *old_data, +static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data, struct printjob *new_data) { BOOL new_job = False; - int snum = print_job_snum(jobid); - - if (snum == -1) - return; if (!old_data) new_job = True; @@ -427,11 +432,11 @@ static void pjob_store_notify(uint32 jobid, struct printjob *old_data, Store a job structure back to the database. ****************************************************************************/ -static BOOL pjob_store(uint32 jobid, struct printjob *pjob) +static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob) { TDB_DATA old_data, new_data; BOOL ret; - struct tdb_print_db *pdb = get_print_db_byjobid(jobid); + struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); if (!pdb) return False; @@ -450,7 +455,7 @@ static BOOL pjob_store(uint32 jobid, struct printjob *pjob) if (ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob))) { pjob_store_notify( - jobid, (struct printjob *)old_data.dptr, + snum, jobid, (struct printjob *)old_data.dptr, (struct printjob *)new_data.dptr); free(old_data.dptr); } @@ -462,12 +467,11 @@ static BOOL pjob_store(uint32 jobid, struct printjob *pjob) Remove a job structure from the database. ****************************************************************************/ -static void pjob_delete(uint32 jobid) +static void pjob_delete(int snum, uint32 jobid) { - int snum; - struct printjob *pjob = print_job_find(jobid); + struct printjob *pjob = print_job_find(snum, jobid); uint32 job_status = 0; - struct tdb_print_db *pdb = get_print_db_byjobid(jobid); + struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); if (!pdb) return; @@ -486,7 +490,6 @@ static void pjob_delete(uint32 jobid) JOB_STATUS_DELETED for the port monitor to delete the job properly. */ - snum = print_job_snum(jobid); job_status |= JOB_STATUS_DELETING; notify_job_status(snum, jobid, job_status); @@ -496,6 +499,7 @@ static void pjob_delete(uint32 jobid) /* Remove from printing.tdb */ tdb_delete(pdb->tdb, print_key(jobid)); + rap_jobid_delete(snum, jobid); } /**************************************************************************** @@ -523,13 +527,12 @@ static uint32 print_parse_jobid(char *fname) static void print_unix_job(int snum, print_queue_struct *q) { - uint32 queueid = get_printer_queueid_byname(PRINTERNAME(snum)); - uint32 jobid = (q->job + UNIX_JOB_START) | QUEUEID_TO_JOBID(queueid); + uint32 jobid = q->job + UNIX_JOB_START; struct printjob pj, *old_pj; /* Preserve the timestamp on an existing unix print job */ - old_pj = print_job_find(jobid); + old_pj = print_job_find(snum, jobid); ZERO_STRUCT(pj); @@ -546,7 +549,7 @@ static void print_unix_job(int snum, print_queue_struct *q) fstrcpy(pj.user, q->fs_user); fstrcpy(pj.queuename, lp_const_servicename(snum)); - pjob_store(jobid, &pj); + pjob_store(snum, jobid, &pj); } @@ -561,7 +564,6 @@ struct traverse_struct { static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) { - uint32 queueid; struct traverse_struct *ts = (struct traverse_struct *)state; struct printjob pjob; uint32 jobid; @@ -577,18 +579,16 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void return 0; } - queueid = get_printer_queueid_byname(pjob.queuename); - if (!pjob.smbjob) { /* remove a unix job if it isn't in the system queue any more */ for (i=0;iqcount;i++) { - uint32 u_jobid = ((ts->queue[i].job + UNIX_JOB_START) | QUEUEID_TO_JOBID(queueid)); + uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START); if (jobid == u_jobid) break; } if (i == ts->qcount) - pjob_delete(jobid); + pjob_delete(ts->snum, jobid); else ts->total_jobs++; return 0; @@ -600,14 +600,14 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void exist then kill it. This cleans up after smbd deaths */ if (!process_exists(pjob.pid)) - pjob_delete(jobid); + pjob_delete(ts->snum, jobid); else ts->total_jobs++; return 0; } for (i=0;iqcount;i++) { - uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file) | QUEUEID_TO_JOBID(queueid); + uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file); if (jobid == curr_jobid) break; } @@ -627,7 +627,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void submitted less than lp_lpqcachetime() seconds ago. */ if ((cur_t - pjob.starttime) > lp_lpqcachetime()) - pjob_delete(jobid); + pjob_delete(ts->snum, jobid); else ts->total_jobs++; } @@ -688,7 +688,7 @@ static pid_t get_updating_pid(fstring printer_name) in the tdb. ****************************************************************************/ -static void set_updating_pid(fstring printer_name, BOOL delete) +static void set_updating_pid(const fstring printer_name, BOOL delete) { fstring keystr; TDB_DATA key; @@ -813,7 +813,7 @@ static void print_queue_update(int snum) } /* we have an active SMB print job - update its status */ - pjob = print_job_find(jobid); + pjob = print_job_find(snum, jobid); if (!pjob) { /* err, somethings wrong. Probably smbd was restarted with jobs in the queue. All we can do is treat them @@ -825,7 +825,7 @@ static void print_queue_update(int snum) pjob->sysjob = queue[i].job; pjob->status = queue[i].status; - pjob_store(jobid, pjob); + pjob_store(snum, jobid, pjob); } /* now delete any queued entries that don't appear in the @@ -871,36 +871,21 @@ static void print_queue_update(int snum) Check if a jobid is valid. It is valid if it exists in the database. ****************************************************************************/ -BOOL print_job_exists(uint32 jobid) +BOOL print_job_exists(int snum, uint32 jobid) { - struct tdb_print_db *pdb = get_print_db_byjobid(jobid); + struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); if (!pdb) return False; return tdb_exists(pdb->tdb, print_key(jobid)); } -/**************************************************************************** - Work out which service a jobid is for. - Note that we have to look up by queue name to ensure that it works for - other than the process that started the job. -****************************************************************************/ - -int print_job_snum(uint32 jobid) -{ - struct printjob *pjob = print_job_find(jobid); - if (!pjob) - return -1; - - return find_service(pjob->queuename); -} - /**************************************************************************** Give the fd used for a jobid. ****************************************************************************/ -int print_job_fd(uint32 jobid) +int print_job_fd(int snum, uint32 jobid) { - struct printjob *pjob = print_job_find(jobid); + struct printjob *pjob = print_job_find(snum, jobid); if (!pjob) return -1; /* don't allow another process to get this info - it is meaningless */ @@ -915,9 +900,9 @@ int print_job_fd(uint32 jobid) has not been spooled. ****************************************************************************/ -char *print_job_fname(uint32 jobid) +char *print_job_fname(int snum, uint32 jobid) { - struct printjob *pjob = print_job_find(jobid); + struct printjob *pjob = print_job_find(snum, jobid); if (!pjob || pjob->spooled || pjob->pid != local_pid) return NULL; return pjob->filename; @@ -927,7 +912,7 @@ char *print_job_fname(uint32 jobid) Set the place in the queue for a job. ****************************************************************************/ -BOOL print_job_set_place(uint32 jobid, int place) +BOOL print_job_set_place(int snum, uint32 jobid, int place) { DEBUG(2,("print_job_set_place not implemented yet\n")); return False; @@ -937,24 +922,24 @@ BOOL print_job_set_place(uint32 jobid, int place) Set the name of a job. Only possible for owner. ****************************************************************************/ -BOOL print_job_set_name(uint32 jobid, char *name) +BOOL print_job_set_name(int snum, uint32 jobid, char *name) { - struct printjob *pjob = print_job_find(jobid); + struct printjob *pjob = print_job_find(snum, jobid); if (!pjob || pjob->pid != local_pid) return False; fstrcpy(pjob->jobname, name); - return pjob_store(jobid, pjob); + return pjob_store(snum, jobid, pjob); } /**************************************************************************** Delete a print job - don't update queue. ****************************************************************************/ -static BOOL print_job_delete1(uint32 jobid) +static BOOL print_job_delete1(int snum, uint32 jobid) { - struct printjob *pjob = print_job_find(jobid); - int snum, result = 0; + struct printjob *pjob = print_job_find(snum, jobid); + int result = 0; if (!pjob) return False; @@ -966,12 +951,6 @@ static BOOL print_job_delete1(uint32 jobid) if (pjob->status == LPQ_DELETING) return True; - snum = print_job_snum(jobid); - if (snum == -1) { - DEBUG(5,("print_job_delete1: unknown service number for jobid %u\n", (unsigned int)jobid)); - return False; - } - /* Hrm - we need to be able to cope with deleting a job before it has reached the spooler. */ @@ -982,7 +961,7 @@ static BOOL print_job_delete1(uint32 jobid) /* Set the tdb entry to be deleting. */ pjob->status = LPQ_DELETING; - pjob_store(jobid, pjob); + pjob_store(snum, jobid, pjob); if (pjob->spooled && pjob->sysjob != -1) result = (*(current_printif->job_delete))(snum, pjob); @@ -991,7 +970,7 @@ static BOOL print_job_delete1(uint32 jobid) been spooled. */ if (result == 0) - pjob_delete(jobid); + pjob_delete(snum, jobid); return (result == 0); } @@ -1000,9 +979,9 @@ static BOOL print_job_delete1(uint32 jobid) Return true if the current user owns the print job. ****************************************************************************/ -static BOOL is_owner(struct current_user *user, uint32 jobid) +static BOOL is_owner(struct current_user *user, int snum, uint32 jobid) { - struct printjob *pjob = print_job_find(jobid); + struct printjob *pjob = print_job_find(snum, jobid); user_struct *vuser; if (!pjob || !user) @@ -1019,17 +998,11 @@ static BOOL is_owner(struct current_user *user, uint32 jobid) Delete a print job. ****************************************************************************/ -BOOL print_job_delete(struct current_user *user, uint32 jobid, WERROR *errcode) +BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) { - int snum = print_job_snum(jobid); BOOL owner; - if (snum == -1) { - DEBUG(5,("print_job_delete: unknown service number for jobid %d\n", jobid)); - return False; - } - - owner = is_owner(user, jobid); + owner = is_owner(user, snum, jobid); /* Check access against security descriptor or whether the user owns their job. */ @@ -1041,7 +1014,7 @@ BOOL print_job_delete(struct current_user *user, uint32 jobid, WERROR *errcode) return False; } - if (!print_job_delete1(jobid)) + if (!print_job_delete1(snum, jobid)) return False; /* force update the database and say the delete failed if the @@ -1049,17 +1022,17 @@ BOOL print_job_delete(struct current_user *user, uint32 jobid, WERROR *errcode) print_queue_update(snum); - return !print_job_exists(jobid); + return !print_job_exists(snum, jobid); } /**************************************************************************** Pause a job. ****************************************************************************/ -BOOL print_job_pause(struct current_user *user, uint32 jobid, WERROR *errcode) +BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) { - struct printjob *pjob = print_job_find(jobid); - int snum, ret = -1; + struct printjob *pjob = print_job_find(snum, jobid); + int ret = -1; if (!pjob || !user) return False; @@ -1067,13 +1040,7 @@ BOOL print_job_pause(struct current_user *user, uint32 jobid, WERROR *errcode) if (!pjob->spooled || pjob->sysjob == -1) return False; - snum = print_job_snum(jobid); - if (snum == -1) { - DEBUG(5,("print_job_pause: unknown service number for jobid %u\n", (unsigned int)jobid)); - return False; - } - - if (!is_owner(user, jobid) && + if (!is_owner(user, snum, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("pause denied by security descriptor\n")); *errcode = WERR_ACCESS_DENIED; @@ -1104,10 +1071,10 @@ BOOL print_job_pause(struct current_user *user, uint32 jobid, WERROR *errcode) Resume a job. ****************************************************************************/ -BOOL print_job_resume(struct current_user *user, uint32 jobid, WERROR *errcode) +BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) { - struct printjob *pjob = print_job_find(jobid); - int snum, ret; + struct printjob *pjob = print_job_find(snum, jobid); + int ret; if (!pjob || !user) return False; @@ -1115,13 +1082,7 @@ BOOL print_job_resume(struct current_user *user, uint32 jobid, WERROR *errcode) if (!pjob->spooled || pjob->sysjob == -1) return False; - snum = print_job_snum(jobid); - if (snum == -1) { - DEBUG(5,("print_job_resume: unknown service number for jobid %u\n", (unsigned int)jobid)); - return False; - } - - if (!is_owner(user, jobid) && + if (!is_owner(user, snum, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("resume denied by security descriptor\n")); *errcode = WERR_ACCESS_DENIED; @@ -1149,10 +1110,10 @@ BOOL print_job_resume(struct current_user *user, uint32 jobid, WERROR *errcode) Write to a print file. ****************************************************************************/ -int print_job_write(uint32 jobid, const char *buf, int size) +int print_job_write(int snum, uint32 jobid, const char *buf, int size) { int return_code; - struct printjob *pjob = print_job_find(jobid); + struct printjob *pjob = print_job_find(snum, jobid); if (!pjob) return -1; @@ -1163,7 +1124,7 @@ int print_job_write(uint32 jobid, const char *buf, int size) return_code = write(pjob->fd, buf, size); if (return_code>0) { pjob->size += size; - pjob_store(jobid, pjob); + pjob_store(snum, jobid, pjob); } return return_code; } @@ -1260,18 +1221,24 @@ int print_queue_length(int snum, print_status_struct *pstatus) static int get_total_jobs(void) { - int total_jobs; - struct printer_queueid_map *p; + int total_jobs = 0; + int snum; + int services = lp_numservices(); - for (p = printer_queueid_map_head; p; p = p->next) { + for (snum = 0; snum < services; snum++) { + struct tdb_print_db *pdb; int jobs; - struct tdb_print_db *pdb = get_print_db_byname(p->printername); + + if (!lp_print_ok(snum)) + continue; + + pdb = get_print_db_byname(lp_const_servicename(snum)); if (!pdb) continue; /* make sure the database is up to date */ - if (print_cache_expired(lp_servicenumber(p->printername))) - print_queue_update(lp_servicenumber(p->printername)); + if (print_cache_expired(snum)) + print_queue_update(snum); jobs = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs"); if (jobs > 0) @@ -1294,7 +1261,6 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) int njobs = 0; const char *printername = lp_const_servicename(snum); struct tdb_print_db *pdb = get_print_db_byname(printername); - uint32 queueid = queueid = get_printer_queueid_byname(printername); errno = 0; @@ -1376,10 +1342,10 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) next_jobid = 1; for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) { - if (!print_job_exists(jobid | QUEUEID_TO_JOBID(queueid))) + if (!print_job_exists(snum, jobid)) break; } - if (jobid == next_jobid || !pjob_store(jobid | QUEUEID_TO_JOBID(queueid), &pjob)) { + if (jobid == next_jobid || !pjob_store(snum, jobid, &pjob)) { DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or pjob_store failed.\n", jobid, next_jobid )); jobid = -1; @@ -1392,9 +1358,6 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) goto fail; } - /* Ensure the queuid is added to the jobid. */ - jobid |= QUEUEID_TO_JOBID(queueid); - /* we have a job entry - now create the spool file */ slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", path, PRINT_SPOOL_PREFIX, (unsigned int)jobid); @@ -1413,7 +1376,7 @@ to open spool file %s.\n", pjob.filename)); goto fail; } - pjob_store(jobid, &pjob); + pjob_store(snum, jobid, &pjob); tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); @@ -1425,14 +1388,14 @@ to open spool file %s.\n", pjob.filename)); * tim@fsg.com 09/06/94 */ if (lp_postscript(snum)) { - print_job_write(jobid, "%!\n",3); + print_job_write(snum, jobid, "%!\n",3); } return jobid; fail: if (jobid != -1) - pjob_delete(jobid); + pjob_delete(snum, jobid); tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); @@ -1444,9 +1407,9 @@ to open spool file %s.\n", pjob.filename)); Update the number of pages spooled to jobid ****************************************************************************/ -void print_job_endpage(uint32 jobid) +void print_job_endpage(int snum, uint32 jobid) { - struct printjob *pjob = print_job_find(jobid); + struct printjob *pjob = print_job_find(snum, jobid); if (!pjob) return; /* don't allow another process to get this info - it is meaningless */ @@ -1454,7 +1417,7 @@ void print_job_endpage(uint32 jobid) return; pjob->page_count++; - pjob_store(jobid, pjob); + pjob_store(snum, jobid, pjob); } /**************************************************************************** @@ -1463,10 +1426,10 @@ void print_job_endpage(uint32 jobid) error. ****************************************************************************/ -BOOL print_job_end(uint32 jobid, BOOL normal_close) +BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) { - struct printjob *pjob = print_job_find(jobid); - int snum, ret; + struct printjob *pjob = print_job_find(snum, jobid); + int ret; SMB_STRUCT_STAT sbuf; if (!pjob) @@ -1475,12 +1438,6 @@ BOOL print_job_end(uint32 jobid, BOOL normal_close) if (pjob->spooled || pjob->pid != local_pid) return False; - snum = print_job_snum(jobid); - if (snum == -1) { - DEBUG(5,("print_job_end: unknown service number for jobid %u\n", (unsigned int)jobid)); - return False; - } - if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) { pjob->size = sbuf.st_size; close(pjob->fd); @@ -1505,7 +1462,7 @@ BOOL print_job_end(uint32 jobid, BOOL normal_close) DEBUG(5,("print_job_end: canceling spool of %s (%s)\n", pjob->filename, pjob->size ? "deleted" : "zero length" )); unlink(pjob->filename); - pjob_delete(jobid); + pjob_delete(snum, jobid); return True; } @@ -1518,7 +1475,7 @@ BOOL print_job_end(uint32 jobid, BOOL normal_close) pjob->spooled = True; pjob->status = LPQ_QUEUED; - pjob_store(jobid, pjob); + pjob_store(snum, jobid, pjob); /* make sure the database is up to date */ if (print_cache_expired(snum)) @@ -1531,7 +1488,7 @@ fail: /* The print job was not succesfully started. Cleanup */ /* Still need to add proper error return propagation! 010122:JRR */ unlink(pjob->filename); - pjob_delete(jobid); + pjob_delete(snum, jobid); return False; } @@ -1793,10 +1750,10 @@ BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode) njobs = print_queue_status(snum, &queue, &status); for (i=0;i Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/printing/printing.c | 427 ++++++++++++++++++++++++++++++++------------ 1 file changed, 317 insertions(+), 110 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index cb689c05d6..6474c92c69 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -132,11 +132,13 @@ static pid_t local_pid; static int get_queue_status(int, print_status_struct *); +/* There can be this many printing tdb's open, plus any locked ones. */ #define MAX_PRINT_DBS_OPEN 1 struct tdb_print_db { struct tdb_print_db *next, *prev; TDB_CONTEXT *tdb; + int ref_count; fstring printer_name; }; @@ -149,32 +151,45 @@ static struct tdb_print_db *print_db_head; static struct tdb_print_db *get_print_db_byname(const char *printername) { - struct tdb_print_db *p, *last_entry; + struct tdb_print_db *p = NULL, *last_entry = NULL; int num_open = 0; pstring printdb_path; for (p = print_db_head, last_entry = print_db_head; p; p = p->next) { if (p->tdb && strequal(p->printer_name, printername)) { DLIST_PROMOTE(print_db_head, p); + p->ref_count++; return p; } num_open++; last_entry = p; } + /* Not found. */ if (num_open >= MAX_PRINT_DBS_OPEN) { - /* Recycle the last entry. */ + /* Try and recycle the last entry. */ DLIST_PROMOTE(print_db_head, last_entry); - if (print_db_head->tdb) { - if (tdb_close(print_db_head->tdb)) { - DEBUG(0,("get_print_db: Failed to close tdb for printer %s\n", - print_db_head->printer_name )); - return NULL; + + for (p = print_db_head; p; p = p->next) { + if (p->ref_count) + continue; + if (p->tdb) { + if (tdb_close(print_db_head->tdb)) { + DEBUG(0,("get_print_db: Failed to close tdb for printer %s\n", + print_db_head->printer_name )); + return NULL; + } } + ZERO_STRUCTP(p); + break; } - p = print_db_head; - ZERO_STRUCTP(p); - } else { + if (p) { + DLIST_PROMOTE(print_db_head, p); + p = print_db_head; + } + } + + if (!p) { /* Create one. */ p = (struct tdb_print_db *)malloc(sizeof(struct tdb_print_db)); if (!p) { @@ -201,9 +216,16 @@ static struct tdb_print_db *get_print_db_byname(const char *printername) return NULL; } fstrcpy(p->printer_name, printername); + p->ref_count++; return p; } +static void release_print_db( struct tdb_print_db *pdb) +{ + pdb->ref_count--; + SMB_ASSERT(pdb->ref_count >= 0); +} + /**************************************************************************** Initialise the printing backend. Called once at startup. Does not survive a fork @@ -235,7 +257,10 @@ BOOL print_backend_init(void) pdb = get_print_db_byname(lp_const_servicename(snum)); if (!pdb) continue; - tdb_lock_bystring(pdb->tdb, sversion); + if (tdb_lock_bystring(pdb->tdb, sversion) == -1) { + DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) )); + return False; + } if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) { tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL); tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION); @@ -286,25 +311,74 @@ static TDB_DATA print_key(uint32 jobid) return ret; } +/*********************************************************************** + unpack a pjob from a tdb buffer +***********************************************************************/ + +int unpack_pjob( char* buf, int buflen, struct printjob *pjob ) +{ + int len = 0; + int used; + + if ( !buf || !pjob ) + return -1; + + len += tdb_unpack(buf+len, buflen-len, "dddddddddffff", + &pjob->pid, + &pjob->sysjob, + &pjob->fd, + &pjob->starttime, + &pjob->status, + &pjob->size, + &pjob->page_count, + &pjob->spooled, + &pjob->smbjob, + pjob->filename, + pjob->jobname, + pjob->user, + pjob->queuename); + + if ( len == -1 ) + return -1; + + if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 ) + return -1; + + len += used; + + return len; + +} + /**************************************************************************** Useful function to find a print job in the database. ****************************************************************************/ static struct printjob *print_job_find(int snum, uint32 jobid) { - static struct printjob pjob; - TDB_DATA ret; - struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); + static struct printjob pjob; + TDB_DATA ret; + struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); + if (!pdb) return NULL; ret = tdb_fetch(pdb->tdb, print_key(jobid)); - if (!ret.dptr || ret.dsize != sizeof(pjob)) - return NULL; + release_print_db(pdb); - memcpy(&pjob, ret.dptr, sizeof(pjob)); - SAFE_FREE(ret.dptr); + if (!ret.dptr) + return NULL; + + if ( pjob.nt_devmode ) + free_nt_devicemode( &pjob.nt_devmode ); + + ZERO_STRUCT( pjob ); + + if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) + return NULL; + + SAFE_FREE(ret.dptr); return &pjob; } @@ -315,9 +389,13 @@ static uint32 sysjob_to_jobid_value; static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA data, void *state) { - struct printjob *pjob = (struct printjob *)data.dptr; + struct printjob *pjob; int *sysjob = (int *)state; + if (!data.dptr || data.dsize == 0) + return 0; + + pjob = (struct printjob *)data.dptr; if (key.dsize != sizeof(uint32)) return 0; @@ -350,6 +428,7 @@ uint32 sysjob_to_jobid(int unix_jobid) pdb = get_print_db_byname(lp_const_servicename(snum)); if (pdb) tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid); + release_print_db(pdb); if (sysjob_to_jobid_value != (uint32)-1) return sysjob_to_jobid_value; } @@ -434,9 +513,12 @@ static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data, static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob) { - TDB_DATA old_data, new_data; - BOOL ret; - struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); + TDB_DATA old_data, new_data; + BOOL ret = False; + struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); + char *buf = NULL; + int len, newlen, buflen; + if (!pdb) return False; @@ -445,20 +527,63 @@ static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob) old_data = tdb_fetch(pdb->tdb, print_key(jobid)); + /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */ + + newlen = 0; + + do { + len = 0; + buflen = newlen; + len += tdb_pack(buf+len, buflen-len, "dddddddddffff", + pjob->pid, + pjob->sysjob, + pjob->fd, + pjob->starttime, + pjob->status, + pjob->size, + pjob->page_count, + pjob->spooled, + pjob->smbjob, + pjob->filename, + pjob->jobname, + pjob->user, + pjob->queuename); + + len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len); + + if (buflen != len) + { + char *tb; + + tb = (char *)Realloc(buf, len); + if (!tb) { + DEBUG(0,("pjob_store: failed to enlarge buffer!\n")); + goto done; + } + else + buf = tb; + newlen = len; + } + } + while ( buflen != len ); + + /* Store new data */ - new_data.dptr = (void *)pjob; - new_data.dsize = sizeof(*pjob); + new_data.dptr = buf; + new_data.dsize = len; ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0); + release_print_db(pdb); + /* Send notify updates for what has changed */ - if (ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob))) { - pjob_store_notify( - snum, jobid, (struct printjob *)old_data.dptr, - (struct printjob *)new_data.dptr); - free(old_data.dptr); - } + if ( ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob)) ) + pjob_store_notify( snum, jobid, (struct printjob *)old_data.dptr, pjob ); + +done: + SAFE_FREE( old_data.dptr ); + SAFE_FREE( buf ); return ret; } @@ -479,6 +604,7 @@ static void pjob_delete(int snum, uint32 jobid) if (!pjob) { DEBUG(5, ("pjob_delete(): we were asked to delete nonexistent job %u\n", (unsigned int)jobid)); + release_print_db(pdb); return; } @@ -499,6 +625,7 @@ static void pjob_delete(int snum, uint32 jobid) /* Remove from printing.tdb */ tdb_delete(pdb->tdb, print_key(jobid)); + release_print_db(pdb); rap_jobid_delete(snum, jobid); } @@ -569,10 +696,14 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void uint32 jobid; int i; - if (data.dsize != sizeof(pjob) || key.dsize != sizeof(jobid)) + if ( key.dsize != sizeof(jobid) ) return 0; + memcpy(&jobid, key.dptr, sizeof(jobid)); - memcpy(&pjob, data.dptr, sizeof(pjob)); + if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 ) + return 0; + free_nt_devicemode( &pjob.nt_devmode ); + if (ts->snum != lp_servicenumber(pjob.queuename)) { /* this isn't for the queue we are looking at - this cannot happen with the split tdb's. JRA */ @@ -651,6 +782,7 @@ static void print_cache_flush(int snum) return; slprintf(key, sizeof(key)-1, "CACHE/%s", printername); tdb_store_int32(pdb->tdb, key, -1); + release_print_db(pdb); } /**************************************************************************** @@ -671,6 +803,7 @@ static pid_t get_updating_pid(fstring printer_name) key.dsize = strlen(keystr); data = tdb_fetch(pdb->tdb, key); + release_print_db(pdb); if (!data.dptr || data.dsize != sizeof(pid_t)) return (pid_t)-1; @@ -705,6 +838,7 @@ static void set_updating_pid(const fstring printer_name, BOOL delete) if (delete) { tdb_delete(pdb->tdb, key); + release_print_db(pdb); return; } @@ -712,6 +846,7 @@ static void set_updating_pid(const fstring printer_name, BOOL delete) data.dsize = sizeof(pid_t); tdb_store(pdb->tdb, key, data, TDB_REPLACE); + release_print_db(pdb); } /**************************************************************************** @@ -740,13 +875,19 @@ static void print_queue_update(int snum) * This is essentially a mutex on the update. */ - if (get_updating_pid(printer_name) != -1) + if (get_updating_pid(printer_name) != -1) { + release_print_db(pdb); return; + } /* Lock the queue for the database update */ slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name); - tdb_lock_bystring(pdb->tdb, keystr); + if (tdb_lock_bystring(pdb->tdb, keystr) == -1) { + DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name)); + release_print_db(pdb); + return; + } /* * Ensure that no one else got in here. @@ -759,6 +900,7 @@ static void print_queue_update(int snum) * Someone else is doing the update, exit. */ tdb_unlock_bystring(pdb->tdb, keystr); + release_print_db(pdb); return; } @@ -865,6 +1007,7 @@ static void print_queue_update(int snum) /* Delete our pid from the db. */ set_updating_pid(printer_name, True); + release_print_db(pdb); } /**************************************************************************** @@ -874,9 +1017,13 @@ static void print_queue_update(int snum) BOOL print_job_exists(int snum, uint32 jobid) { struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); + BOOL ret; + if (!pdb) return False; - return tdb_exists(pdb->tdb, print_key(jobid)); + ret = tdb_exists(pdb->tdb, print_key(jobid)); + release_print_db(pdb); + return ret; } /**************************************************************************** @@ -908,6 +1055,23 @@ char *print_job_fname(int snum, uint32 jobid) return pjob->filename; } + +/**************************************************************************** + Give the filename used for a jobid. + Only valid for the process doing the spooling and when the job + has not been spooled. +****************************************************************************/ + +NT_DEVICEMODE *print_job_devmode(int snum, uint32 jobid) +{ + struct printjob *pjob = print_job_find(snum, jobid); + + if ( !pjob ) + return NULL; + + return pjob->nt_devmode; +} + /**************************************************************************** Set the place in the queue for a job. ****************************************************************************/ @@ -1000,8 +1164,11 @@ static BOOL is_owner(struct current_user *user, int snum, uint32 jobid) BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) { - BOOL owner; + BOOL owner, deleted; + char *fname; + *errcode = WERR_OK; + owner = is_owner(user, snum, jobid); /* Check access against security descriptor or whether the user @@ -1014,15 +1181,40 @@ BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR return False; } - if (!print_job_delete1(snum, jobid)) + /* + * get the spooled filename of the print job + * if this works, then the file has not been spooled + * to the underlying print system. Just delete the + * spool file & return. + */ + + if ( (fname = print_job_fname( snum, jobid )) != NULL ) + { + /* remove the spool file */ + DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname )); + if ( unlink( fname ) == -1 ) { + *errcode = map_werror_from_unix(errno); + return False; + } + + return True; + } + + if (!print_job_delete1(snum, jobid)) { + *errcode = WERR_ACCESS_DENIED; return False; + } /* force update the database and say the delete failed if the job still exists */ print_queue_update(snum); + + deleted = !print_job_exists(snum, jobid); + if ( !deleted ) + *errcode = WERR_ACCESS_DENIED; - return !print_job_exists(snum, jobid); + return deleted; } /**************************************************************************** @@ -1161,8 +1353,10 @@ static BOOL print_cache_expired(int snum) DEBUG(3, ("print cache expired for queue %s \ (last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername, (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() )); + release_print_db(pdb); return True; } + release_print_db(pdb); return False; } @@ -1184,6 +1378,7 @@ static int get_queue_status(int snum, print_status_struct *status) key.dptr = keystr; key.dsize = strlen(keystr); data = tdb_fetch(pdb->tdb, key); + release_print_db(pdb); if (data.dptr) { if (data.dsize == sizeof(print_status_struct)) { memcpy(status, data.dptr, sizeof(print_status_struct)); @@ -1214,44 +1409,11 @@ int print_queue_length(int snum, print_status_struct *pstatus) return len; } -/**************************************************************************** - Determine the number of jobs in all queues. This is very expensive. Don't - call ! JRA. -****************************************************************************/ - -static int get_total_jobs(void) -{ - int total_jobs = 0; - int snum; - int services = lp_numservices(); - - for (snum = 0; snum < services; snum++) { - struct tdb_print_db *pdb; - int jobs; - - if (!lp_print_ok(snum)) - continue; - - pdb = get_print_db_byname(lp_const_servicename(snum)); - if (!pdb) - continue; - - /* make sure the database is up to date */ - if (print_cache_expired(snum)) - print_queue_update(snum); - - jobs = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs"); - if (jobs > 0) - total_jobs += jobs; - } - return total_jobs; -} - /*************************************************************************** Start spooling a job - return the jobid. ***************************************************************************/ -uint32 print_job_start(struct current_user *user, int snum, char *jobname) +uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode ) { uint32 jobid; char *path; @@ -1261,6 +1423,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) int njobs = 0; const char *printername = lp_const_servicename(snum); struct tdb_print_db *pdb = get_print_db_byname(printername); + BOOL pdb_locked = False; errno = 0; @@ -1269,11 +1432,13 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) { DEBUG(3, ("print_job_start: job start denied by security descriptor\n")); + release_print_db(pdb); return (uint32)-1; } if (!print_time_access_check(snum)) { DEBUG(3, ("print_job_start: job start denied by time check\n")); + release_print_db(pdb); return (uint32)-1; } @@ -1285,6 +1450,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) if (sys_fsusage(path, &dspace, &dsize) == 0 && dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) { DEBUG(3, ("print_job_start: disk space check failed.\n")); + release_print_db(pdb); errno = ENOSPC; return (uint32)-1; } @@ -1293,6 +1459,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) /* for autoloaded printers, check that the printcap entry still exists */ if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) { DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) )); + release_print_db(pdb); errno = ENOENT; return (uint32)-1; } @@ -1301,41 +1468,19 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) if (lp_maxprintjobs(snum) && (njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) { DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per queue (%d).\n", njobs, lp_maxprintjobs(snum) )); + release_print_db(pdb); errno = ENOSPC; return (uint32)-1; } - /* Insure the maximum print jobs in the system is not violated */ - if (lp_totalprintjobs() && get_total_jobs() > lp_totalprintjobs()) { - DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per system (%d).\n", - njobs, lp_totalprintjobs() )); - errno = ENOSPC; + /* Lock the database */ + if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob") == -1) { + DEBUG(0,("print_job_start: failed to lock printing database %s\n", printername )); + release_print_db(pdb); return (uint32)-1; } - /* create the database entry */ - ZERO_STRUCT(pjob); - pjob.pid = local_pid; - pjob.sysjob = -1; - pjob.fd = -1; - pjob.starttime = time(NULL); - pjob.status = LPQ_SPOOLING; - pjob.size = 0; - pjob.spooled = False; - pjob.smbjob = True; - - fstrcpy(pjob.jobname, jobname); - - if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { - fstrcpy(pjob.user, vuser->user.smb_name); - } else { - fstrcpy(pjob.user, uidtoname(user->uid)); - } - - fstrcpy(pjob.queuename, lp_const_servicename(snum)); - - /* lock the database */ - tdb_lock_bystring(pdb->tdb, "INFO/nextjob"); + pdb_locked = True; next_jobid = tdb_fetch_int32(pdb->tdb, "INFO/nextjob"); if (next_jobid == -1) @@ -1345,19 +1490,61 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) if (!print_job_exists(snum, jobid)) break; } - if (jobid == next_jobid || !pjob_store(snum, jobid, &pjob)) { - DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or pjob_store failed.\n", + + if (jobid == next_jobid) { + DEBUG(3, ("print_job_start: jobid (%d)==next_jobid(%d).\n", jobid, next_jobid )); jobid = -1; goto fail; } + /* Store a dummy placeholder. This must be quick as we have the lock. */ + { + TDB_DATA dum; + dum.dptr = NULL; + dum.dsize = 0; + if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) { + DEBUG(3, ("print_job_start: jobid (%d) failed to store placeholder.\n", + jobid )); + jobid = -1; + goto fail; + } + } + if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) { DEBUG(3, ("print_job_start: failed to store INFO/nextjob.\n")); jobid = -1; goto fail; } + /* We've finished with the INFO/nextjob lock. */ + tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); + pdb_locked = False; + + /* create the database entry */ + + ZERO_STRUCT(pjob); + + pjob.pid = local_pid; + pjob.sysjob = -1; + pjob.fd = -1; + pjob.starttime = time(NULL); + pjob.status = LPQ_SPOOLING; + pjob.size = 0; + pjob.spooled = False; + pjob.smbjob = True; + pjob.nt_devmode = nt_devmode; + + fstrcpy(pjob.jobname, jobname); + + if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { + fstrcpy(pjob.user, vuser->user.smb_name); + } else { + fstrcpy(pjob.user, uidtoname(user->uid)); + } + + fstrcpy(pjob.queuename, lp_const_servicename(snum)); + /* we have a job entry - now create the spool file */ slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", path, PRINT_SPOOL_PREFIX, (unsigned int)jobid); @@ -1378,7 +1565,7 @@ to open spool file %s.\n", pjob.filename)); pjob_store(snum, jobid, &pjob); - tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); + release_print_db(pdb); /* * If the printer is marked as postscript output a leading @@ -1397,7 +1584,9 @@ to open spool file %s.\n", pjob.filename)); if (jobid != -1) pjob_delete(snum, jobid); - tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); + if (pdb_locked) + tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); + release_print_db(pdb); DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) )); return -1; @@ -1503,10 +1692,16 @@ static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void * int i; uint32 jobid; - if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) + /* sanity checks */ + + if ( key.dsize != sizeof(jobid) ) return 0; + memcpy(&jobid, key.dptr, sizeof(jobid)); - memcpy(&pjob, data.dptr, sizeof(pjob)); + + if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 ) + return 0; + free_nt_devicemode( &pjob.nt_devmode ); /* maybe it isn't for this queue */ if (ts->snum != lp_servicenumber(pjob.queuename)) @@ -1545,10 +1740,17 @@ static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, struct printjob pjob; uint32 jobid; - if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) + /* sanity checks */ + + if ( key.dsize != sizeof(jobid) ) return 0; + memcpy(&jobid, key.dptr, sizeof(jobid)); - memcpy(&pjob, data.dptr, sizeof(pjob)); + + if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 ) + return 0; + + free_nt_devicemode( &pjob.nt_devmode ); /* maybe it isn't for this queue - this cannot happen with the tdb/printer code. JRA */ if (ts->snum != lp_servicenumber(pjob.queuename)) @@ -1630,13 +1832,17 @@ int print_queue_status(int snum, tdb_traverse(pdb->tdb, traverse_count_fn_queue, (void *)&tsc); - if (tsc.count == 0) + if (tsc.count == 0) { + release_print_db(pdb); return 0; + } /* Allocate the queue size. */ if ((tstruct.queue = (print_queue_struct *) - malloc(sizeof(print_queue_struct)*tsc.count)) == NULL) + malloc(sizeof(print_queue_struct)*tsc.count)) == NULL) { + release_print_db(pdb); return 0; + } /* * Fill in the queue. @@ -1648,6 +1854,7 @@ int print_queue_status(int snum, tstruct.snum = snum; tdb_traverse(pdb->tdb, traverse_fn_queue, (void *)&tstruct); + release_print_db(pdb); /* Sort the queue by submission time otherwise they are displayed in hash order. */ -- cgit From 3665777a5bc7ffa92f64ba17daf4cc66c3607198 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Oct 2002 22:53:18 +0000 Subject: Add a timeout to tdb_lock_bystring(). Ensure we never have more than MAX_PRINT_JOBS in a queue. Jeremy. (This used to be commit 9fe3c0b90d4bff2217e3cb5a34b4683ca314c06e) --- source3/printing/printing.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 6474c92c69..91851a37f8 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -257,7 +257,7 @@ BOOL print_backend_init(void) pdb = get_print_db_byname(lp_const_servicename(snum)); if (!pdb) continue; - if (tdb_lock_bystring(pdb->tdb, sversion) == -1) { + if (tdb_lock_bystring(pdb->tdb, sversion, 0) == -1) { DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) )); return False; } @@ -883,7 +883,8 @@ static void print_queue_update(int snum) /* Lock the queue for the database update */ slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name); - if (tdb_lock_bystring(pdb->tdb, keystr) == -1) { + /* Only wait 10 seconds for this. */ + if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) { DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name)); release_print_db(pdb); return; @@ -1380,9 +1381,8 @@ static int get_queue_status(int snum, print_status_struct *status) data = tdb_fetch(pdb->tdb, key); release_print_db(pdb); if (data.dptr) { - if (data.dsize == sizeof(print_status_struct)) { + if (data.dsize == sizeof(print_status_struct)) memcpy(status, data.dptr, sizeof(print_status_struct)); - } SAFE_FREE(data.dptr); } return status->qcount; @@ -1465,7 +1465,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE } /* Insure the maximum queue size is not violated */ - if (lp_maxprintjobs(snum) && (njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) { + if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) { DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per queue (%d).\n", njobs, lp_maxprintjobs(snum) )); release_print_db(pdb); @@ -1473,8 +1473,8 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE return (uint32)-1; } - /* Lock the database */ - if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob") == -1) { + /* Lock the database - only wait 20 seconds. */ + if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) { DEBUG(0,("print_job_start: failed to lock printing database %s\n", printername )); release_print_db(pdb); return (uint32)-1; -- cgit From 64876b9fb8b7ee3dd73d754070ae24ca36826350 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Oct 2002 01:28:42 +0000 Subject: SMB_ASSERT to check list terminates. Jeremy. (This used to be commit bf3b0ef56168aff9b1bd5760b595f8951d434861) --- source3/printing/printing.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 91851a37f8..7a527eebbf 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -156,6 +156,9 @@ static struct tdb_print_db *get_print_db_byname(const char *printername) pstring printdb_path; for (p = print_db_head, last_entry = print_db_head; p; p = p->next) { + /* Ensure the list terminates... JRA. */ + SMB_ASSERT(p->next != print_db_head); + if (p->tdb && strequal(p->printer_name, printername)) { DLIST_PROMOTE(print_db_head, p); p->ref_count++; -- cgit From 452baba8cb2f644b1f57161a2bfebf570efc596c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Oct 2002 20:09:51 +0000 Subject: Never do a ZERO_STRUCT on a structure in a linked list, it's dumb :-). Jeremy. (This used to be commit 20986489f4736820a4981c6aa0eecccf169f0170) --- source3/printing/printing.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 7a527eebbf..95d8915976 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -183,7 +183,9 @@ static struct tdb_print_db *get_print_db_byname(const char *printername) return NULL; } } - ZERO_STRUCTP(p); + p->tdb = NULL; + p->ref_count = 0; + memset(p->printer_name, '\0', sizeof(p->printer_name)); break; } if (p) { -- cgit From 6ce3e3b10c30946ebe6ce25b5be0ca03e9d5617f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 21 Oct 2002 20:11:12 +0000 Subject: removed the following parameters * postscript * printer driver * printer driver location * printer driver file also removed the get_a_printer_driver_9x_compatible() function (This used to be commit 743f2b8025effe57d8f075ff14a9357123c507a8) --- source3/printing/printing.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 95d8915976..afcf0ee720 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1572,17 +1572,6 @@ to open spool file %s.\n", pjob.filename)); release_print_db(pdb); - /* - * If the printer is marked as postscript output a leading - * file identifier to ensure the file is treated as a raw - * postscript file. - * This has a similar effect as CtrlD=0 in WIN.INI file. - * tim@fsg.com 09/06/94 - */ - if (lp_postscript(snum)) { - print_job_write(snum, jobid, "%!\n",3); - } - return jobid; fail: -- cgit From 0e7938ab5dc666d83a490210d35fee03f6483e49 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 26 Oct 2002 00:29:04 +0000 Subject: Fix problem where an fd would be left open for every printer queue. Jeremy. (This used to be commit e240c7a428659bce392d47f2eda16bdcf32863c1) --- source3/printing/printing.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index afcf0ee720..2d75699ac5 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -225,12 +225,35 @@ static struct tdb_print_db *get_print_db_byname(const char *printername) return p; } +/*************************************************************************** + Remove a reference count. +****************************************************************************/ + static void release_print_db( struct tdb_print_db *pdb) { pdb->ref_count--; SMB_ASSERT(pdb->ref_count >= 0); } +/*************************************************************************** + Close all open print db entries. +****************************************************************************/ + +static void close_all_print_db(void) +{ + struct tdb_print_db *p = NULL, *next_p = NULL; + + for (p = print_db_head; p; p = next_p) { + next_p = p->next; + + if (p->tdb) + tdb_close(p->tdb); + DLIST_REMOVE(print_db_head, p); + ZERO_STRUCTP(p); + SAFE_FREE(p); + } +} + /**************************************************************************** Initialise the printing backend. Called once at startup. Does not survive a fork @@ -264,6 +287,7 @@ BOOL print_backend_init(void) continue; if (tdb_lock_bystring(pdb->tdb, sversion, 0) == -1) { DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) )); + release_print_db(pdb); return False; } if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) { @@ -271,8 +295,11 @@ BOOL print_backend_init(void) tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION); } tdb_unlock_bystring(pdb->tdb, sversion); + release_print_db(pdb); } + close_all_print_db(); /* Don't leave any open. */ + /* select the appropriate printing interface... */ #ifdef HAVE_CUPS if (strcmp(lp_printcapname(), "cups") == 0) -- cgit From a63844e10e3e498c1c1e8457d50eb6ab1e6510cf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Oct 2002 23:41:00 +0000 Subject: Fix slowdown because of enumerating all print queues on every smbd startup. Jeremy. (This used to be commit 6efd17ef78ebcfed1130312fa019d674e4663a00) --- source3/printing/printing.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 2d75699ac5..2121fb20a3 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -154,6 +154,7 @@ static struct tdb_print_db *get_print_db_byname(const char *printername) struct tdb_print_db *p = NULL, *last_entry = NULL; int num_open = 0; pstring printdb_path; + BOOL done_become_root = False; for (p = print_db_head, last_entry = print_db_head; p; p = p->next) { /* Ensure the list terminates... JRA. */ @@ -209,9 +210,15 @@ static struct tdb_print_db *get_print_db_byname(const char *printername) pstrcat(printdb_path, printername); pstrcat(printdb_path, ".tdb"); - become_root(); + if (geteuid() != 0) { + become_root(); + done_become_root = True; + } + p->tdb = tdb_open_log(printdb_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); - unbecome_root(); + + if (done_become_root) + unbecome_root(); if (!p->tdb) { DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n", @@ -255,8 +262,7 @@ static void close_all_print_db(void) } /**************************************************************************** - Initialise the printing backend. Called once at startup. - Does not survive a fork + Initialise the printing backend. Called once at startup before the fork(). ****************************************************************************/ BOOL print_backend_init(void) @@ -316,16 +322,7 @@ BOOL print_backend_init(void) void printing_end(void) { - struct tdb_print_db *p; - - for (p = print_db_head; p; ) { - struct tdb_print_db *next_p = p->next; - if (p->tdb) - tdb_close(p->tdb); - DLIST_REMOVE(print_db_head, p); - SAFE_FREE(p); - p = next_p; - } + close_all_print_db(); /* Don't leave any open. */ } /**************************************************************************** -- cgit From 93042487882d8b2407541ad21d2e9bc2b59142e5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Nov 2002 02:15:35 +0000 Subject: Merge of scalable printing code fix... Needs testing. Jeremy. (This used to be commit d030df76439c72825d68410211e62090438cef54) --- source3/printing/printing.c | 248 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 2121fb20a3..6d4cc213a7 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1040,6 +1040,254 @@ static void print_queue_update(int snum) release_print_db(pdb); } +/**************************************************************************** + Fetch and clean the pid_t record list for all pids interested in notify + messages. data needs freeing on exit. +****************************************************************************/ + +#define NOTIFY_PID_LIST_KEY "NOTIFY_PID_LIST" + +static TDB_DATA get_printer_notify_pid_list(struct tdb_print_db *pdb) +{ + TDB_DATA data; + size_t i; + + ZERO_STRUCT(data); + + data = tdb_fetch_by_string( pdb->tdb, NOTIFY_PID_LIST_KEY ); + + if (!data.dptr) { + ZERO_STRUCT(data); + return data; + } + + if (data.dsize % 8) { + DEBUG(0,("get_pid_list: Size of record for printer %s not a multiple of 8 !\n", + pdb->printer_name )); + tdb_delete_by_string(pdb->tdb, NOTIFY_PID_LIST_KEY ); + ZERO_STRUCT(data); + return data; + } + + /* + * Weed out all dead entries. + */ + + for( i = 0; i < data.dsize; ) { + pid_t pid = (pid_t)IVAL(data.dptr, i); + + if (pid == sys_getpid()) + continue; + + /* Entry is dead if process doesn't exist or refcount is zero. */ + + if ((IVAL(data.dptr, i + 4) == 0) || !process_exists(pid)) { + + /* Refcount == zero is a logic error and should never happen. */ + if (IVAL(data.dptr, i + 4) == 0) { + DEBUG(0,("get_pid_list: Refcount == 0 for pid = %u printer %s !\n", + (unsigned int)pid, pdb->printer_name )); + } + + if (data.dsize - i > 8) + memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8); + data.dsize -= 8; + continue; + } + + i += 8; + } + + return data; +} + +/**************************************************************************** + Return a malloced list of pid_t's that are interested in getting update + messages on this print queue. Used in printing/notify to send the messages. +****************************************************************************/ + +BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t *p_num_pids, pid_t **pp_pid_list) +{ + struct tdb_print_db *pdb; + TDB_DATA data; + BOOL ret = True; + size_t i, num_pids; + pid_t *pid_list; + + *p_num_pids = 0; + *pp_pid_list = NULL; + + pdb = get_print_db_byname(printername); + if (!pdb) + return False; + + if (tdb_lock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { + DEBUG(0,("print_notify_pid_list: Failed to lock printer %s database\n", printername)); + release_print_db(pdb); + return False; + } + + data = get_printer_notify_pid_list( pdb ); + + if (!data.dptr) { + ret = True; + goto done; + } + + num_pids = data.dsize / 8; + + if ((pid_list = (pid_t *)talloc(mem_ctx, sizeof(pid_t) * num_pids)) == NULL) { + ret = False; + goto done; + } + + for( i = 0; i < data.dsize; i += 8) { + pid_t pid = (pid_t)IVAL(data.dptr, i); + pid_list[i] = pid; + } + + *pp_pid_list = pid_list; + *p_num_pids = num_pids; + + ret = True; + + done: + + tdb_unlock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY); + release_print_db(pdb); + SAFE_FREE(data.dptr); + return ret; +} + +/**************************************************************************** + Create/Update an entry in the print tdb that will allow us to send notify + updates only to interested smbd's. +****************************************************************************/ + +BOOL print_notify_register_pid(int snum) +{ + TDB_DATA data; + struct tdb_print_db *pdb; + const char *printername = lp_const_servicename(snum); + uint32 mypid = (uint32)sys_getpid(); + BOOL ret = False; + size_t i; + + pdb = get_print_db_byname(printername); + if (!pdb) + return False; + + if (tdb_lock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { + DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n", printername)); + release_print_db(pdb); + return False; + } + + data = get_printer_notify_pid_list( pdb ); + + /* Add ourselves and increase the refcount. */ + + for (i = 0; i < data.dsize; i += 8) { + if (IVAL(data.dptr,i) == mypid) { + uint32 new_refcount = IVAL(data.dptr, i+4) + 1; + SIVAL(data.dptr, i+4, new_refcount); + break; + } + } + + if (i == data.dsize) { + /* We weren't in the list. Realloc. */ + data.dptr = Realloc(data.dptr, data.dsize + 8); + if (!data.dptr) { + DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n", printername)); + goto done; + } + data.dsize += 8; + SIVAL(data.dptr,data.dsize - 8,mypid); + SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */ + } + + /* Store back the record. */ + if (tdb_store_by_string(pdb->tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) { + DEBUG(0,("print_notify_register_pid: Failed to update pid list for printer %s\n", printername)); + goto done; + } + + ret = True; + + done: + + tdb_unlock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY); + release_print_db(pdb); + SAFE_FREE(data.dptr); + return ret; +} + +/**************************************************************************** + Update an entry in the print tdb that will allow us to send notify + updates only to interested smbd's. +****************************************************************************/ + +BOOL print_notify_deregister_pid(int snum) +{ + TDB_DATA data; + struct tdb_print_db *pdb; + const char *printername = lp_const_servicename(snum); + uint32 mypid = (uint32)sys_getpid(); + size_t i; + BOOL ret = False; + + pdb = get_print_db_byname(printername); + if (!pdb) + return False; + + if (tdb_lock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { + DEBUG(0,("print_notify_register_pid: Failed to lock printer %s database\n", printername)); + release_print_db(pdb); + return False; + } + + data = get_printer_notify_pid_list( pdb ); + + /* Reduce refcount. Remove ourselves if zero. */ + + for (i = 0; i < data.dsize; ) { + if (IVAL(data.dptr,i) == mypid) { + uint32 refcount = IVAL(data.dptr, i+4); + + refcount--; + + if (refcount == 0) { + if (data.dsize - i > 8) + memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8); + data.dsize -= 8; + continue; + } + SIVAL(data.dptr, i+4, refcount); + } + + i += 8; + } + + if (data.dsize == 0) + SAFE_FREE(data.dptr); + + /* Store back the record. */ + if (tdb_store_by_string(pdb->tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) { + DEBUG(0,("print_notify_register_pid: Failed to update pid list for printer %s\n", printername)); + goto done; + } + + ret = True; + + done: + + tdb_unlock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY); + release_print_db(pdb); + SAFE_FREE(data.dptr); + return ret; +} + /**************************************************************************** Check if a jobid is valid. It is valid if it exists in the database. ****************************************************************************/ -- cgit From 72b7cfe4f14abfc553072bf341196ec98b0d40d6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Nov 2002 22:43:54 +0000 Subject: Fix crash bug with overwriting malloced memory. Jeremy. (This used to be commit 3228730c8311ec6507227f8936318b1d965c1228) --- source3/printing/printing.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 6d4cc213a7..71e09c793f 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1111,7 +1111,7 @@ BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t struct tdb_print_db *pdb; TDB_DATA data; BOOL ret = True; - size_t i, num_pids; + size_t i, num_pids, offset; pid_t *pid_list; *p_num_pids = 0; @@ -1141,10 +1141,8 @@ BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t goto done; } - for( i = 0; i < data.dsize; i += 8) { - pid_t pid = (pid_t)IVAL(data.dptr, i); - pid_list[i] = pid; - } + for( i = 0, offset = 0; offset < data.dsize; offset += 8, i++) + pid_list[i] = (pid_t)IVAL(data.dptr, offset); *pp_pid_list = pid_list; *p_num_pids = num_pids; -- cgit From 978214b18e4df64b215a8ecd339c46e1c358fb7c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 10 Nov 2002 03:00:43 +0000 Subject: Fix for scalable printing noticed by tpot. Don't loop infinately when holding a mutex.... :-). Jeremy. (This used to be commit 7e7b40e0fe1302ae416247c70d8d76bd82ec3474) --- source3/printing/printing.c | 49 +++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 13 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 71e09c793f..9bc4606ada 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1047,7 +1047,7 @@ static void print_queue_update(int snum) #define NOTIFY_PID_LIST_KEY "NOTIFY_PID_LIST" -static TDB_DATA get_printer_notify_pid_list(struct tdb_print_db *pdb) +static TDB_DATA get_printer_notify_pid_list(struct tdb_print_db *pdb, BOOL cleanlist) { TDB_DATA data; size_t i; @@ -1062,18 +1062,21 @@ static TDB_DATA get_printer_notify_pid_list(struct tdb_print_db *pdb) } if (data.dsize % 8) { - DEBUG(0,("get_pid_list: Size of record for printer %s not a multiple of 8 !\n", + DEBUG(0,("get_printer_notify_pid_list: Size of record for printer %s not a multiple of 8 !\n", pdb->printer_name )); tdb_delete_by_string(pdb->tdb, NOTIFY_PID_LIST_KEY ); ZERO_STRUCT(data); return data; } + if (!cleanlist) + return data; + /* * Weed out all dead entries. */ - for( i = 0; i < data.dsize; ) { + for( i = 0; i < data.dsize; i += 8) { pid_t pid = (pid_t)IVAL(data.dptr, i); if (pid == sys_getpid()) @@ -1081,21 +1084,18 @@ static TDB_DATA get_printer_notify_pid_list(struct tdb_print_db *pdb) /* Entry is dead if process doesn't exist or refcount is zero. */ - if ((IVAL(data.dptr, i + 4) == 0) || !process_exists(pid)) { + while ((i < data.dsize) && ((IVAL(data.dptr, i + 4) == 0) || !process_exists(pid))) { /* Refcount == zero is a logic error and should never happen. */ if (IVAL(data.dptr, i + 4) == 0) { - DEBUG(0,("get_pid_list: Refcount == 0 for pid = %u printer %s !\n", + DEBUG(0,("get_printer_notify_pid_list: Refcount == 0 for pid = %u printer %s !\n", (unsigned int)pid, pdb->printer_name )); } if (data.dsize - i > 8) memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8); data.dsize -= 8; - continue; } - - i += 8; } return data; @@ -1121,13 +1121,13 @@ BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t if (!pdb) return False; - if (tdb_lock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { + if (tdb_read_lock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { DEBUG(0,("print_notify_pid_list: Failed to lock printer %s database\n", printername)); release_print_db(pdb); return False; } - data = get_printer_notify_pid_list( pdb ); + data = get_printer_notify_pid_list( pdb, True ); if (!data.dptr) { ret = True; @@ -1151,7 +1151,7 @@ BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t done: - tdb_unlock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY); + tdb_read_unlock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY); release_print_db(pdb); SAFE_FREE(data.dptr); return ret; @@ -1181,7 +1181,7 @@ BOOL print_notify_register_pid(int snum) return False; } - data = get_printer_notify_pid_list( pdb ); + data = get_printer_notify_pid_list( pdb, True ); /* Add ourselves and increase the refcount. */ @@ -1245,7 +1245,7 @@ BOOL print_notify_deregister_pid(int snum) return False; } - data = get_printer_notify_pid_list( pdb ); + data = get_printer_notify_pid_list( pdb, True ); /* Reduce refcount. Remove ourselves if zero. */ @@ -1454,6 +1454,14 @@ BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("delete denied by security descriptor\n")); *errcode = WERR_ACCESS_DENIED; + + /* BEGIN_ADMIN_LOG */ + sys_adminlog( LOG_ERR, (char *) + "Permission denied-- user not allowed to delete, \ +pause, or resume print job. User name: %s. Printer name: %s.", + uidtoname(user->uid), PRINTERNAME(snum) ); + /* END_ADMIN_LOG */ + return False; } @@ -1511,6 +1519,14 @@ BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR * if (!is_owner(user, snum, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("pause denied by security descriptor\n")); + + /* BEGIN_ADMIN_LOG */ + sys_adminlog( LOG_ERR, (char *) + "Permission denied-- user not allowed to delete, \ +pause, or resume print job. User name: %s. Printer name: %s.", + uidtoname(user->uid), PRINTERNAME(snum) ); + /* END_ADMIN_LOG */ + *errcode = WERR_ACCESS_DENIED; return False; } @@ -1554,6 +1570,13 @@ BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("resume denied by security descriptor\n")); *errcode = WERR_ACCESS_DENIED; + + /* BEGIN_ADMIN_LOG */ + sys_adminlog( LOG_ERR, (char *) + "Permission denied-- user not allowed to delete, \ +pause, or resume print job. User name: %s. Printer name: %s.", + uidtoname(user->uid), PRINTERNAME(snum) ); + /* END_ADMIN_LOG */ return False; } -- cgit From fc2dc328e157d625d6fb4baa5d46cab2bd2a8a4f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 10 Nov 2002 22:24:00 +0000 Subject: First cut of fix for changenotify on a print server handle. Use the connections tdb with an snum of -1 and a special printername. Jeremy. (This used to be commit 06b04380078ad840768a2c5a803f02669f54bc82) --- source3/printing/printing.c | 123 ++++++++++++++++++++++++++++---------------- 1 file changed, 80 insertions(+), 43 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 9bc4606ada..cc4d588e2d 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1046,15 +1046,16 @@ static void print_queue_update(int snum) ****************************************************************************/ #define NOTIFY_PID_LIST_KEY "NOTIFY_PID_LIST" +#define PRINT_SERVER_ENTRY_NAME "___PRINT_SERVER_ENTRY___" -static TDB_DATA get_printer_notify_pid_list(struct tdb_print_db *pdb, BOOL cleanlist) +static TDB_DATA get_printer_notify_pid_list(TDB_CONTEXT *tdb, const char *printer_name, BOOL cleanlist) { TDB_DATA data; size_t i; ZERO_STRUCT(data); - data = tdb_fetch_by_string( pdb->tdb, NOTIFY_PID_LIST_KEY ); + data = tdb_fetch_by_string( tdb, NOTIFY_PID_LIST_KEY ); if (!data.dptr) { ZERO_STRUCT(data); @@ -1062,9 +1063,8 @@ static TDB_DATA get_printer_notify_pid_list(struct tdb_print_db *pdb, BOOL clean } if (data.dsize % 8) { - DEBUG(0,("get_printer_notify_pid_list: Size of record for printer %s not a multiple of 8 !\n", - pdb->printer_name )); - tdb_delete_by_string(pdb->tdb, NOTIFY_PID_LIST_KEY ); + DEBUG(0,("get_printer_notify_pid_list: Size of record for printer %s not a multiple of 8 !\n", printer_name )); + tdb_delete_by_string(tdb, NOTIFY_PID_LIST_KEY ); ZERO_STRUCT(data); return data; } @@ -1089,7 +1089,7 @@ static TDB_DATA get_printer_notify_pid_list(struct tdb_print_db *pdb, BOOL clean /* Refcount == zero is a logic error and should never happen. */ if (IVAL(data.dptr, i + 4) == 0) { DEBUG(0,("get_printer_notify_pid_list: Refcount == 0 for pid = %u printer %s !\n", - (unsigned int)pid, pdb->printer_name )); + (unsigned int)pid, printer_name )); } if (data.dsize - i > 8) @@ -1108,7 +1108,8 @@ static TDB_DATA get_printer_notify_pid_list(struct tdb_print_db *pdb, BOOL clean BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t *p_num_pids, pid_t **pp_pid_list) { - struct tdb_print_db *pdb; + struct tdb_print_db *pdb = NULL; + TDB_CONTEXT *tdb = NULL; TDB_DATA data; BOOL ret = True; size_t i, num_pids, offset; @@ -1117,17 +1118,25 @@ BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t *p_num_pids = 0; *pp_pid_list = NULL; - pdb = get_print_db_byname(printername); - if (!pdb) - return False; + if (strequal(printername, PRINT_SERVER_ENTRY_NAME)) { + pdb = NULL; + tdb = conn_tdb_ctx(); + } else { + pdb = get_print_db_byname(printername); + if (!pdb) + return False; + tdb = pdb->tdb; + } - if (tdb_read_lock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { - DEBUG(0,("print_notify_pid_list: Failed to lock printer %s database\n", printername)); - release_print_db(pdb); + if (tdb_read_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { + DEBUG(0,("print_notify_pid_list: Failed to lock printer %s database\n", + printername)); + if (pdb) + release_print_db(pdb); return False; } - data = get_printer_notify_pid_list( pdb, True ); + data = get_printer_notify_pid_list( tdb, printername, True ); if (!data.dptr) { ret = True; @@ -1151,8 +1160,9 @@ BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t done: - tdb_read_unlock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY); - release_print_db(pdb); + tdb_read_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY); + if (pdb) + release_print_db(pdb); SAFE_FREE(data.dptr); return ret; } @@ -1165,23 +1175,34 @@ BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t BOOL print_notify_register_pid(int snum) { TDB_DATA data; - struct tdb_print_db *pdb; - const char *printername = lp_const_servicename(snum); + struct tdb_print_db *pdb = NULL; + TDB_CONTEXT *tdb = NULL; + const char *printername; uint32 mypid = (uint32)sys_getpid(); BOOL ret = False; size_t i; - pdb = get_print_db_byname(printername); - if (!pdb) - return False; + if (snum != -1) { + printername = lp_const_servicename(snum); + pdb = get_print_db_byname(printername); + if (!pdb) + return False; + tdb = pdb->tdb; + } else { + printername = PRINT_SERVER_ENTRY_NAME; + pdb = NULL; + tdb = conn_tdb_ctx(); + } - if (tdb_lock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { - DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n", printername)); - release_print_db(pdb); + if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { + DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n", + printername)); + if (pdb) + release_print_db(pdb); return False; } - data = get_printer_notify_pid_list( pdb, True ); + data = get_printer_notify_pid_list( tdb, printername, True ); /* Add ourselves and increase the refcount. */ @@ -1197,7 +1218,8 @@ BOOL print_notify_register_pid(int snum) /* We weren't in the list. Realloc. */ data.dptr = Realloc(data.dptr, data.dsize + 8); if (!data.dptr) { - DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n", printername)); + DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n", + printername)); goto done; } data.dsize += 8; @@ -1206,8 +1228,9 @@ BOOL print_notify_register_pid(int snum) } /* Store back the record. */ - if (tdb_store_by_string(pdb->tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) { - DEBUG(0,("print_notify_register_pid: Failed to update pid list for printer %s\n", printername)); + if (tdb_store_by_string(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) { + DEBUG(0,("print_notify_register_pid: Failed to update pid \ +list for printer %s\n", printername)); goto done; } @@ -1215,8 +1238,9 @@ BOOL print_notify_register_pid(int snum) done: - tdb_unlock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY); - release_print_db(pdb); + tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY); + if (pdb) + release_print_db(pdb); SAFE_FREE(data.dptr); return ret; } @@ -1229,23 +1253,34 @@ BOOL print_notify_register_pid(int snum) BOOL print_notify_deregister_pid(int snum) { TDB_DATA data; - struct tdb_print_db *pdb; - const char *printername = lp_const_servicename(snum); + struct tdb_print_db *pdb = NULL; + TDB_CONTEXT *tdb = NULL; + const char *printername; uint32 mypid = (uint32)sys_getpid(); size_t i; BOOL ret = False; - pdb = get_print_db_byname(printername); - if (!pdb) - return False; + if (snum != -1) { + printername = lp_const_servicename(snum); + pdb = get_print_db_byname(printername); + if (!pdb) + return False; + tdb = pdb->tdb; + } else { + printername = PRINT_SERVER_ENTRY_NAME; + pdb = NULL; + tdb = conn_tdb_ctx(); + } - if (tdb_lock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { - DEBUG(0,("print_notify_register_pid: Failed to lock printer %s database\n", printername)); - release_print_db(pdb); + if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { + DEBUG(0,("print_notify_register_pid: Failed to lock \ +printer %s database\n", printername)); + if (pdb) + release_print_db(pdb); return False; } - data = get_printer_notify_pid_list( pdb, True ); + data = get_printer_notify_pid_list( tdb, printername, True ); /* Reduce refcount. Remove ourselves if zero. */ @@ -1271,8 +1306,9 @@ BOOL print_notify_deregister_pid(int snum) SAFE_FREE(data.dptr); /* Store back the record. */ - if (tdb_store_by_string(pdb->tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) { - DEBUG(0,("print_notify_register_pid: Failed to update pid list for printer %s\n", printername)); + if (tdb_store_by_string(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) { + DEBUG(0,("print_notify_register_pid: Failed to update pid \ +list for printer %s\n", printername)); goto done; } @@ -1280,8 +1316,9 @@ BOOL print_notify_deregister_pid(int snum) done: - tdb_unlock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY); - release_print_db(pdb); + tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY); + if (pdb) + release_print_db(pdb); SAFE_FREE(data.dptr); return ret; } -- cgit From de474974ea25df7738dd175126e3f1de0df47ea6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 23 Nov 2002 02:52:36 +0000 Subject: Lots of fixes for error paths where tdb_fetch() data need freeing. Found via a post from Arcady Chernyak . Jeremy. (This used to be commit 5d5762d1787db4392d2dff16024097c638b2d494) --- source3/printing/printing.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index cc4d588e2d..a8f9097255 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -71,6 +71,7 @@ uint16 pjobid_to_rap(int snum, uint32 jobid) SAFE_FREE(data.dptr); return rap_jobid; } + SAFE_FREE(data.dptr); /* Not found - create and store mapping. */ rap_jobid = ++next_rap_jobid; if (rap_jobid == 0) @@ -99,6 +100,7 @@ BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid) SAFE_FREE(data.dptr); return True; } + SAFE_FREE(data.dptr); return False; } @@ -117,8 +119,10 @@ static void rap_jobid_delete(int snum, uint32 jobid) key.dptr = (char *)&jinfo; key.dsize = sizeof(jinfo); data = tdb_fetch(rap_tdb, key); - if (!data.dptr || (data.dsize != sizeof(uint16))) + if (!data.dptr || (data.dsize != sizeof(uint16))) { + SAFE_FREE(data.dptr); return; + } memcpy(&rap_jobid, data.dptr, sizeof(uint16)); SAFE_FREE(data.dptr); @@ -404,8 +408,10 @@ static struct printjob *print_job_find(int snum, uint32 jobid) ZERO_STRUCT( pjob ); - if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) + if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) { + SAFE_FREE(ret.dptr); return NULL; + } SAFE_FREE(ret.dptr); return &pjob; @@ -580,8 +586,7 @@ static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob) len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len); - if (buflen != len) - { + if (buflen != len) { char *tb; tb = (char *)Realloc(buf, len); @@ -593,8 +598,7 @@ static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob) buf = tb; newlen = len; } - } - while ( buflen != len ); + } while ( buflen != len ); /* Store new data */ @@ -833,8 +837,10 @@ static pid_t get_updating_pid(fstring printer_name) data = tdb_fetch(pdb->tdb, key); release_print_db(pdb); - if (!data.dptr || data.dsize != sizeof(pid_t)) + if (!data.dptr || data.dsize != sizeof(pid_t)) { + SAFE_FREE(data.dptr); return (pid_t)-1; + } memcpy(&updating_pid, data.dptr, sizeof(pid_t)); SAFE_FREE(data.dptr); @@ -1065,6 +1071,7 @@ static TDB_DATA get_printer_notify_pid_list(TDB_CONTEXT *tdb, const char *printe if (data.dsize % 8) { DEBUG(0,("get_printer_notify_pid_list: Size of record for printer %s not a multiple of 8 !\n", printer_name )); tdb_delete_by_string(tdb, NOTIFY_PID_LIST_KEY ); + SAFE_FREE(data.dptr); ZERO_STRUCT(data); return data; } -- cgit From afc5f1aefbddf68252f4b9a0a2cee2d5601d8057 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 26 Nov 2002 00:46:31 +0000 Subject: [print notify fixes from APP_HEAD] * fixing change notify on print server handle * adding change notify support into smbcontrol for sending comment changes, etc... All part of CR 1159/1160 (This used to be commit f1062e79de8a3046c6e3f22b3d1a4819afe6809b) --- source3/printing/printing.c | 314 +++++--------------------------------------- 1 file changed, 35 insertions(+), 279 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index a8f9097255..a6b5e5cb83 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -136,135 +136,6 @@ static pid_t local_pid; static int get_queue_status(int, print_status_struct *); -/* There can be this many printing tdb's open, plus any locked ones. */ -#define MAX_PRINT_DBS_OPEN 1 - -struct tdb_print_db { - struct tdb_print_db *next, *prev; - TDB_CONTEXT *tdb; - int ref_count; - fstring printer_name; -}; - -static struct tdb_print_db *print_db_head; - -/**************************************************************************** - Function to find or create the printer specific job tdb given a printername. - Limits the number of tdb's open to MAX_PRINT_DBS_OPEN. -****************************************************************************/ - -static struct tdb_print_db *get_print_db_byname(const char *printername) -{ - struct tdb_print_db *p = NULL, *last_entry = NULL; - int num_open = 0; - pstring printdb_path; - BOOL done_become_root = False; - - for (p = print_db_head, last_entry = print_db_head; p; p = p->next) { - /* Ensure the list terminates... JRA. */ - SMB_ASSERT(p->next != print_db_head); - - if (p->tdb && strequal(p->printer_name, printername)) { - DLIST_PROMOTE(print_db_head, p); - p->ref_count++; - return p; - } - num_open++; - last_entry = p; - } - - /* Not found. */ - if (num_open >= MAX_PRINT_DBS_OPEN) { - /* Try and recycle the last entry. */ - DLIST_PROMOTE(print_db_head, last_entry); - - for (p = print_db_head; p; p = p->next) { - if (p->ref_count) - continue; - if (p->tdb) { - if (tdb_close(print_db_head->tdb)) { - DEBUG(0,("get_print_db: Failed to close tdb for printer %s\n", - print_db_head->printer_name )); - return NULL; - } - } - p->tdb = NULL; - p->ref_count = 0; - memset(p->printer_name, '\0', sizeof(p->printer_name)); - break; - } - if (p) { - DLIST_PROMOTE(print_db_head, p); - p = print_db_head; - } - } - - if (!p) { - /* Create one. */ - p = (struct tdb_print_db *)malloc(sizeof(struct tdb_print_db)); - if (!p) { - DEBUG(0,("get_print_db: malloc fail !\n")); - return NULL; - } - ZERO_STRUCTP(p); - DLIST_ADD(print_db_head, p); - } - - pstrcpy(printdb_path, lock_path("printing/")); - pstrcat(printdb_path, printername); - pstrcat(printdb_path, ".tdb"); - - if (geteuid() != 0) { - become_root(); - done_become_root = True; - } - - p->tdb = tdb_open_log(printdb_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); - - if (done_become_root) - unbecome_root(); - - if (!p->tdb) { - DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n", - printdb_path )); - DLIST_REMOVE(print_db_head, p); - SAFE_FREE(p); - return NULL; - } - fstrcpy(p->printer_name, printername); - p->ref_count++; - return p; -} - -/*************************************************************************** - Remove a reference count. -****************************************************************************/ - -static void release_print_db( struct tdb_print_db *pdb) -{ - pdb->ref_count--; - SMB_ASSERT(pdb->ref_count >= 0); -} - -/*************************************************************************** - Close all open print db entries. -****************************************************************************/ - -static void close_all_print_db(void) -{ - struct tdb_print_db *p = NULL, *next_p = NULL; - - for (p = print_db_head; p; p = next_p) { - next_p = p->next; - - if (p->tdb) - tdb_close(p->tdb); - DLIST_REMOVE(print_db_head, p); - ZERO_STRUCTP(p); - SAFE_FREE(p); - } -} - /**************************************************************************** Initialise the printing backend. Called once at startup before the fork(). ****************************************************************************/ @@ -1046,134 +917,6 @@ static void print_queue_update(int snum) release_print_db(pdb); } -/**************************************************************************** - Fetch and clean the pid_t record list for all pids interested in notify - messages. data needs freeing on exit. -****************************************************************************/ - -#define NOTIFY_PID_LIST_KEY "NOTIFY_PID_LIST" -#define PRINT_SERVER_ENTRY_NAME "___PRINT_SERVER_ENTRY___" - -static TDB_DATA get_printer_notify_pid_list(TDB_CONTEXT *tdb, const char *printer_name, BOOL cleanlist) -{ - TDB_DATA data; - size_t i; - - ZERO_STRUCT(data); - - data = tdb_fetch_by_string( tdb, NOTIFY_PID_LIST_KEY ); - - if (!data.dptr) { - ZERO_STRUCT(data); - return data; - } - - if (data.dsize % 8) { - DEBUG(0,("get_printer_notify_pid_list: Size of record for printer %s not a multiple of 8 !\n", printer_name )); - tdb_delete_by_string(tdb, NOTIFY_PID_LIST_KEY ); - SAFE_FREE(data.dptr); - ZERO_STRUCT(data); - return data; - } - - if (!cleanlist) - return data; - - /* - * Weed out all dead entries. - */ - - for( i = 0; i < data.dsize; i += 8) { - pid_t pid = (pid_t)IVAL(data.dptr, i); - - if (pid == sys_getpid()) - continue; - - /* Entry is dead if process doesn't exist or refcount is zero. */ - - while ((i < data.dsize) && ((IVAL(data.dptr, i + 4) == 0) || !process_exists(pid))) { - - /* Refcount == zero is a logic error and should never happen. */ - if (IVAL(data.dptr, i + 4) == 0) { - DEBUG(0,("get_printer_notify_pid_list: Refcount == 0 for pid = %u printer %s !\n", - (unsigned int)pid, printer_name )); - } - - if (data.dsize - i > 8) - memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8); - data.dsize -= 8; - } - } - - return data; -} - -/**************************************************************************** - Return a malloced list of pid_t's that are interested in getting update - messages on this print queue. Used in printing/notify to send the messages. -****************************************************************************/ - -BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t *p_num_pids, pid_t **pp_pid_list) -{ - struct tdb_print_db *pdb = NULL; - TDB_CONTEXT *tdb = NULL; - TDB_DATA data; - BOOL ret = True; - size_t i, num_pids, offset; - pid_t *pid_list; - - *p_num_pids = 0; - *pp_pid_list = NULL; - - if (strequal(printername, PRINT_SERVER_ENTRY_NAME)) { - pdb = NULL; - tdb = conn_tdb_ctx(); - } else { - pdb = get_print_db_byname(printername); - if (!pdb) - return False; - tdb = pdb->tdb; - } - - if (tdb_read_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { - DEBUG(0,("print_notify_pid_list: Failed to lock printer %s database\n", - printername)); - if (pdb) - release_print_db(pdb); - return False; - } - - data = get_printer_notify_pid_list( tdb, printername, True ); - - if (!data.dptr) { - ret = True; - goto done; - } - - num_pids = data.dsize / 8; - - if ((pid_list = (pid_t *)talloc(mem_ctx, sizeof(pid_t) * num_pids)) == NULL) { - ret = False; - goto done; - } - - for( i = 0, offset = 0; offset < data.dsize; offset += 8, i++) - pid_list[i] = (pid_t)IVAL(data.dptr, offset); - - *pp_pid_list = pid_list; - *p_num_pids = num_pids; - - ret = True; - - done: - - tdb_read_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY); - if (pdb) - release_print_db(pdb); - SAFE_FREE(data.dptr); - return ret; -} - /**************************************************************************** Create/Update an entry in the print tdb that will allow us to send notify updates only to interested smbd's. @@ -1189,16 +932,29 @@ BOOL print_notify_register_pid(int snum) BOOL ret = False; size_t i; - if (snum != -1) { + /* if (snum == -1), then the change notify request was + on a print server handle and we need to register on + all print queus */ + + if (snum == -1) + { + int num_services = lp_numservices(); + int idx; + + for ( idx=0; idxtdb; - } else { - printername = PRINT_SERVER_ENTRY_NAME; - pdb = NULL; - tdb = conn_tdb_ctx(); } if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { @@ -1267,16 +1023,28 @@ BOOL print_notify_deregister_pid(int snum) size_t i; BOOL ret = False; - if (snum != -1) { + /* if ( snum == -1 ), we are deregister a print server handle + which means to deregister on all print queues */ + + if (snum == -1) + { + int num_services = lp_numservices(); + int idx; + + for ( idx=0; idxtdb; - } else { - printername = PRINT_SERVER_ENTRY_NAME; - pdb = NULL; - tdb = conn_tdb_ctx(); } if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { @@ -2197,18 +1965,6 @@ int print_queue_status(int snum, return tstruct.qcount; } -/**************************************************************************** - Turn a queue name into a snum. -****************************************************************************/ - -int print_queue_snum(const char *qname) -{ - int snum = lp_servicenumber(qname); - if (snum == -1 || !lp_print_ok(snum)) - return -1; - return snum; -} - /**************************************************************************** Pause a queue. ****************************************************************************/ -- cgit From 00a20ce45f11e62470e60a8d5fcacc6b0b1f90a2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 5 Dec 2002 04:00:16 +0000 Subject: The element in fsp->print_job should be a RAP jobid, not a uint32 RPC jobid. This was causing Win9x client "set name" calls to fail. Still need one cleanup fix to finish. Jeremy. (This used to be commit 6c23d2030ab8dddff4c849903c529f0012b94027) --- source3/printing/printing.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index a6b5e5cb83..6c70b3deae 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -53,6 +53,8 @@ uint16 pjobid_to_rap(int snum, uint32 jobid) TDB_DATA data, key; char jinfo[8]; + DEBUG(10,("pjobid_to_rap: called.\n")); + if (!rap_tdb) { /* Create the in-memory tdb. */ rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644); @@ -80,13 +82,18 @@ uint16 pjobid_to_rap(int snum, uint32 jobid) data.dsize = sizeof(rap_jobid); tdb_store(rap_tdb, key, data, TDB_REPLACE); tdb_store(rap_tdb, data, key, TDB_REPLACE); + + DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n", + (unsigned int)jobid, + (unsigned int)rap_jobid)); return rap_jobid; } BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid) { TDB_DATA data, key; - char jinfo[8]; + + DEBUG(10,("rap_to_pjobid called.\n")); if (!rap_tdb) return False; @@ -94,12 +101,18 @@ BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid) key.dptr = (char *)&rap_jobid; key.dsize = sizeof(rap_jobid); data = tdb_fetch(rap_tdb, key); - if (data.dptr && data.dsize == sizeof(jinfo)) { - *psnum = IVAL(&jinfo,0); - *pjobid = IVAL(&jinfo,4); + if (data.dptr && data.dsize == 8) { + *psnum = IVAL(data.dptr,0); + *pjobid = IVAL(data.dptr,4); + DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n", + (unsigned int)*pjobid, + (unsigned int)rap_jobid)); SAFE_FREE(data.dptr); return True; } + + DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n", + (unsigned int)rap_jobid)); SAFE_FREE(data.dptr); return False; } @@ -110,6 +123,8 @@ static void rap_jobid_delete(int snum, uint32 jobid) uint16 rap_jobid; char jinfo[8]; + DEBUG(10,("rap_jobid_delete: called.\n")); + if (!rap_tdb) return; @@ -120,10 +135,15 @@ static void rap_jobid_delete(int snum, uint32 jobid) key.dsize = sizeof(jinfo); data = tdb_fetch(rap_tdb, key); if (!data.dptr || (data.dsize != sizeof(uint16))) { + DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n", + (unsigned int)jobid )); SAFE_FREE(data.dptr); return; } + DEBUG(10,("rap_jobid_delete: deleting jobid %u\n", + (unsigned int)jobid )); + memcpy(&rap_jobid, data.dptr, sizeof(uint16)); SAFE_FREE(data.dptr); data.dptr = (char *)&rap_jobid; -- cgit From 3999a905e93a0070132888804cafa114bc7d613d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 5 Dec 2002 22:32:15 +0000 Subject: Fix debugs for rap mapping. Delete job on map fail. Jeremy. (This used to be commit 6eb27e4f0dea6027ba9e041348f066c947e751c6) --- source3/printing/printing.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 6c70b3deae..cde1646107 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -71,6 +71,9 @@ uint16 pjobid_to_rap(int snum, uint32 jobid) if (data.dptr && data.dsize == sizeof(uint16)) { memcpy(&rap_jobid, data.dptr, sizeof(uint16)); SAFE_FREE(data.dptr); + DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n", + (unsigned int)jobid, + (unsigned int)rap_jobid)); return rap_jobid; } SAFE_FREE(data.dptr); @@ -83,7 +86,7 @@ uint16 pjobid_to_rap(int snum, uint32 jobid) tdb_store(rap_tdb, key, data, TDB_REPLACE); tdb_store(rap_tdb, data, key, TDB_REPLACE); - DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n", + DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n", (unsigned int)jobid, (unsigned int)rap_jobid)); return rap_jobid; @@ -516,7 +519,7 @@ done: Remove a job structure from the database. ****************************************************************************/ -static void pjob_delete(int snum, uint32 jobid) +void pjob_delete(int snum, uint32 jobid) { struct printjob *pjob = print_job_find(snum, jobid); uint32 job_status = 0; -- cgit From 634c54310c92c48dd4eceec602e230a021bdcfc5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 3 Jan 2003 08:28:12 +0000 Subject: Merge from HEAD - make Samba compile with -Wwrite-strings without additional warnings. (Adds a lot of const). Andrew Bartlett (This used to be commit 3a7458f9472432ef12c43008414925fd1ce8ea0c) --- source3/printing/printing.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index cde1646107..711d99f394 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -165,7 +165,7 @@ static int get_queue_status(int, print_status_struct *); BOOL print_backend_init(void) { - char *sversion = "INFO/version"; + const char *sversion = "INFO/version"; pstring printing_path; int services = lp_numservices(); int snum; @@ -1291,10 +1291,10 @@ BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode = WERR_ACCESS_DENIED; /* BEGIN_ADMIN_LOG */ - sys_adminlog( LOG_ERR, (char *) - "Permission denied-- user not allowed to delete, \ + sys_adminlog( LOG_ERR, + "Permission denied-- user not allowed to delete, \ pause, or resume print job. User name: %s. Printer name: %s.", - uidtoname(user->uid), PRINTERNAME(snum) ); + uidtoname(user->uid), PRINTERNAME(snum) ); /* END_ADMIN_LOG */ return False; @@ -1356,7 +1356,7 @@ BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR * DEBUG(3, ("pause denied by security descriptor\n")); /* BEGIN_ADMIN_LOG */ - sys_adminlog( LOG_ERR, (char *) + sys_adminlog( LOG_ERR, "Permission denied-- user not allowed to delete, \ pause, or resume print job. User name: %s. Printer name: %s.", uidtoname(user->uid), PRINTERNAME(snum) ); @@ -1407,7 +1407,7 @@ BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode = WERR_ACCESS_DENIED; /* BEGIN_ADMIN_LOG */ - sys_adminlog( LOG_ERR, (char *) + sys_adminlog( LOG_ERR, "Permission denied-- user not allowed to delete, \ pause, or resume print job. User name: %s. Printer name: %s.", uidtoname(user->uid), PRINTERNAME(snum) ); -- cgit From 545087c060ee9bf3d2a092f4d99c79426e4a0ecb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Jan 2003 01:21:59 +0000 Subject: Don't delete jobs subitted after the lpq time. Jeremy. (This used to be commit 6cb9f6ccb1fab3ff597f52c931561d52de09e84a) --- source3/printing/printing.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 711d99f394..be42664b56 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -610,6 +610,7 @@ static void print_unix_job(int snum, print_queue_struct *q) struct traverse_struct { print_queue_struct *queue; int qcount, snum, maxcount, total_jobs; + time_t lpq_time; }; /**************************************************************************** @@ -674,17 +675,15 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void completed, so delete the database entry. */ if (i == ts->qcount) { - time_t cur_t = time(NULL); /* A race can occur between the time a job is spooled and when it appears in the lpq output. This happens when the job is added to printing.tdb when another smbd running print_queue_update() has completed a lpq and is currently traversing the printing tdb and deleting jobs. - A workaround is to not delete the job if it has been - submitted less than lp_lpqcachetime() seconds ago. */ + Don't delete the job if it was submitted after the lpq_time. */ - if ((cur_t - pjob.starttime) > lp_lpqcachetime()) + if (pjob.starttime < ts->lpq_time) pjob_delete(ts->snum, jobid); else ts->total_jobs++; @@ -906,6 +905,7 @@ static void print_queue_update(int snum) tstruct.qcount = qcount; tstruct.snum = snum; tstruct.total_jobs = 0; + tstruct.lpq_time = time(NULL); tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct); -- cgit From 071af8f007efc20c23959d140a87cc09363aae83 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 11 Jan 2003 02:38:36 +0000 Subject: [merge] make sure to update print queue cache during timeout_processing() to send notify events; CR 1491 (This used to be commit f8a915b14d63e4fdb99235053eeb896ef9492068) --- source3/printing/printing.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index be42664b56..a770e7a09a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1907,6 +1907,7 @@ static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2) /**************************************************************************** Get a printer queue listing. + set queue = NULL and status = NULL if you just want to update the cache ****************************************************************************/ int print_queue_status(int snum, @@ -1917,18 +1918,26 @@ int print_queue_status(int snum, struct traverse_count_struct tsc; fstring keystr; TDB_DATA data, key; - const char *printername = lp_const_servicename(snum); - struct tdb_print_db *pdb = get_print_db_byname(printername); + const char *printername; + struct tdb_print_db *pdb; + + /* make sure the database is up to date */ + + if (print_cache_expired(snum)) + print_queue_update(snum); + + /* return if we are done */ + + if ( !queue || !status ) + return 0; *queue = NULL; + printername = lp_const_servicename(snum); + pdb = get_print_db_byname(printername); if (!pdb) return 0; - /* make sure the database is up to date */ - if (print_cache_expired(snum)) - print_queue_update(snum); - /* * Fetch the queue status. We must do this first, as there may * be no jobs in the queue. -- cgit From 27b7e51a3cc619f879655a3230611457ac43b9e7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 14 Jan 2003 08:53:59 +0000 Subject: Merge from HEAD: - fstring/pstring mixups - the detection code that found them (disabled) - a bit of whitespace - a static Andrew Bartlett (This used to be commit 9b70fa868e7d9481f584c83fc4046174e1dedfd9) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index a770e7a09a..5f2594f07a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1934,7 +1934,7 @@ int print_queue_status(int snum, *queue = NULL; printername = lp_const_servicename(snum); pdb = get_print_db_byname(printername); - + if (!pdb) return 0; -- cgit From 920287bf6b6950abfac53e6430954aee7e76bd15 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 30 Jan 2003 23:26:49 +0000 Subject: More scalable print tdb fixes. Jeremy. (This used to be commit 7ace900b335e83b447cab63137968806a8e2f4d3) --- source3/printing/printing.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 5f2594f07a..cfa9ddbe61 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -913,7 +913,8 @@ static void print_queue_update(int snum) tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs); - if( qcount != get_queue_status(snum, &old_status)) + get_queue_status(snum, &old_status); + if (old_status.qcount != qcount) DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n", old_status.qcount, qcount, printer_name )); @@ -1504,21 +1505,26 @@ static int get_queue_status(int snum, print_status_struct *status) TDB_DATA data, key; const char *printername = lp_const_servicename(snum); struct tdb_print_db *pdb = get_print_db_byname(printername); + int len; + if (!pdb) return 0; - ZERO_STRUCTP(status); - slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername); - key.dptr = keystr; - key.dsize = strlen(keystr); - data = tdb_fetch(pdb->tdb, key); - release_print_db(pdb); - if (data.dptr) { - if (data.dsize == sizeof(print_status_struct)) - memcpy(status, data.dptr, sizeof(print_status_struct)); - SAFE_FREE(data.dptr); + if (status) { + ZERO_STRUCTP(status); + slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername); + key.dptr = keystr; + key.dsize = strlen(keystr); + data = tdb_fetch(pdb->tdb, key); + if (data.dptr) { + if (data.dsize == sizeof(print_status_struct)) + memcpy(status, data.dptr, sizeof(print_status_struct)); + SAFE_FREE(data.dptr); + } } - return status->qcount; + len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs"); + release_print_db(pdb); + return (len == -1 ? 0 : len); } /**************************************************************************** @@ -1537,8 +1543,10 @@ int print_queue_length(int snum, print_status_struct *pstatus) /* also fetch the queue status */ memset(&status, 0, sizeof(status)); len = get_queue_status(snum, &status); + if (pstatus) *pstatus = status; + return len; } @@ -1619,7 +1627,8 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE if (next_jobid == -1) next_jobid = 1; - for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) { + njobs = 0; + for (njobs = 0, jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid), njobs++) { if (!print_job_exists(snum, jobid)) break; } @@ -1627,6 +1636,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE if (jobid == next_jobid) { DEBUG(3, ("print_job_start: jobid (%d)==next_jobid(%d).\n", jobid, next_jobid )); + tdb_store_int32(pdb->tdb, "INFO/total_jobs", njobs); jobid = -1; goto fail; } -- cgit From 42edbfe9180386fbe3e1a578771fb90bf7d0f2cd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 4 Feb 2003 23:52:49 +0000 Subject: Hold the lock for a much shorter time when allocating a new jobid. Jeremy. (This used to be commit 62e274abbb0ceec90c97c022fa14d96bdf574121) --- source3/printing/printing.c | 121 ++++++++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 54 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index cfa9ddbe61..a46fff0de2 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1550,6 +1550,70 @@ int print_queue_length(int snum, print_status_struct *pstatus) return len; } +/*************************************************************************** + Allocate a jobid. Hold the lock for as short a time as possible. +***************************************************************************/ + +static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *printername, uint32 *pjobid) +{ + int i; + uint32 jobid; + + *pjobid = (uint32)-1; + + for (i = 0; i < 3; i++) { + /* Lock the database - only wait 20 seconds. */ + if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) { + DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", printername )); + return False; + } + + if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) { + if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) { + DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n", + printername )); + return False; + } + jobid = 0; + } + + jobid = NEXT_JOBID(jobid); + + if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) { + DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n")); + tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); + return False; + } + + /* We've finished with the INFO/nextjob lock. */ + tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); + + if (!print_job_exists(snum, jobid)) + break; + } + + if (i > 2) { + DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n", + printername )); + return False; + } + + /* Store a dummy placeholder. */ + { + TDB_DATA dum; + dum.dptr = NULL; + dum.dsize = 0; + if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) { + DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n", + jobid )); + return False; + } + } + + *pjobid = jobid; + return True; +} + /*************************************************************************** Start spooling a job - return the jobid. ***************************************************************************/ @@ -1559,12 +1623,10 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE uint32 jobid; char *path; struct printjob pjob; - int next_jobid; user_struct *vuser; - int njobs = 0; const char *printername = lp_const_servicename(snum); struct tdb_print_db *pdb = get_print_db_byname(printername); - BOOL pdb_locked = False; + int njobs; errno = 0; @@ -1614,55 +1676,8 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE return (uint32)-1; } - /* Lock the database - only wait 20 seconds. */ - if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) { - DEBUG(0,("print_job_start: failed to lock printing database %s\n", printername )); - release_print_db(pdb); - return (uint32)-1; - } - - pdb_locked = True; - - next_jobid = tdb_fetch_int32(pdb->tdb, "INFO/nextjob"); - if (next_jobid == -1) - next_jobid = 1; - - njobs = 0; - for (njobs = 0, jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid), njobs++) { - if (!print_job_exists(snum, jobid)) - break; - } - - if (jobid == next_jobid) { - DEBUG(3, ("print_job_start: jobid (%d)==next_jobid(%d).\n", - jobid, next_jobid )); - tdb_store_int32(pdb->tdb, "INFO/total_jobs", njobs); - jobid = -1; + if (!allocate_print_jobid(pdb, snum, printername, &jobid)) goto fail; - } - - /* Store a dummy placeholder. This must be quick as we have the lock. */ - { - TDB_DATA dum; - dum.dptr = NULL; - dum.dsize = 0; - if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) { - DEBUG(3, ("print_job_start: jobid (%d) failed to store placeholder.\n", - jobid )); - jobid = -1; - goto fail; - } - } - - if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) { - DEBUG(3, ("print_job_start: failed to store INFO/nextjob.\n")); - jobid = -1; - goto fail; - } - - /* We've finished with the INFO/nextjob lock. */ - tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); - pdb_locked = False; /* create the database entry */ @@ -1716,12 +1731,10 @@ to open spool file %s.\n", pjob.filename)); if (jobid != -1) pjob_delete(snum, jobid); - if (pdb_locked) - tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); release_print_db(pdb); DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) )); - return -1; + return (uint32)-1; } /**************************************************************************** -- cgit From 4703248a8e7287b738fa82edfd91fb2b13e7c222 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 8 Feb 2003 01:04:43 +0000 Subject: Ensure we return NOSPACE if we can't fast allocate a print job. Jeremy. (This used to be commit 82cf8aa74794649fb16c336011ca48d549d6abb8) --- source3/printing/printing.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index a46fff0de2..3bf992ad69 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1595,6 +1595,8 @@ static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char if (i > 2) { DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n", printername )); + /* Probably full... */ + errno = ENOSPC; return False; } @@ -1669,13 +1671,16 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE /* Insure the maximum queue size is not violated */ if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) { - DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per queue (%d).\n", - njobs, lp_maxprintjobs(snum) )); + DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n", + printername, njobs, lp_maxprintjobs(snum) )); release_print_db(pdb); errno = ENOSPC; return (uint32)-1; } + DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n", + printername, njobs, lp_maxprintjobs(snum) )); + if (!allocate_print_jobid(pdb, snum, printername, &jobid)) goto fail; -- cgit From 647d65e08be07c87393b10cd95bf569978fc2a42 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 19 Feb 2003 01:43:33 +0000 Subject: Bit of a hack job to prevent smbprn.XXX jobs appearing in the queue if the jobid is below the UNIX_JOB_START number. Jeremy. (This used to be commit 7ec1c8869d3df9af77ff95942beba34f56a06b73) --- source3/printing/printing.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 3bf992ad69..c9612ab3a9 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -579,11 +579,13 @@ static uint32 print_parse_jobid(char *fname) List a unix job in the print database. ****************************************************************************/ -static void print_unix_job(int snum, print_queue_struct *q) +static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid) { - uint32 jobid = q->job + UNIX_JOB_START; struct printjob pj, *old_pj; + if (jobid == (uint32)-1) + jobid = q->job + UNIX_JOB_START; + /* Preserve the timestamp on an existing unix print job */ old_pj = print_job_find(snum, jobid); @@ -597,11 +599,14 @@ static void print_unix_job(int snum, print_queue_struct *q) pj.status = q->status; pj.size = q->size; pj.spooled = True; - pj.smbjob = False; - fstrcpy(pj.filename, ""); - fstrcpy(pj.jobname, q->fs_file); - fstrcpy(pj.user, q->fs_user); - fstrcpy(pj.queuename, lp_const_servicename(snum)); + pj.smbjob = (old_pj != NULL ? True : False); + fstrcpy(pj.filename, old_pj ? old_pj->filename : ""); + if (jobid < UNIX_JOB_START) + fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document"); + else + fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file); + fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user); + fstrcpy(pj.queuename, old_pj ? old_pj->queuename : lp_const_servicename(snum)); pjob_store(snum, jobid, &pj); } @@ -879,7 +884,7 @@ static void print_queue_update(int snum) if (jobid == (uint32)-1) { /* assume its a unix print job */ - print_unix_job(snum, &queue[i]); + print_unix_job(snum, &queue[i], jobid); continue; } @@ -889,7 +894,7 @@ static void print_queue_update(int snum) /* err, somethings wrong. Probably smbd was restarted with jobs in the queue. All we can do is treat them like unix jobs. Pity. */ - print_unix_job(snum, &queue[i]); + print_unix_job(snum, &queue[i], jobid); continue; } -- cgit From 0bf15545dd1ee7d0fd8b16a5523e85343765a123 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 1 Mar 2003 00:49:00 +0000 Subject: Ensure added jobs increment total_jobs. Jeremy. (This used to be commit a75d9fc4e1c26e3ae15a97508f6f1cf69fe54148) --- source3/printing/printing.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index c9612ab3a9..26ea52e35a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -916,6 +916,9 @@ static void print_queue_update(int snum) SAFE_FREE(tstruct.queue); + DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n", + printer_name, tstruct.total_jobs )); + tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs); get_queue_status(snum, &old_status); @@ -1733,6 +1736,9 @@ to open spool file %s.\n", pjob.filename)); pjob_store(snum, jobid, &pjob); + /* Ensure we keep a rough count of the number of total jobs... */ + tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1); + release_print_db(pdb); return jobid; -- cgit From 3be18a1fba5b008e55a4497470165de62aa15054 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 20 Mar 2003 00:52:37 +0000 Subject: lib/messages.c: Check return from chainlock before modifying message queue. Apply the job returned limit across all requests for job queues. Jeremy. (This used to be commit bf795b684e608f82db822e0759e7b69afd451b65) --- source3/printing/printing.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 26ea52e35a..99578975ca 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1959,6 +1959,7 @@ int print_queue_status(int snum, TDB_DATA data, key; const char *printername; struct tdb_print_db *pdb; + int max_reported_jobs = lp_max_reported_jobs(snum); /* make sure the database is up to date */ @@ -2033,6 +2034,10 @@ int print_queue_status(int snum, QSORT_CAST(printjob_comp)); *queue = tstruct.queue; + + if (max_reported_jobs && tstruct.qcount > max_reported_jobs) + tstruct.qcount = max_reported_jobs; + return tstruct.qcount; } -- cgit From 67df8fb3003a25d274d805c8db6af8eaf30a9d24 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 21 Mar 2003 22:00:21 +0000 Subject: Merge of new appliance-head scalable printing fixes. Jeremy. (This used to be commit 331e621b580f997592892be0226fb452c67ae9e1) --- source3/printing/printing.c | 429 +++++++++++++++++++++++++++++--------------- 1 file changed, 287 insertions(+), 142 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 99578975ca..da29eab9f2 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -246,20 +246,22 @@ int unpack_pjob( char* buf, int buflen, struct printjob *pjob ) { int len = 0; int used; - + uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus; + uint32 pjsize, pjpage_count, pjspooled, pjsmbjob; + if ( !buf || !pjob ) return -1; len += tdb_unpack(buf+len, buflen-len, "dddddddddffff", - &pjob->pid, - &pjob->sysjob, - &pjob->fd, - &pjob->starttime, - &pjob->status, - &pjob->size, - &pjob->page_count, - &pjob->spooled, - &pjob->smbjob, + &pjpid, + &pjsysjob, + &pjfd, + &pjstarttime, + &pjstatus, + &pjsize, + &pjpage_count, + &pjspooled, + &pjsmbjob, pjob->filename, pjob->jobname, pjob->user, @@ -272,6 +274,16 @@ int unpack_pjob( char* buf, int buflen, struct printjob *pjob ) return -1; len += used; + + pjob->pid = pjpid; + pjob->sysjob = pjsysjob; + pjob->fd = pjfd; + pjob->starttime = pjstarttime; + pjob->status = pjstatus; + pjob->size = pjsize; + pjob->page_count = pjpage_count; + pjob->spooled = pjspooled; + pjob->smbjob = pjsmbjob; return len; @@ -464,15 +476,15 @@ static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob) len = 0; buflen = newlen; len += tdb_pack(buf+len, buflen-len, "dddddddddffff", - pjob->pid, - pjob->sysjob, - pjob->fd, - pjob->starttime, - pjob->status, - pjob->size, - pjob->page_count, - pjob->spooled, - pjob->smbjob, + (uint32)pjob->pid, + (uint32)pjob->sysjob, + (uint32)pjob->fd, + (uint32)pjob->starttime, + (uint32)pjob->status, + (uint32)pjob->size, + (uint32)pjob->page_count, + (uint32)pjob->spooled, + (uint32)pjob->smbjob, pjob->filename, pjob->jobname, pjob->user, @@ -782,6 +794,84 @@ static void set_updating_pid(const fstring printer_name, BOOL delete) release_print_db(pdb); } +/**************************************************************************** + Sort print jobs by submittal time. +****************************************************************************/ + +static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2) +{ + /* Silly cases */ + + if (!j1 && !j2) + return 0; + if (!j1) + return -1; + if (!j2) + return 1; + + /* Sort on job start time */ + + if (j1->time == j2->time) + return 0; + return (j1->time > j2->time) ? 1 : -1; +} + +/**************************************************************************** + Store the sorted queue representation for later portmon retrieval. +****************************************************************************/ + +static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts) +{ + TDB_DATA data, key; + int max_reported_jobs = lp_max_reported_jobs(pts->snum); + print_queue_struct *queue = pts->queue; + size_t len; + size_t i; + uint qcount; + + if (max_reported_jobs < pts->qcount) + pts->qcount = max_reported_jobs; + qcount = pts->qcount; + + /* Work out the size. */ + data.dsize = 0; + data.dsize += tdb_pack(NULL, 0, NULL, "d", qcount); + + for (i = 0; i < pts->qcount; i++) { + data.dsize += tdb_pack(NULL, 0, NULL, "ddddddff", + (uint32)queue[i].job, + (uint32)queue[i].size, + (uint32)queue[i].page_count, + (uint32)queue[i].status, + (uint32)queue[i].priority, + (uint32)queue[i].time, + queue[i].fs_user, + queue[i].fs_file); + } + + if ((data.dptr = malloc(data.dsize)) == NULL) + return; + + len = 0; + len += tdb_pack(data.dptr + len, data.dsize - len, NULL, "d", qcount); + for (i = 0; i < pts->qcount; i++) { + len += tdb_pack(data.dptr + len, data.dsize - len, NULL, "ddddddff", + (uint32)queue[i].job, + (uint32)queue[i].size, + (uint32)queue[i].page_count, + (uint32)queue[i].status, + (uint32)queue[i].priority, + (uint32)queue[i].time, + queue[i].fs_user, + queue[i].fs_file); + } + + key.dptr = "INFO/linear_queue_array"; + key.dsize = strlen(key.dptr); + tdb_store(pdb->tdb, key, data, TDB_REPLACE); + return; +} + /**************************************************************************** Update the internal database from the system print queue for a queue. ****************************************************************************/ @@ -869,6 +959,12 @@ static void print_queue_update(int snum) DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ? "s" : "", printer_name)); + /* Sort the queue by submission time otherwise they are displayed + in hash order. */ + + qsort(queue, qcount, sizeof(print_queue_struct), + QSORT_CAST(printjob_comp)); + /* any job in the internal database that is marked as spooled and doesn't exist in the system queue is considered finished @@ -914,6 +1010,9 @@ static void print_queue_update(int snum) tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct); + /* Store the linearised queue, max jobs only. */ + store_queue_struct(pdb, &tstruct); + SAFE_FREE(tstruct.queue); DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n", @@ -1216,6 +1315,58 @@ BOOL print_job_set_name(int snum, uint32 jobid, char *name) return pjob_store(snum, jobid, pjob); } +/*************************************************************************** + Remove a jobid from the 'jobs changed' list. +***************************************************************************/ + +static BOOL remove_from_jobs_changed(int snum, uint32 jobid) +{ + const char *printername = lp_const_servicename(snum); + struct tdb_print_db *pdb = get_print_db_byname(printername); + TDB_DATA data, key; + size_t job_count, i; + BOOL ret = False; + BOOL gotlock = False; + + key.dptr = "INFO/jobs_changed"; + key.dsize = strlen(key.dptr); + ZERO_STRUCT(data); + + if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1) + goto out; + + gotlock = True; + + data = tdb_fetch(pdb->tdb, key); + + if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) + goto out; + + job_count = data.dsize / 4; + for (i = 0; i < job_count; i++) { + uint32 ch_jobid; + + memcpy(&ch_jobid, data.dptr + (i*4), 4); + if (ch_jobid == jobid) { + if (i < job_count -1 ) + memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 ); + data.dsize -= 4; + if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1) + goto out; + break; + } + } + + ret = True; + out: + + if (gotlock) + tdb_chainunlock(pdb->tdb, key); + SAFE_FREE(data.dptr); + release_print_db(pdb); + return ret; +} + /**************************************************************************** Delete a print job - don't update queue. ****************************************************************************/ @@ -1249,6 +1400,8 @@ static BOOL print_job_delete1(int snum, uint32 jobid) if (pjob->spooled && pjob->sysjob != -1) result = (*(current_printif->job_delete))(snum, pjob); + else + remove_from_jobs_changed(snum, jobid); /* Delete the tdb entry if the delete suceeded or the job hasn't been spooled. */ @@ -1624,6 +1777,22 @@ static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char return True; } +/*************************************************************************** + Append a jobid to the 'jobs changed' list. +***************************************************************************/ + +static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid) +{ + TDB_DATA data, key; + + key.dptr = "INFO/jobs_changed"; + key.dsize = strlen(key.dptr); + data.dptr = (char *)&jobid; + data.dsize = 4; + + return (tdb_append(pdb->tdb, key, data) == 0); +} + /*************************************************************************** Start spooling a job - return the jobid. ***************************************************************************/ @@ -1736,6 +1905,9 @@ to open spool file %s.\n", pjob.filename)); pjob_store(snum, jobid, &pjob); + /* Update the 'jobs changed' entry used by print_queue_status. */ + add_to_jobs_changed(pdb, jobid); + /* Ensure we keep a rough count of the number of total jobs... */ tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1); @@ -1826,6 +1998,7 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) pjob->spooled = True; pjob->status = LPQ_QUEUED; pjob_store(snum, jobid, pjob); + remove_from_jobs_changed(snum, jobid); /* make sure the database is up to date */ if (print_cache_expired(snum)) @@ -1839,109 +2012,116 @@ fail: /* Still need to add proper error return propagation! 010122:JRR */ unlink(pjob->filename); pjob_delete(snum, jobid); + remove_from_jobs_changed(snum, jobid); return False; } /**************************************************************************** - Utility fn to enumerate the print queue. + Get a snapshot of jobs in the system without traversing. ****************************************************************************/ -static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) +static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue) { - struct traverse_struct *ts = (struct traverse_struct *)state; - struct printjob pjob; - int i; - uint32 jobid; - - /* sanity checks */ - - if ( key.dsize != sizeof(jobid) ) - return 0; - - memcpy(&jobid, key.dptr, sizeof(jobid)); - - if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 ) - return 0; - free_nt_devicemode( &pjob.nt_devmode ); - - /* maybe it isn't for this queue */ - if (ts->snum != lp_servicenumber(pjob.queuename)) - return 0; + TDB_DATA data, key, cgdata; + print_queue_struct *queue = NULL; + uint32 qcount = 0; + uint32 extra_count = 0; + int total_count = 0; + uint32 i; + int max_reported_jobs = lp_max_reported_jobs(snum); + BOOL ret = False; - if (ts->qcount >= ts->maxcount) - return 0; + *pcount = 0; + *ppqueue = NULL; - i = ts->qcount; + ZERO_STRUCT(data); + ZERO_STRUCT(cgdata); + key.dptr = "INFO/linear_queue_array"; + key.dsize = strlen(key.dptr); - ts->queue[i].job = jobid; - ts->queue[i].size = pjob.size; - ts->queue[i].page_count = pjob.page_count; - ts->queue[i].status = pjob.status; - ts->queue[i].priority = 1; - ts->queue[i].time = pjob.starttime; - fstrcpy(ts->queue[i].fs_user, pjob.user); - fstrcpy(ts->queue[i].fs_file, pjob.jobname); + /* Get the stored queue data. */ + data = tdb_fetch(pdb->tdb, key); - ts->qcount++; + if (data.dptr == NULL || data.dsize < 4) + qcount = 0; + else + memcpy(&qcount, data.dptr, 4); - return 0; -} + /* Get the changed jobs list. */ + key.dptr = "INFO/jobs_changed"; + key.dsize = strlen(key.dptr); -struct traverse_count_struct { - int snum, count; -}; + cgdata = tdb_fetch(pdb->tdb, key); + if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0)) + extra_count = cgdata.dsize/4; -/**************************************************************************** - Utility fn to count the number of entries in the print queue. -****************************************************************************/ + /* Allocate the queue size. */ + if (qcount == 0 && extra_count == 0) + goto out; + + if ((queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(qcount + extra_count))) == NULL) + goto out; + + /* Retrieve the linearised queue data. */ + for( i = 0; i < qcount; i++) { + size_t len = 0; + uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime; + len += tdb_unpack(data.dptr + 4 + len, data.dsize - len, NULL, "ddddddff", + &qjob, + &qsize, + &qpage_count, + &qstatus, + &qpriority, + &qtime, + queue[i].fs_user, + queue[i].fs_file); + queue[i].job = qjob; + queue[i].size = qsize; + queue[i].page_count = qpage_count; + queue[i].status = qstatus; + queue[i].priority = qpriority; + queue[i].time = qtime; + } + + total_count = qcount; + + /* Add in the changed jobids. */ + for( i = 0; i < extra_count; i++) { + uint32 jobid; + struct printjob *pjob; + + memcpy(&jobid, &cgdata.dptr[i*4], 4); + pjob = print_job_find(snum, jobid); + if (!pjob) + continue; -static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) -{ - struct traverse_count_struct *ts = (struct traverse_count_struct *)state; - struct printjob pjob; - uint32 jobid; + queue[total_count].job = jobid; + queue[total_count].size = pjob->size; + queue[total_count].page_count = pjob->page_count; + queue[total_count].status = pjob->status; + queue[total_count].priority = 1; + fstrcpy(queue[total_count].fs_user, pjob->user); + fstrcpy(queue[total_count].fs_file, pjob->jobname); + } - /* sanity checks */ - - if ( key.dsize != sizeof(jobid) ) - return 0; - - memcpy(&jobid, key.dptr, sizeof(jobid)); - - if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 ) - return 0; - - free_nt_devicemode( &pjob.nt_devmode ); + /* Sort the queue by submission time otherwise they are displayed + in hash order. */ - /* maybe it isn't for this queue - this cannot happen with the tdb/printer code. JRA */ - if (ts->snum != lp_servicenumber(pjob.queuename)) - return 0; + qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp)); - ts->count++; + if (max_reported_jobs && total_count > max_reported_jobs) + total_count = max_reported_jobs; - return 0; -} + *ppqueue = queue; + *pcount = total_count; -/**************************************************************************** - Sort print jobs by submittal time. -****************************************************************************/ - -static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2) -{ - /* Silly cases */ - - if (!j1 && !j2) - return 0; - if (!j1) - return -1; - if (!j2) - return 1; + ret = True; - /* Sort on job start time */ + out: - if (j1->time == j2->time) - return 0; - return (j1->time > j2->time) ? 1 : -1; + SAFE_FREE(data.dptr); + SAFE_FREE(cgdata.dptr); + return ret; } /**************************************************************************** @@ -1950,16 +2130,14 @@ static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2) ****************************************************************************/ int print_queue_status(int snum, - print_queue_struct **queue, + print_queue_struct **ppqueue, print_status_struct *status) { - struct traverse_struct tstruct; - struct traverse_count_struct tsc; fstring keystr; TDB_DATA data, key; const char *printername; struct tdb_print_db *pdb; - int max_reported_jobs = lp_max_reported_jobs(snum); + int count = 0; /* make sure the database is up to date */ @@ -1967,11 +2145,10 @@ int print_queue_status(int snum, print_queue_update(snum); /* return if we are done */ - - if ( !queue || !status ) + if ( !ppqueue || !status ) return 0; - *queue = NULL; + *ppqueue = NULL; printername = lp_const_servicename(snum); pdb = get_print_db_byname(printername); @@ -1982,6 +2159,7 @@ int print_queue_status(int snum, * Fetch the queue status. We must do this first, as there may * be no jobs in the queue. */ + ZERO_STRUCTP(status); slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername); key.dptr = keystr; @@ -1998,47 +2176,14 @@ int print_queue_status(int snum, * Now, fetch the print queue information. We first count the number * of entries, and then only retrieve the queue if necessary. */ - tsc.count = 0; - tsc.snum = snum; - - tdb_traverse(pdb->tdb, traverse_count_fn_queue, (void *)&tsc); - if (tsc.count == 0) { + if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) { release_print_db(pdb); return 0; } - /* Allocate the queue size. */ - if ((tstruct.queue = (print_queue_struct *) - malloc(sizeof(print_queue_struct)*tsc.count)) == NULL) { - release_print_db(pdb); - return 0; - } - - /* - * Fill in the queue. - * We need maxcount as the queue size may have changed between - * the two calls to tdb_traverse. - */ - tstruct.qcount = 0; - tstruct.maxcount = tsc.count; - tstruct.snum = snum; - - tdb_traverse(pdb->tdb, traverse_fn_queue, (void *)&tstruct); release_print_db(pdb); - - /* Sort the queue by submission time otherwise they are displayed - in hash order. */ - - qsort(tstruct.queue, tstruct.qcount, sizeof(print_queue_struct), - QSORT_CAST(printjob_comp)); - - *queue = tstruct.queue; - - if (max_reported_jobs && tstruct.qcount > max_reported_jobs) - tstruct.qcount = max_reported_jobs; - - return tstruct.qcount; + return count; } /**************************************************************************** -- cgit From 5ab2abd707b3a81b8c28813ebe2fd0b2ae1112a7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 26 Mar 2003 19:35:37 +0000 Subject: Fix extra NULL arg added during app-head merge. Jeremy. (This used to be commit b2ef052adad01c37f0fd4b9b82a16a9989d57082) --- source3/printing/printing.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index da29eab9f2..b6c4969761 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -838,7 +838,7 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct data.dsize += tdb_pack(NULL, 0, NULL, "d", qcount); for (i = 0; i < pts->qcount; i++) { - data.dsize += tdb_pack(NULL, 0, NULL, "ddddddff", + data.dsize += tdb_pack(NULL, 0, "ddddddff", (uint32)queue[i].job, (uint32)queue[i].size, (uint32)queue[i].page_count, @@ -853,9 +853,9 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct return; len = 0; - len += tdb_pack(data.dptr + len, data.dsize - len, NULL, "d", qcount); + len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount); for (i = 0; i < pts->qcount; i++) { - len += tdb_pack(data.dptr + len, data.dsize - len, NULL, "ddddddff", + len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff", (uint32)queue[i].job, (uint32)queue[i].size, (uint32)queue[i].page_count, -- cgit From a9b39993fa366a6f0ab26deafac61947a9e8e1cc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 2 Apr 2003 02:31:51 +0000 Subject: Subtle changes to message handling after ENUMJOBS. Jeremy. (This used to be commit e5e83544dc0acf812bfa5ea17960b5a6be954ca1) --- source3/printing/printing.c | 94 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 84 insertions(+), 10 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index b6c4969761..39fb48ae17 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -24,6 +24,7 @@ /* Current printer interface */ static struct printif *current_printif = &generic_printif; +static BOOL remove_from_jobs_changed(int snum, uint32 jobid); /* the printing backend revolves around a tdb database that stores the @@ -663,9 +664,11 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void if (jobid == u_jobid) break; } - if (i == ts->qcount) + if (i == ts->qcount) { + DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n", + (unsigned int)jobid )); pjob_delete(ts->snum, jobid); - else + } else ts->total_jobs++; return 0; } @@ -675,9 +678,11 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void /* if a job is not spooled and the process doesn't exist then kill it. This cleans up after smbd deaths */ - if (!process_exists(pjob.pid)) + if (!process_exists(pjob.pid)) { + DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n", + (unsigned int)jobid, (unsigned int)pjob.pid )); pjob_delete(ts->snum, jobid); - else + } else ts->total_jobs++; return 0; } @@ -700,9 +705,13 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void is currently traversing the printing tdb and deleting jobs. Don't delete the job if it was submitted after the lpq_time. */ - if (pjob.starttime < ts->lpq_time) + if (pjob.starttime < ts->lpq_time) { + DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n", + (unsigned int)jobid, + (unsigned int)pjob.starttime, + (unsigned int)ts->lpq_time )); pjob_delete(ts->snum, jobid); - else + } else ts->total_jobs++; } else @@ -872,6 +881,37 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct return; } +static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb) +{ + TDB_DATA data, key; + + key.dptr = "INFO/jobs_changed"; + key.dsize = strlen(key.dptr); + ZERO_STRUCT(data); + + data = tdb_fetch(pdb->tdb, key); + if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) { + SAFE_FREE(data.dptr); + ZERO_STRUCT(data); + } + + return data; +} + +static void check_job_changed(int snum, TDB_DATA data, uint32 jobid) +{ + unsigned int i; + unsigned int job_count = data.dsize / 4; + + for (i = 0; i < job_count; i++) { + uint32 ch_jobid; + + memcpy(&ch_jobid, data.dptr + (i*4), 4); + if (ch_jobid == jobid) + remove_from_jobs_changed(snum, jobid); + } +} + /**************************************************************************** Update the internal database from the system print queue for a queue. ****************************************************************************/ @@ -886,6 +926,7 @@ static void print_queue_update(int snum) struct traverse_struct tstruct; fstring keystr, printer_name, cachestr; TDB_DATA data, key; + TDB_DATA jcdata; struct tdb_print_db *pdb; fstrcpy(printer_name, lp_const_servicename(snum)); @@ -975,6 +1016,9 @@ static void print_queue_update(int snum) fill in any system job numbers as we go */ + + jcdata = get_jobs_changed_data(pdb); + for (i=0; isysjob = queue[i].job; pjob->status = queue[i].status; - pjob_store(snum, jobid, pjob); + check_job_changed(snum, jcdata, jobid); } + SAFE_FREE(jcdata.dptr); + /* now delete any queued entries that don't appear in the system queue */ tstruct.queue = queue; @@ -1364,6 +1410,10 @@ static BOOL remove_from_jobs_changed(int snum, uint32 jobid) tdb_chainunlock(pdb->tdb, key); SAFE_FREE(data.dptr); release_print_db(pdb); + if (ret) + DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid )); + else + DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid )); return ret; } @@ -1406,8 +1456,18 @@ static BOOL print_job_delete1(int snum, uint32 jobid) /* Delete the tdb entry if the delete suceeded or the job hasn't been spooled. */ - if (result == 0) + if (result == 0) { + const char *printername = lp_const_servicename(snum); + struct tdb_print_db *pdb = get_print_db_byname(printername); + int njobs = 1; + + if (!pdb) + return False; pjob_delete(snum, jobid); + /* Ensure we keep a rough count of the number of total jobs... */ + tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1); + release_print_db(pdb); + } return (result == 0); } @@ -1790,6 +1850,8 @@ static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid) data.dptr = (char *)&jobid; data.dsize = 4; + DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid )); + return (tdb_append(pdb->tdb, key, data) == 0); } @@ -1998,7 +2060,6 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) pjob->spooled = True; pjob->status = LPQ_QUEUED; pjob_store(snum, jobid, pjob); - remove_from_jobs_changed(snum, jobid); /* make sure the database is up to date */ if (print_cache_expired(snum)) @@ -2031,6 +2092,10 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun int max_reported_jobs = lp_max_reported_jobs(snum); BOOL ret = False; + /* make sure the database is up to date */ + if (print_cache_expired(snum)) + print_queue_update(snum); + *pcount = 0; *ppqueue = NULL; @@ -2055,6 +2120,8 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0)) extra_count = cgdata.dsize/4; + DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count)); + /* Allocate the queue size. */ if (qcount == 0 && extra_count == 0) goto out; @@ -2091,9 +2158,13 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun struct printjob *pjob; memcpy(&jobid, &cgdata.dptr[i*4], 4); + DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid)); pjob = print_job_find(snum, jobid); - if (!pjob) + if (!pjob) { + DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid)); + remove_from_jobs_changed(snum, jobid); continue; + } queue[total_count].job = jobid; queue[total_count].size = pjob->size; @@ -2102,6 +2173,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun queue[total_count].priority = 1; fstrcpy(queue[total_count].fs_user, pjob->user); fstrcpy(queue[total_count].fs_file, pjob->jobname); + total_count++; } /* Sort the queue by submission time otherwise they are displayed @@ -2109,6 +2181,8 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp)); + DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count)); + if (max_reported_jobs && total_count > max_reported_jobs) total_count = max_reported_jobs; -- cgit From 7991cf1e52f777c728f00809d5afcfccefe16e09 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Apr 2003 01:02:20 +0000 Subject: Fix the new storage code to correctly convert from system queue info to pjob info. Ensure we retrieve more than one job from the storage code. Jeremy. (This used to be commit 59be98401c5a8b419597c18acbe996b469bbe89a) --- source3/printing/printing.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 39fb48ae17..e788645306 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -713,9 +713,20 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void pjob_delete(ts->snum, jobid); } else ts->total_jobs++; + return 0; } - else - ts->total_jobs++; + + /* Save the pjob attributes we will store. */ + ts->queue[i].job = jobid; + ts->queue[i].size = pjob.size; + ts->queue[i].page_count = pjob.page_count; + ts->queue[i].status = pjob.status; + ts->queue[i].priority = 1; + ts->queue[i].time = pjob.starttime; + fstrcpy(ts->queue[i].fs_user, pjob.user); + fstrcpy(ts->queue[i].fs_file, pjob.jobname); + + ts->total_jobs++; return 0; } @@ -2088,6 +2099,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun uint32 qcount = 0; uint32 extra_count = 0; int total_count = 0; + size_t len = 0; uint32 i; int max_reported_jobs = lp_max_reported_jobs(snum); BOOL ret = False; @@ -2130,8 +2142,8 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun goto out; /* Retrieve the linearised queue data. */ + len = 0; for( i = 0; i < qcount; i++) { - size_t len = 0; uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime; len += tdb_unpack(data.dptr + 4 + len, data.dsize - len, NULL, "ddddddff", &qjob, -- cgit From 6e0bd81f44ff17d45cc375a379fef956c310500d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 10 Apr 2003 19:34:52 +0000 Subject: Grr. Get rid of one of the extra NULL's that crept in from app-head. Spotted by Andrew Esh. Jeremy. (This used to be commit 9e6e6c3f50844cf4322d6dd193c4e24b76bae9ba) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index e788645306..79cab3d9fa 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -855,7 +855,7 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct /* Work out the size. */ data.dsize = 0; - data.dsize += tdb_pack(NULL, 0, NULL, "d", qcount); + data.dsize += tdb_pack(NULL, 0, "d", qcount); for (i = 0; i < pts->qcount; i++) { data.dsize += tdb_pack(NULL, 0, "ddddddff", -- cgit From cf00ce3e87a0d714fb38f709f9635b8a045866e3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Apr 2003 08:46:03 +0000 Subject: Fix mem leak. Spotted by tpot (thanks Tim). Jeremy. (This used to be commit 03a1f46e3448913cc21ed89aafaa22818d4026d0) --- source3/printing/printing.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 79cab3d9fa..add690fb8b 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -889,6 +889,7 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct key.dptr = "INFO/linear_queue_array"; key.dsize = strlen(key.dptr); tdb_store(pdb->tdb, key, data, TDB_REPLACE); + SAFE_FREE(data.dptr); return; } -- cgit From fb5a006c0971694ff4da3601c04f304234d27ae7 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 1 Jul 2003 05:45:16 +0000 Subject: fix typos in log messages and comments. (This used to be commit fd24183ec30688f3699e466bd4d908b24918e328) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index add690fb8b..79f8571e31 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1465,7 +1465,7 @@ static BOOL print_job_delete1(int snum, uint32 jobid) else remove_from_jobs_changed(snum, jobid); - /* Delete the tdb entry if the delete suceeded or the job hasn't + /* Delete the tdb entry if the delete succeeded or the job hasn't been spooled. */ if (result == 0) { -- cgit From c674e411c7e7a5d56ef455dab5ecbea2eaa4883e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 10 Jul 2003 20:37:01 +0000 Subject: i guess i'm the only one this ever annyoed... fix the confusion when we tdb_lock_bystring() but we retrieve an entry using tdb_fetch_by_string. It's now always tdb.*bystring() (This used to be commit 66359531b89368939f0e8f584a45844b5f2f99e7) --- source3/printing/printing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 79f8571e31..1a7066f906 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1180,7 +1180,7 @@ BOOL print_notify_register_pid(int snum) } /* Store back the record. */ - if (tdb_store_by_string(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) { + if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) { DEBUG(0,("print_notify_register_pid: Failed to update pid \ list for printer %s\n", printername)); goto done; @@ -1270,7 +1270,7 @@ printer %s database\n", printername)); SAFE_FREE(data.dptr); /* Store back the record. */ - if (tdb_store_by_string(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) { + if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) { DEBUG(0,("print_notify_register_pid: Failed to update pid \ list for printer %s\n", printername)); goto done; -- cgit From 8ce241cb80943c7f1af20529e23b8215678d1071 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 11 Sep 2003 17:01:26 +0000 Subject: fix unitiailized timestamp where merging print_jobs and lpq listing (This used to be commit 8382cd6796992e55bf10f381089cb740052a0bca) --- source3/printing/printing.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 1a7066f906..1a878afb92 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -2184,6 +2184,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun queue[total_count].page_count = pjob->page_count; queue[total_count].status = pjob->status; queue[total_count].priority = 1; + queue[total_count].time = pjob->starttime; fstrcpy(queue[total_count].fs_user, pjob->user); fstrcpy(queue[total_count].fs_file, pjob->jobname); total_count++; -- cgit From e1c468477c1781b8d4d1539489ce577b71cd1a70 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 12 Nov 2003 01:51:10 +0000 Subject: a small include file rearrangement that doesn't affect normal compilation, but that allows Samba3 to take advantage of pre-compiled headers in gcc if available. (This used to be commit b3e024ce1da7c7e24fcacd8a2964dd2e4562ba39) --- source3/printing/printing.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 1a878afb92..56020f7838 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "printing.h" /* Current printer interface */ -- cgit From 281e293331f20d9341ebaf555f10ef339952048c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 13 Nov 2003 20:15:17 +0000 Subject: * Fix from SATOH Fumiyasu for bug 660 (failing to view print jobs) by only enforce the 'max reported print jobs' parameter when it is non-zero. * Fixed bug 338 by making sure that data values are written out when we are marshalling an EnumPrinterDataEx() reply. This probably fixes other bugs reported against point-n-print feature in 3.0.0 (This used to be commit fd98af75d655449a677360f6991da5caabc88b4d) --- source3/printing/printing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 56020f7838..ad17213c2d 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -850,7 +850,7 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct size_t i; uint qcount; - if (max_reported_jobs < pts->qcount) + if (max_reported_jobs && (max_reported_jobs < pts->qcount)) pts->qcount = max_reported_jobs; qcount = pts->qcount; @@ -2147,7 +2147,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun len = 0; for( i = 0; i < qcount; i++) { uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime; - len += tdb_unpack(data.dptr + 4 + len, data.dsize - len, NULL, "ddddddff", + len += tdb_unpack(data.dptr + 4 + len, data.dsize - len, "ddddddff", &qjob, &qsize, &qpage_count, -- cgit From 055750f090874d6b355c26de94a1fbd18955d4c9 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 25 Nov 2003 19:16:35 +0000 Subject: allow users to delete jobs with cups printing backend The changes the name of the job passed off to cups from "Test Page" to "smbprn.00000033 Test Page" so that we can get the smb jobid back from lpq. Working on bug 770. (This used to be commit 5979f4d645e84fb22223e6cbf0043f2fa21acb2f) --- source3/printing/printing.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index ad17213c2d..32470fb22f 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -2063,6 +2063,8 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) return True; } + pjob->smbjob = jobid; + ret = (*(current_printif->job_submit))(snum, pjob); if (ret) -- cgit From 038784aa80aea37b66ab9eab384dd703837e02b0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 1 Dec 2003 18:02:05 +0000 Subject: don't mistake pre-existing UNIX jobs for smb jobs; patch from SATOH Fumiyasu bug 770 (This used to be commit 3a55788dca537248d0aea9973a84075e142b7736) --- source3/printing/printing.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 32470fb22f..bdcd950450 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -613,12 +613,14 @@ static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid) pj.status = q->status; pj.size = q->size; pj.spooled = True; - pj.smbjob = (old_pj != NULL ? True : False); fstrcpy(pj.filename, old_pj ? old_pj->filename : ""); - if (jobid < UNIX_JOB_START) + if (jobid < UNIX_JOB_START) { + pj.smbjob = (old_pj != NULL ? True : False); fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document"); - else + } else { + pj.smbjob = False; fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file); + } fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user); fstrcpy(pj.queuename, old_pj ? old_pj->queuename : lp_const_servicename(snum)); -- cgit From e7615b5776604af23592ed26dc0aa3ae0076835e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 14 Jan 2004 19:12:06 +0000 Subject: bug 660; using byte order safe macros (or tdb_unpack) when reading 2 or 4 byte values from a tdb buffer (This used to be commit be9f25bea94415af6b631a9c6e7af28d9d6e6565) --- source3/printing/printing.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index bdcd950450..ae7291bfc7 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -71,7 +71,7 @@ uint16 pjobid_to_rap(int snum, uint32 jobid) key.dsize = sizeof(jinfo); data = tdb_fetch(rap_tdb, key); if (data.dptr && data.dsize == sizeof(uint16)) { - memcpy(&rap_jobid, data.dptr, sizeof(uint16)); + rap_jobid = SVAL(data.dptr, 0); SAFE_FREE(data.dptr); DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n", (unsigned int)jobid, @@ -149,7 +149,7 @@ static void rap_jobid_delete(int snum, uint32 jobid) DEBUG(10,("rap_jobid_delete: deleting jobid %u\n", (unsigned int)jobid )); - memcpy(&rap_jobid, data.dptr, sizeof(uint16)); + rap_jobid = SVAL(data.dptr, 0); SAFE_FREE(data.dptr); data.dptr = (char *)&rap_jobid; data.dsize = sizeof(rap_jobid); @@ -615,7 +615,7 @@ static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid) pj.spooled = True; fstrcpy(pj.filename, old_pj ? old_pj->filename : ""); if (jobid < UNIX_JOB_START) { - pj.smbjob = (old_pj != NULL ? True : False); + pj.smbjob = True; fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document"); } else { pj.smbjob = False; @@ -648,7 +648,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void if ( key.dsize != sizeof(jobid) ) return 0; - memcpy(&jobid, key.dptr, sizeof(jobid)); + jobid = IVAL(key.dptr, 0); if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 ) return 0; free_nt_devicemode( &pjob.nt_devmode ); @@ -775,7 +775,7 @@ static pid_t get_updating_pid(fstring printer_name) return (pid_t)-1; } - memcpy(&updating_pid, data.dptr, sizeof(pid_t)); + updating_pid = IVAL(data.dptr, 0); SAFE_FREE(data.dptr); if (process_exists(updating_pid)) @@ -921,7 +921,7 @@ static void check_job_changed(int snum, TDB_DATA data, uint32 jobid) for (i = 0; i < job_count; i++) { uint32 ch_jobid; - memcpy(&ch_jobid, data.dptr + (i*4), 4); + ch_jobid = IVAL(data.dptr, i*4); if (ch_jobid == jobid) remove_from_jobs_changed(snum, jobid); } @@ -1407,7 +1407,7 @@ static BOOL remove_from_jobs_changed(int snum, uint32 jobid) for (i = 0; i < job_count; i++) { uint32 ch_jobid; - memcpy(&ch_jobid, data.dptr + (i*4), 4); + ch_jobid = IVAL(data.dptr, i*4); if (ch_jobid == jobid) { if (i < job_count -1 ) memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 ); @@ -1754,6 +1754,8 @@ static int get_queue_status(int snum, print_status_struct *status) data = tdb_fetch(pdb->tdb, key); if (data.dptr) { if (data.dsize == sizeof(print_status_struct)) + /* this memcpy is ok since the status struct was + not packed before storing it in the tdb */ memcpy(status, data.dptr, sizeof(print_status_struct)); SAFE_FREE(data.dptr); } @@ -2124,12 +2126,10 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun /* Get the stored queue data. */ data = tdb_fetch(pdb->tdb, key); - - if (data.dptr == NULL || data.dsize < 4) - qcount = 0; - else - memcpy(&qcount, data.dptr, 4); - + + if (data.dptr && data.dsize >= sizeof(qcount)) + len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount); + /* Get the changed jobs list. */ key.dptr = "INFO/jobs_changed"; key.dsize = strlen(key.dptr); @@ -2148,10 +2148,10 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun goto out; /* Retrieve the linearised queue data. */ - len = 0; + for( i = 0; i < qcount; i++) { uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime; - len += tdb_unpack(data.dptr + 4 + len, data.dsize - len, "ddddddff", + len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff", &qjob, &qsize, &qpage_count, @@ -2175,7 +2175,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun uint32 jobid; struct printjob *pjob; - memcpy(&jobid, &cgdata.dptr[i*4], 4); + jobid = IVAL(&cgdata.dptr, i*4); DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid)); pjob = print_job_find(snum, jobid); if (!pjob) { @@ -2260,6 +2260,8 @@ int print_queue_status(int snum, data = tdb_fetch(pdb->tdb, key); if (data.dptr) { if (data.dsize == sizeof(*status)) { + /* this memcpy is ok since the status struct was + not packed before storing it in the tdb */ memcpy(status, data.dptr, sizeof(*status)); } SAFE_FREE(data.dptr); -- cgit From bb104f31d5a849d5a3a0865fa77824c90d5e927e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 14 Jan 2004 20:56:26 +0000 Subject: bug 770; correct fix this time; Make sure that we send the SMBjobid for unix jobs back to the client. Allows windows client to remove print jobs submitted from lpr (This used to be commit 514561118860f982c458930c34763dac9ce0554e) --- source3/printing/printing.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index ae7291bfc7..1f0bb1e074 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -597,7 +597,7 @@ static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid) { struct printjob pj, *old_pj; - if (jobid == (uint32)-1) + if (jobid == (uint32)-1) jobid = q->job + UNIX_JOB_START; /* Preserve the timestamp on an existing unix print job */ @@ -671,9 +671,11 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n", (unsigned int)jobid )); pjob_delete(ts->snum, jobid); - } else - ts->total_jobs++; - return 0; + return 0; + } + + /* need to continue the the bottom of the function to + save the correct attributes */ } /* maybe it hasn't been spooled yet */ @@ -690,10 +692,14 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void return 0; } - for (i=0;iqcount;i++) { - uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file); - if (jobid == curr_jobid) - break; + /* this check only makes sense for jobs submitted from Windows clients */ + + if ( pjob.smbjob ) { + for (i=0;iqcount;i++) { + uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file); + if (jobid == curr_jobid) + break; + } } /* The job isn't in the system queue - we have to assume it has @@ -720,7 +726,9 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void } /* Save the pjob attributes we will store. */ - ts->queue[i].job = jobid; + /* FIXME!!! This is the only place where queue->job + represents the SMB jobid --jerry */ + ts->queue[i].job = jobid; ts->queue[i].size = pjob.size; ts->queue[i].page_count = pjob.page_count; ts->queue[i].status = pjob.status; -- cgit From 1fe6e296374619b3e0e398f6eff3f704ac9cd021 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 1 Mar 2004 17:03:05 +0000 Subject: BUG 1147; bad pointer case in get_stored_queue_info() causing seg fault (This used to be commit 91af1fb73a2e86a343c085128aaed2ef0c26de57) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 1f0bb1e074..c453eb796c 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -2183,7 +2183,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun uint32 jobid; struct printjob *pjob; - jobid = IVAL(&cgdata.dptr, i*4); + jobid = IVAL(cgdata.dptr, i*4); DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid)); pjob = print_job_find(snum, jobid); if (!pjob) { -- cgit From ef36785beb02f56c44b62d427ef15e6b6fb22744 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 2 Mar 2004 14:26:45 +0000 Subject: allow the 'printing' parameter to be set on a per share basis. The problem was that the current_printif struct was set during print_backend_init() based on the 'printcap name'. So you could not use cups and then override the setting for a specific printer by setting 'printing = bsd' (a common setup for pdf generation print services. There is a subtle change in behavior in that the print interface functions are selecting on the basis of lp_printing() and not lp_printcap_name(), but the new behavior seems more intuitive IMHO. (This used to be commit 14de9c065787bd1675021a6cd6555f81ea965f17) --- source3/printing/printing.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index c453eb796c..1efd932749 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -24,7 +24,6 @@ #include "printing.h" /* Current printer interface */ -static struct printif *current_printif = &generic_printif; static BOOL remove_from_jobs_changed(int snum, uint32 jobid); /* @@ -206,12 +205,6 @@ BOOL print_backend_init(void) close_all_print_db(); /* Don't leave any open. */ - /* select the appropriate printing interface... */ -#ifdef HAVE_CUPS - if (strcmp(lp_printcapname(), "cups") == 0) - current_printif = &cups_printif; -#endif /* HAVE_CUPS */ - /* do NT print initialization... */ return nt_printing_init(); } @@ -225,6 +218,28 @@ void printing_end(void) close_all_print_db(); /* Don't leave any open. */ } +/**************************************************************************** + Retrieve the set of printing functions for a given service. This allows + us to set the printer function table based on the value of the 'printing' + service parameter. + + Use the generic interface as the default and only use cups interface only + when asked for (and only when supported) +****************************************************************************/ + +static struct printif *get_printer_fns( int snum ) +{ + struct printif *printer_fns = &generic_printif; + +#ifdef HAVE_CUPS + if ( lp_printing(snum) == PRINT_CUPS ) { + printer_fns = &cups_printif; + } +#endif /* HAVE_CUPS */ + + return printer_fns; +} + /**************************************************************************** Useful function to generate a tdb key. ****************************************************************************/ @@ -951,6 +966,7 @@ static void print_queue_update(int snum) TDB_DATA data, key; TDB_DATA jcdata; struct tdb_print_db *pdb; + struct printif *current_printif = get_printer_fns( snum ); fstrcpy(printer_name, lp_const_servicename(snum)); pdb = get_print_db_byname(printer_name); @@ -1448,6 +1464,7 @@ static BOOL print_job_delete1(int snum, uint32 jobid) { struct printjob *pjob = print_job_find(snum, jobid); int result = 0; + struct printif *current_printif = get_printer_fns( snum ); if (!pjob) return False; @@ -1589,6 +1606,7 @@ BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR * { struct printjob *pjob = print_job_find(snum, jobid); int ret = -1; + struct printif *current_printif = get_printer_fns( snum ); if (!pjob || !user) return False; @@ -1639,6 +1657,7 @@ BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR { struct printjob *pjob = print_job_find(snum, jobid); int ret; + struct printif *current_printif = get_printer_fns( snum ); if (!pjob || !user) return False; @@ -2040,6 +2059,7 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) struct printjob *pjob = print_job_find(snum, jobid); int ret; SMB_STRUCT_STAT sbuf; + struct printif *current_printif = get_printer_fns( snum ); if (!pjob) return False; @@ -2296,6 +2316,7 @@ int print_queue_status(int snum, BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode) { int ret; + struct printif *current_printif = get_printer_fns( snum ); if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { *errcode = WERR_ACCESS_DENIED; @@ -2326,6 +2347,7 @@ BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode) BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode) { int ret; + struct printif *current_printif = get_printer_fns( snum ); if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { *errcode = WERR_ACCESS_DENIED; -- cgit From cb49c07c98fcc2c5e89643cb2cf7d0417c69114a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 5 Mar 2004 17:39:38 +0000 Subject: fix compiler warning (This used to be commit df19b6066e1f4e200adcd80f9526aa1a68509580) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 1efd932749..ad11108a5a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -658,7 +658,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void struct traverse_struct *ts = (struct traverse_struct *)state; struct printjob pjob; uint32 jobid; - int i; + int i = 0; if ( key.dsize != sizeof(jobid) ) return 0; -- cgit From dbe9e8a4cbd266990a68f66559bcaff896bc4d51 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 15 Mar 2004 15:06:33 +0000 Subject: fix byte ordering problem when storing the updating pid for the lpq cache; was causing an abort in process_exists() on solaris (This used to be commit 26681cd2a1567d90cc7d344e8aca6e6a686053f5) --- source3/printing/printing.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index ad11108a5a..ed19c01f24 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -818,6 +818,8 @@ static void set_updating_pid(const fstring printer_name, BOOL delete) TDB_DATA key; TDB_DATA data; pid_t updating_pid = sys_getpid(); + uint8 buffer[4]; + struct tdb_print_db *pdb = get_print_db_byname(printer_name); if (!pdb) @@ -833,8 +835,9 @@ static void set_updating_pid(const fstring printer_name, BOOL delete) return; } - data.dptr = (void *)&updating_pid; - data.dsize = sizeof(pid_t); + SIVAL( buffer, 0, updating_pid); + data.dptr = (void *)buffer; + data.dsize = 4; /* we always assume this is a 4 byte value */ tdb_store(pdb->tdb, key, data, TDB_REPLACE); release_print_db(pdb); -- cgit From dbb38cc6b5829d9ac45e3dea40878039edd26f8d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 16 Mar 2004 17:06:11 +0000 Subject: merging print change notify fix from HP appliance. Also might address some one the issues in BUG 1007 (This used to be commit 17ecea4152fb0883acde675b01f19d3e19ff1d64) --- source3/printing/printing.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index ed19c01f24..e4ef1f52d0 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -534,8 +534,22 @@ static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob) /* Send notify updates for what has changed */ - if ( ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob)) ) - pjob_store_notify( snum, jobid, (struct printjob *)old_data.dptr, pjob ); + if ( ret ) { + struct printjob old_pjob; + + if ( old_data.dsize ) + { + if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 ) + { + pjob_store_notify( snum, jobid, &old_pjob , pjob ); + free_nt_devicemode( &old_pjob.nt_devmode ); + } + } + else { + /* new job */ + pjob_store_notify( snum, jobid, NULL, pjob ); + } + } done: SAFE_FREE( old_data.dptr ); -- cgit From ba8a59dbf43a18bb93007b22758cfe5f9882dd3e Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 7 May 2004 15:21:27 +0000 Subject: r555: Fix big-endian storage of jobids in jobs_changed list. Found during debugging of 1279 (This used to be commit 7c1cfb16c0b2f0128afca0b01036567253a3f92a) --- source3/printing/printing.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index e4ef1f52d0..fd123267d1 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1905,10 +1905,12 @@ static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid) { TDB_DATA data, key; + uint32 store_jobid; key.dptr = "INFO/jobs_changed"; key.dsize = strlen(key.dptr); - data.dptr = (char *)&jobid; + SIVAL(&store_jobid, 0, jobid); + data.dptr = (char *)&store_jobid; data.dsize = 4; DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid )); -- cgit From 88adbfa1f7e136705fad2fe2926e4053808914ab Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 7 May 2004 17:17:25 +0000 Subject: r560: Fix bugzilla 1279: cannot control individual print jobs using cups Store the print job using a little-endian key. (This used to be commit e0491dae989ea289438de3bdf29d8810d409a01b) --- source3/printing/printing.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index fd123267d1..2355dd1450 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -249,7 +249,7 @@ static TDB_DATA print_key(uint32 jobid) static uint32 j; TDB_DATA ret; - j = jobid; + SIVAL(&j, 0, jobid); ret.dptr = (void *)&j; ret.dsize = sizeof(j); return ret; @@ -358,9 +358,9 @@ static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, return 0; if (*sysjob == pjob->sysjob) { - uint32 *jobid = (uint32 *)key.dptr; + uint32 jobid = IVAL(key.dptr,0); - sysjob_to_jobid_value = *jobid; + sysjob_to_jobid_value = jobid; return 1; } -- cgit From 7959cba656133840c37d293ffab6831f3097016f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 27 May 2004 15:38:54 +0000 Subject: r925: add changes frpm trunk (r841 and r842) -- enable background queue update process and allow printers to have different sharenames from printernames (This used to be commit 066b9c4276a968788a03709a00d4f672ac032df7) --- source3/printing/printing.c | 88 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 2355dd1450..670e489786 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -23,6 +23,9 @@ #include "includes.h" #include "printing.h" +extern SIG_ATOMIC_T got_sig_term; +extern SIG_ATOMIC_T reload_after_sighup; + /* Current printer interface */ static BOOL remove_from_jobs_changed(int snum, uint32 jobid); @@ -971,7 +974,7 @@ static void check_job_changed(int snum, TDB_DATA data, uint32 jobid) Update the internal database from the system print queue for a queue. ****************************************************************************/ -static void print_queue_update(int snum) +static void print_queue_update_internal(int snum) { int i, qcount; print_queue_struct *queue = NULL; @@ -1150,6 +1153,89 @@ static void print_queue_update(int snum) release_print_db(pdb); } +/**************************************************************************** +this is the receive function of the background lpq updater +****************************************************************************/ +static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len) +{ + int snum; + snum=*((int *)buf); + print_queue_update_internal(snum); +} + +static pid_t background_lpq_updater_pid = -1; + +/**************************************************************************** +main thread of the background lpq updater +****************************************************************************/ +void start_background_queue(void) +{ + DEBUG(3,("start_background_queue: Starting background LPQ thread\n")); + background_lpq_updater_pid = sys_fork(); + + if (background_lpq_updater_pid == -1) { + DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) )); + exit(1); + } + + if(background_lpq_updater_pid == 0) { + /* Child. */ + DEBUG(5,("start_background_queue: background LPQ thread started\n")); + + claim_connection( NULL, "smbd lpq backend", 0, False, + FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINTING ); + + if (!locking_init(0)) { + exit(1); + } + + if (!print_backend_init()) { + exit(1); + } + + message_register(MSG_PRINTER_UPDATE, print_queue_receive); + + DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n")); + while (1) { + pause(); + + /* check for some essential signals first */ + + if (got_sig_term) { + exit_server("Caught TERM signal"); + } + + if (reload_after_sighup) { + change_to_root_user(); + DEBUG(1,("Reloading services after SIGHUP\n")); + reload_services(False); + reload_after_sighup = 0; + } + + /* now check for messages */ + + DEBUG(10,("start_background_queue: background LPQ thread got a message\n")); + message_dispatch(); + } + } +} + +/**************************************************************************** +update the internal database from the system print queue for a queue +****************************************************************************/ +static void print_queue_update(int snum) +{ + /* + * Make sure that the backgroup queueu process exists. + * Otherwise just do the update ourselves + */ + + if ( background_lpq_updater_pid != -1 ) + message_send_pid(background_lpq_updater_pid, MSG_PRINTER_UPDATE, &snum, sizeof(snum), False); + else + print_queue_update_internal( snum ); +} + /**************************************************************************** Create/Update an entry in the print tdb that will allow us to send notify updates only to interested smbd's. -- cgit From 087868c49916e96cf860577144bc19b799fd720e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 23 Jun 2004 15:46:01 +0000 Subject: r1230: (merges from HP PSA) fixing a couple of caching bugs in the printing code. (a) make sure to clear jobs_changed list when deleting a job and, (b) invalidate the printer handle cache when we get a notification that something has changed on that printer (This used to be commit e3d4fea7808abc77bfdb1a540ab18afe04af5030) --- source3/printing/printing.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 670e489786..5814182b25 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -600,6 +600,7 @@ void pjob_delete(int snum, uint32 jobid) tdb_delete(pdb->tdb, print_key(jobid)); release_print_db(pdb); rap_jobid_delete(snum, jobid); + remove_from_jobs_changed( snum, jobid ); } /**************************************************************************** -- cgit From baf7cf42a6319c9c31c9d29ee8102d5478826a38 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 Jun 2004 15:42:00 +0000 Subject: r1295: To be able to send a message to the background queue updated, we need to be root. Otherwise the USR1 signal will not be delivered. Volker (This used to be commit c66be874d8ce1f381518e07025305222bac1ab3a) --- source3/printing/printing.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 5814182b25..8beea9d0ce 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1231,9 +1231,13 @@ static void print_queue_update(int snum) * Otherwise just do the update ourselves */ - if ( background_lpq_updater_pid != -1 ) - message_send_pid(background_lpq_updater_pid, MSG_PRINTER_UPDATE, &snum, sizeof(snum), False); - else + if ( background_lpq_updater_pid != -1 ) { + become_root(); + message_send_pid(background_lpq_updater_pid, + MSG_PRINTER_UPDATE, &snum, sizeof(snum), + False); + unbecome_root(); + } else print_queue_update_internal( snum ); } -- cgit From d90c4a046203f6218e36a2b5f06742a7a4eae8b1 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 7 Jul 2004 21:43:44 +0000 Subject: r1384: ensure we remove the tdb entry for a job in the spooling state (This used to be commit bc8cf6c852617b266f6dabed84bbd912a188f3a3) --- source3/printing/printing.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 8beea9d0ce..10ca7e47e7 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -600,7 +600,6 @@ void pjob_delete(int snum, uint32 jobid) tdb_delete(pdb->tdb, print_key(jobid)); release_print_db(pdb); rap_jobid_delete(snum, jobid); - remove_from_jobs_changed( snum, jobid ); } /**************************************************************************** @@ -1685,8 +1684,6 @@ pause, or resume print job. User name: %s. Printer name: %s.", *errcode = map_werror_from_unix(errno); return False; } - - return True; } if (!print_job_delete1(snum, jobid)) { -- cgit From 1842fde7d10a6faccae1a24ebc67f8452a5a828e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 18 Aug 2004 13:55:58 +0000 Subject: r1885: tighten the cache consistency with the ntprinters.tdb entry an the in memory cache associated with open printer handles; also make sure that register_messages_flags() doesn't overwrite the originally registers flags (This used to be commit 540daf71d8ad189af5dd6d45aa1ce2b3d67da752) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 10ca7e47e7..31cb0faa9b 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1183,7 +1183,7 @@ void start_background_queue(void) DEBUG(5,("start_background_queue: background LPQ thread started\n")); claim_connection( NULL, "smbd lpq backend", 0, False, - FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINTING ); + FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL); if (!locking_init(0)) { exit(1); -- cgit From 278f9467f2079044497e3fd4c5358c280f179e41 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 31 Aug 2004 15:11:41 +0000 Subject: r2133: Several fixes: * BUG 1627: fix for NIS compiles on HPUX 11.00, AIX 4.3 and 5.1 patch from Olaf Flebbe . Will need to watch this one in the build farm. * Fix bug found by rwf@loonybin.net where the PRINT_ATTRIBUTE_PUBLISHED was getting reset by attempts to sanitize the defined attributes (PRINTER_ATTRIBUTE_SAMBA) * Resolve name conflict on DEC OSF-5.1 (inspired by patch from Adharsh Praveen ) * Work around parsing error in the print change notify code (not that the alignment bug is still there but reording the entries in the array works around it). * remove duplicate declaration of getprintprocdir from rpcclient. (This used to be commit 7474c6a446037f3ca2546cb6984d800bfc524029) --- source3/printing/printing.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 31cb0faa9b..8b93a43311 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -442,22 +442,30 @@ static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data, if (!old_data) new_job = True; - /* Notify the job name first */ - - if (new_job || !strequal(old_data->jobname, new_data->jobname)) - notify_job_name(snum, jobid, new_data->jobname); - /* Job attributes that can't be changed. We only send notification for these on a new job. */ + /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the + NOTIFY_INFO_DATA buffer, we *have* to send the job submission + time first or else we'll end up with potential alignment + errors. I don't think the systemtime should be spooled as + a string, but this gets us around that error. + --jerry (i'll feel dirty for this) */ + if (new_job) { notify_job_submitted(snum, jobid, new_data->starttime); notify_job_username(snum, jobid, new_data->user); } + if (new_job || !strequal(old_data->jobname, new_data->jobname)) + notify_job_name(snum, jobid, new_data->jobname); + /* Job attributes of a new job or attributes that can be modified. */ + if (new_job || !strequal(old_data->jobname, new_data->jobname)) + notify_job_name(snum, jobid, new_data->jobname); + if (new_job || old_data->status != new_data->status) notify_job_status(snum, jobid, map_to_spoolss_status(new_data->status)); @@ -575,26 +583,19 @@ void pjob_delete(int snum, uint32 jobid) return; if (!pjob) { - DEBUG(5, ("pjob_delete(): we were asked to delete nonexistent job %u\n", + DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n", (unsigned int)jobid)); release_print_db(pdb); return; } - /* Send a notification that a job has been deleted */ - - job_status = map_to_spoolss_status(pjob->status); - /* We must cycle through JOB_STATUS_DELETING and JOB_STATUS_DELETED for the port monitor to delete the job properly. */ - job_status |= JOB_STATUS_DELETING; + job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED; notify_job_status(snum, jobid, job_status); - job_status |= JOB_STATUS_DELETED; - notify_job_status(snum, jobid, job_status); - /* Remove from printing.tdb */ tdb_delete(pdb->tdb, print_key(jobid)); -- cgit From 12172c91da46de18f0dc9799aba98d50f1524d0d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 2 Sep 2004 21:52:35 +0000 Subject: r2191: ensure that we assign our pid to print jobs (and not our parent's pid); ensures that spooling jobs from dead smbds are removed from the tdb (This used to be commit 9e42d016e1fee9ac999dadc383eb5db45ed79b00) --- source3/printing/printing.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 8b93a43311..d9bc13d03a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -159,8 +159,6 @@ static void rap_jobid_delete(int snum, uint32 jobid) tdb_delete(rap_tdb, data); } -static pid_t local_pid; - static int get_queue_status(int, print_status_struct *); /**************************************************************************** @@ -174,15 +172,10 @@ BOOL print_backend_init(void) int services = lp_numservices(); int snum; - if (local_pid == sys_getpid()) - return True; - unlink(lock_path("printing.tdb")); pstrcpy(printing_path,lock_path("printing")); mkdir(printing_path,0755); - local_pid = sys_getpid(); - /* handle a Samba upgrade */ for (snum = 0; snum < services; snum++) { @@ -599,6 +592,7 @@ void pjob_delete(int snum, uint32 jobid) /* Remove from printing.tdb */ tdb_delete(pdb->tdb, print_key(jobid)); + remove_from_jobs_changed(snum, jobid); release_print_db(pdb); rap_jobid_delete(snum, jobid); } @@ -1448,7 +1442,7 @@ int print_job_fd(int snum, uint32 jobid) if (!pjob) return -1; /* don't allow another process to get this info - it is meaningless */ - if (pjob->pid != local_pid) + if (pjob->pid != sys_getpid()) return -1; return pjob->fd; } @@ -1462,7 +1456,7 @@ int print_job_fd(int snum, uint32 jobid) char *print_job_fname(int snum, uint32 jobid) { struct printjob *pjob = print_job_find(snum, jobid); - if (!pjob || pjob->spooled || pjob->pid != local_pid) + if (!pjob || pjob->spooled || pjob->pid != sys_getpid()) return NULL; return pjob->filename; } @@ -1501,7 +1495,7 @@ BOOL print_job_set_place(int snum, uint32 jobid, int place) BOOL print_job_set_name(int snum, uint32 jobid, char *name) { struct printjob *pjob = print_job_find(snum, jobid); - if (!pjob || pjob->pid != local_pid) + if (!pjob || pjob->pid != sys_getpid()) return False; fstrcpy(pjob->jobname, name); @@ -1598,8 +1592,6 @@ static BOOL print_job_delete1(int snum, uint32 jobid) if (pjob->spooled && pjob->sysjob != -1) result = (*(current_printif->job_delete))(snum, pjob); - else - remove_from_jobs_changed(snum, jobid); /* Delete the tdb entry if the delete succeeded or the job hasn't been spooled. */ @@ -1814,7 +1806,7 @@ int print_job_write(int snum, uint32 jobid, const char *buf, int size) if (!pjob) return -1; /* don't allow another process to get this info - it is meaningless */ - if (pjob->pid != local_pid) + if (pjob->pid != sys_getpid()) return -1; return_code = write(pjob->fd, buf, size); @@ -2079,7 +2071,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE ZERO_STRUCT(pjob); - pjob.pid = local_pid; + pjob.pid = sys_getpid(); pjob.sysjob = -1; pjob.fd = -1; pjob.starttime = time(NULL); @@ -2149,7 +2141,7 @@ void print_job_endpage(int snum, uint32 jobid) if (!pjob) return; /* don't allow another process to get this info - it is meaningless */ - if (pjob->pid != local_pid) + if (pjob->pid != sys_getpid()) return; pjob->page_count++; @@ -2172,7 +2164,7 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) if (!pjob) return False; - if (pjob->spooled || pjob->pid != local_pid) + if (pjob->spooled || pjob->pid != sys_getpid()) return False; if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) { @@ -2228,7 +2220,6 @@ fail: /* Still need to add proper error return propagation! 010122:JRR */ unlink(pjob->filename); pjob_delete(snum, jobid); - remove_from_jobs_changed(snum, jobid); return False; } -- cgit From 5a8effaaae3c3037ae0f96a942734298950169c6 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 23 Sep 2004 19:24:02 +0000 Subject: r2569: Patch from Rob Foehl : - fix typo in libads/ldap_printer.c:39, ads_find_printer_on_server() (originally libads-typo.patch) - fix leak in printing/nt_printing.c, is_printer_published() (originally is_printer_published-leak.patch) - fix double print_backend_init() calls, now only called from main() - restructuring in printing/nt_printing.c - replaced (un)publish_it() with ads-specific functions - moved common code to nt_printer_publish() - improved error handling in several places - added check_published_printers() in printing/nt_printing.c, to verify that each published printer is actually in the directory at startup - changed calling semantics of mod_a_printer, dump_a_printer, and update_driver_init to be more consistent with the rest of the api and reduce some copying (This used to be commit 50a5a3dbd02acb0d09133b6e42cc37d091ea901d) --- source3/printing/printing.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index d9bc13d03a..60adcc4d7f 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1184,10 +1184,6 @@ void start_background_queue(void) exit(1); } - if (!print_backend_init()) { - exit(1); - } - message_register(MSG_PRINTER_UPDATE, print_queue_receive); DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n")); -- cgit From 293136c04b7eb5293ef18273e13fca00c85bb5f0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 19 Oct 2004 17:05:01 +0000 Subject: r3067: patch based on volker's initial work in trunk that fixes the queu update problem when using the background daemon (This used to be commit de7af09e727e744aa27af85ef7c0f73ed5c1550a) --- source3/printing/printing.c | 512 ++++++++++++++++++++++++++------------------ 1 file changed, 301 insertions(+), 211 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 60adcc4d7f..1e897c962a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -27,7 +27,7 @@ extern SIG_ATOMIC_T got_sig_term; extern SIG_ATOMIC_T reload_after_sighup; /* Current printer interface */ -static BOOL remove_from_jobs_changed(int snum, uint32 jobid); +static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid); /* the printing backend revolves around a tdb database that stores the @@ -50,12 +50,16 @@ static BOOL remove_from_jobs_changed(int snum, uint32 jobid); static TDB_CONTEXT *rap_tdb; static uint16 next_rap_jobid; +struct rap_jobid_key { + fstring sharename; + uint32 jobid; +}; -uint16 pjobid_to_rap(int snum, uint32 jobid) +uint16 pjobid_to_rap(const char* sharename, uint32 jobid) { uint16 rap_jobid; TDB_DATA data, key; - char jinfo[8]; + struct rap_jobid_key jinfo; DEBUG(10,("pjobid_to_rap: called.\n")); @@ -66,18 +70,18 @@ uint16 pjobid_to_rap(int snum, uint32 jobid) return 0; } - SIVAL(&jinfo,0,(int32)snum); - SIVAL(&jinfo,4,jobid); - - key.dptr = (char *)&jinfo; + ZERO_STRUCT( jinfo ); + fstrcpy( jinfo.sharename, sharename ); + jinfo.jobid = jobid; + key.dptr = (char*)&jinfo; key.dsize = sizeof(jinfo); + data = tdb_fetch(rap_tdb, key); if (data.dptr && data.dsize == sizeof(uint16)) { rap_jobid = SVAL(data.dptr, 0); SAFE_FREE(data.dptr); DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n", - (unsigned int)jobid, - (unsigned int)rap_jobid)); + (unsigned int)jobid, (unsigned int)rap_jobid)); return rap_jobid; } SAFE_FREE(data.dptr); @@ -91,12 +95,11 @@ uint16 pjobid_to_rap(int snum, uint32 jobid) tdb_store(rap_tdb, data, key, TDB_REPLACE); DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n", - (unsigned int)jobid, - (unsigned int)rap_jobid)); + (unsigned int)jobid, (unsigned int)rap_jobid)); return rap_jobid; } -BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid) +BOOL rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid) { TDB_DATA data, key; @@ -108,48 +111,50 @@ BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid) key.dptr = (char *)&rap_jobid; key.dsize = sizeof(rap_jobid); data = tdb_fetch(rap_tdb, key); - if (data.dptr && data.dsize == 8) { - *psnum = IVAL(data.dptr,0); - *pjobid = IVAL(data.dptr,4); + if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) ) + { + struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr; + fstrcpy( sharename, jinfo->sharename ); + *pjobid = jinfo->jobid; DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n", - (unsigned int)*pjobid, - (unsigned int)rap_jobid)); + (unsigned int)*pjobid, (unsigned int)rap_jobid)); SAFE_FREE(data.dptr); return True; } DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n", - (unsigned int)rap_jobid)); + (unsigned int)rap_jobid)); SAFE_FREE(data.dptr); return False; } -static void rap_jobid_delete(int snum, uint32 jobid) +static void rap_jobid_delete(const char* sharename, uint32 jobid) { TDB_DATA key, data; uint16 rap_jobid; - char jinfo[8]; + struct rap_jobid_key jinfo; DEBUG(10,("rap_jobid_delete: called.\n")); if (!rap_tdb) return; - SIVAL(&jinfo,0,(int32)snum); - SIVAL(&jinfo,4,jobid); - - key.dptr = (char *)&jinfo; + ZERO_STRUCT( jinfo ); + fstrcpy( jinfo.sharename, sharename ); + jinfo.jobid = jobid; + key.dptr = (char*)&jinfo; key.dsize = sizeof(jinfo); + data = tdb_fetch(rap_tdb, key); if (!data.dptr || (data.dsize != sizeof(uint16))) { DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n", - (unsigned int)jobid )); + (unsigned int)jobid )); SAFE_FREE(data.dptr); return; } DEBUG(10,("rap_jobid_delete: deleting jobid %u\n", - (unsigned int)jobid )); + (unsigned int)jobid )); rap_jobid = SVAL(data.dptr, 0); SAFE_FREE(data.dptr); @@ -159,7 +164,7 @@ static void rap_jobid_delete(int snum, uint32 jobid) tdb_delete(rap_tdb, data); } -static int get_queue_status(int, print_status_struct *); +static int get_queue_status(const char* sharename, print_status_struct *); /**************************************************************************** Initialise the printing backend. Called once at startup before the fork(). @@ -223,19 +228,27 @@ void printing_end(void) when asked for (and only when supported) ****************************************************************************/ -static struct printif *get_printer_fns( int snum ) +static struct printif *get_printer_fns_from_type( enum printing_types type ) { struct printif *printer_fns = &generic_printif; #ifdef HAVE_CUPS - if ( lp_printing(snum) == PRINT_CUPS ) { + if ( type == PRINT_CUPS ) { printer_fns = &cups_printif; } #endif /* HAVE_CUPS */ + + printer_fns->type = type; return printer_fns; } +static struct printif *get_printer_fns( int snum ) +{ + return get_printer_fns_from_type( lp_printing(snum) ); +} + + /**************************************************************************** Useful function to generate a tdb key. ****************************************************************************/ @@ -306,11 +319,11 @@ int unpack_pjob( char* buf, int buflen, struct printjob *pjob ) Useful function to find a print job in the database. ****************************************************************************/ -static struct printjob *print_job_find(int snum, uint32 jobid) +static struct printjob *print_job_find(const char *sharename, uint32 jobid) { static struct printjob pjob; TDB_DATA ret; - struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); + struct tdb_print_db *pdb = get_print_db_byname(sharename); if (!pdb) @@ -427,7 +440,7 @@ static uint32 map_to_spoolss_status(uint32 lpq_status) return 0; } -static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data, +static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data, struct printjob *new_data) { BOOL new_job = False; @@ -446,38 +459,38 @@ static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data, --jerry (i'll feel dirty for this) */ if (new_job) { - notify_job_submitted(snum, jobid, new_data->starttime); - notify_job_username(snum, jobid, new_data->user); + notify_job_submitted(sharename, jobid, new_data->starttime); + notify_job_username(sharename, jobid, new_data->user); } if (new_job || !strequal(old_data->jobname, new_data->jobname)) - notify_job_name(snum, jobid, new_data->jobname); + notify_job_name(sharename, jobid, new_data->jobname); /* Job attributes of a new job or attributes that can be modified. */ if (new_job || !strequal(old_data->jobname, new_data->jobname)) - notify_job_name(snum, jobid, new_data->jobname); + notify_job_name(sharename, jobid, new_data->jobname); if (new_job || old_data->status != new_data->status) - notify_job_status(snum, jobid, map_to_spoolss_status(new_data->status)); + notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status)); if (new_job || old_data->size != new_data->size) - notify_job_total_bytes(snum, jobid, new_data->size); + notify_job_total_bytes(sharename, jobid, new_data->size); if (new_job || old_data->page_count != new_data->page_count) - notify_job_total_pages(snum, jobid, new_data->page_count); + notify_job_total_pages(sharename, jobid, new_data->page_count); } /**************************************************************************** Store a job structure back to the database. ****************************************************************************/ -static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob) +static BOOL pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob) { TDB_DATA old_data, new_data; BOOL ret = False; - struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); + struct tdb_print_db *pdb = get_print_db_byname(sharename); char *buf = NULL; int len, newlen, buflen; @@ -545,13 +558,13 @@ static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob) { if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 ) { - pjob_store_notify( snum, jobid, &old_pjob , pjob ); + pjob_store_notify( sharename, jobid, &old_pjob , pjob ); free_nt_devicemode( &old_pjob.nt_devmode ); } } else { /* new job */ - pjob_store_notify( snum, jobid, NULL, pjob ); + pjob_store_notify( sharename, jobid, NULL, pjob ); } } @@ -566,15 +579,19 @@ done: Remove a job structure from the database. ****************************************************************************/ -void pjob_delete(int snum, uint32 jobid) +void pjob_delete(const char* sharename, uint32 jobid) { - struct printjob *pjob = print_job_find(snum, jobid); + struct printjob *pjob; uint32 job_status = 0; - struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); + struct tdb_print_db *pdb; + + pdb = get_print_db_byname( sharename ); if (!pdb) return; + pjob = print_job_find( sharename, jobid ); + if (!pjob) { DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n", (unsigned int)jobid)); @@ -587,14 +604,14 @@ void pjob_delete(int snum, uint32 jobid) properly. */ job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED; - notify_job_status(snum, jobid, job_status); + notify_job_status(sharename, jobid, job_status); /* Remove from printing.tdb */ tdb_delete(pdb->tdb, print_key(jobid)); - remove_from_jobs_changed(snum, jobid); - release_print_db(pdb); - rap_jobid_delete(snum, jobid); + remove_from_jobs_changed(sharename, jobid); + release_print_db( pdb ); + rap_jobid_delete(sharename, jobid); } /**************************************************************************** @@ -620,7 +637,7 @@ static uint32 print_parse_jobid(char *fname) List a unix job in the print database. ****************************************************************************/ -static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid) +static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid) { struct printjob pj, *old_pj; @@ -629,7 +646,7 @@ static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid) /* Preserve the timestamp on an existing unix print job */ - old_pj = print_job_find(snum, jobid); + old_pj = print_job_find(sharename, jobid); ZERO_STRUCT(pj); @@ -649,15 +666,16 @@ static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid) fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file); } fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user); - fstrcpy(pj.queuename, old_pj ? old_pj->queuename : lp_const_servicename(snum)); + fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename ); - pjob_store(snum, jobid, &pj); + pjob_store(sharename, jobid, &pj); } struct traverse_struct { print_queue_struct *queue; int qcount, snum, maxcount, total_jobs; + const char *sharename; time_t lpq_time; }; @@ -681,11 +699,6 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void free_nt_devicemode( &pjob.nt_devmode ); - if (ts->snum != lp_servicenumber(pjob.queuename)) { - /* this isn't for the queue we are looking at - this cannot happen with the split tdb's. JRA */ - return 0; - } - if (!pjob.smbjob) { /* remove a unix job if it isn't in the system queue any more */ @@ -697,7 +710,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void if (i == ts->qcount) { DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n", (unsigned int)jobid )); - pjob_delete(ts->snum, jobid); + pjob_delete(ts->sharename, jobid); return 0; } @@ -713,7 +726,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void if (!process_exists(pjob.pid)) { DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n", (unsigned int)jobid, (unsigned int)pjob.pid )); - pjob_delete(ts->snum, jobid); + pjob_delete(ts->sharename, jobid); } else ts->total_jobs++; return 0; @@ -746,7 +759,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void (unsigned int)jobid, (unsigned int)pjob.starttime, (unsigned int)ts->lpq_time )); - pjob_delete(ts->snum, jobid); + pjob_delete(ts->sharename, jobid); } else ts->total_jobs++; return 0; @@ -776,12 +789,12 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void static void print_cache_flush(int snum) { fstring key; - const char *printername = lp_const_servicename(snum); - struct tdb_print_db *pdb = get_print_db_byname(printername); + const char *sharename = lp_const_servicename(snum); + struct tdb_print_db *pdb = get_print_db_byname(sharename); if (!pdb) return; - slprintf(key, sizeof(key)-1, "CACHE/%s", printername); + slprintf(key, sizeof(key)-1, "CACHE/%s", sharename); tdb_store_int32(pdb->tdb, key, -1); release_print_db(pdb); } @@ -790,16 +803,16 @@ static void print_cache_flush(int snum) Check if someone already thinks they are doing the update. ****************************************************************************/ -static pid_t get_updating_pid(fstring printer_name) +static pid_t get_updating_pid(fstring sharename) { fstring keystr; TDB_DATA data, key; pid_t updating_pid; - struct tdb_print_db *pdb = get_print_db_byname(printer_name); + struct tdb_print_db *pdb = get_print_db_byname(sharename); if (!pdb) return (pid_t)-1; - slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name); + slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename); key.dptr = keystr; key.dsize = strlen(keystr); @@ -824,7 +837,7 @@ static pid_t get_updating_pid(fstring printer_name) in the tdb. ****************************************************************************/ -static void set_updating_pid(const fstring printer_name, BOOL delete) +static void set_updating_pid(const fstring sharename, BOOL delete) { fstring keystr; TDB_DATA key; @@ -832,12 +845,12 @@ static void set_updating_pid(const fstring printer_name, BOOL delete) pid_t updating_pid = sys_getpid(); uint8 buffer[4]; - struct tdb_print_db *pdb = get_print_db_byname(printer_name); + struct tdb_print_db *pdb = get_print_db_byname(sharename); if (!pdb) return; - slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name); + slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename); key.dptr = keystr; key.dsize = strlen(keystr); @@ -951,7 +964,7 @@ static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb) return data; } -static void check_job_changed(int snum, TDB_DATA data, uint32 jobid) +static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid) { unsigned int i; unsigned int job_count = data.dsize / 4; @@ -961,15 +974,23 @@ static void check_job_changed(int snum, TDB_DATA data, uint32 jobid) ch_jobid = IVAL(data.dptr, i*4); if (ch_jobid == jobid) - remove_from_jobs_changed(snum, jobid); + remove_from_jobs_changed(sharename, jobid); } } +struct print_queue_update_context { + fstring sharename; + enum printing_types printing_type; + pstring lpqcommand; +}; + /**************************************************************************** - Update the internal database from the system print queue for a queue. + main work for updating the lpq cahe for a printer queue ****************************************************************************/ -static void print_queue_update_internal(int snum) +static void print_queue_update_internal( const char *sharename, + struct printif *current_printif, + char *lpq_command ) { int i, qcount; print_queue_struct *queue = NULL; @@ -977,88 +998,35 @@ static void print_queue_update_internal(int snum) print_status_struct old_status; struct printjob *pjob; struct traverse_struct tstruct; - fstring keystr, printer_name, cachestr; TDB_DATA data, key; TDB_DATA jcdata; - struct tdb_print_db *pdb; - struct printif *current_printif = get_printer_fns( snum ); - - fstrcpy(printer_name, lp_const_servicename(snum)); - pdb = get_print_db_byname(printer_name); - if (!pdb) - return; - - /* - * Check to see if someone else is doing this update. - * This is essentially a mutex on the update. - */ - - if (get_updating_pid(printer_name) != -1) { - release_print_db(pdb); - return; - } - - /* Lock the queue for the database update */ - - slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name); - /* Only wait 10 seconds for this. */ - if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) { - DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name)); - release_print_db(pdb); - return; - } - - /* - * Ensure that no one else got in here. - * If the updating pid is still -1 then we are - * the winner. - */ - - if (get_updating_pid(printer_name) != -1) { - /* - * Someone else is doing the update, exit. - */ - tdb_unlock_bystring(pdb->tdb, keystr); - release_print_db(pdb); - return; - } - - /* - * We're going to do the update ourselves. - */ - - /* Tell others we're doing the update. */ - set_updating_pid(printer_name, False); - - /* - * Allow others to enter and notice we're doing - * the update. - */ - - tdb_unlock_bystring(pdb->tdb, keystr); - + fstring keystr, cachestr; + struct tdb_print_db *pdb = get_print_db_byname(sharename); + /* * Update the cache time FIRST ! Stops others even * attempting to get the lock and doing this * if the lpq takes a long time. */ - slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name); + slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename); tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL)); /* get the current queue using the appropriate interface */ ZERO_STRUCT(status); - qcount = (*(current_printif->queue_get))(snum, &queue, &status); + qcount = (*(current_printif->queue_get))(sharename, + current_printif->type, + lpq_command, &queue, &status); DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ? - "s" : "", printer_name)); + "s" : "", sharename)); /* Sort the queue by submission time otherwise they are displayed in hash order. */ qsort(queue, qcount, sizeof(print_queue_struct), - QSORT_CAST(printjob_comp)); + QSORT_CAST(printjob_comp)); /* any job in the internal database that is marked as spooled @@ -1078,24 +1046,24 @@ static void print_queue_update_internal(int snum) if (jobid == (uint32)-1) { /* assume its a unix print job */ - print_unix_job(snum, &queue[i], jobid); + print_unix_job(sharename, &queue[i], jobid); continue; } /* we have an active SMB print job - update its status */ - pjob = print_job_find(snum, jobid); + pjob = print_job_find(sharename, jobid); if (!pjob) { /* err, somethings wrong. Probably smbd was restarted with jobs in the queue. All we can do is treat them like unix jobs. Pity. */ - print_unix_job(snum, &queue[i], jobid); + print_unix_job(sharename, &queue[i], jobid); continue; } pjob->sysjob = queue[i].job; pjob->status = queue[i].status; - pjob_store(snum, jobid, pjob); - check_job_changed(snum, jcdata, jobid); + pjob_store(sharename, jobid, pjob); + check_job_changed(sharename, jcdata, jobid); } SAFE_FREE(jcdata.dptr); @@ -1104,9 +1072,10 @@ static void print_queue_update_internal(int snum) system queue */ tstruct.queue = queue; tstruct.qcount = qcount; - tstruct.snum = snum; + tstruct.snum = -1; tstruct.total_jobs = 0; tstruct.lpq_time = time(NULL); + tstruct.sharename = sharename; tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct); @@ -1116,17 +1085,17 @@ static void print_queue_update_internal(int snum) SAFE_FREE(tstruct.queue); DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n", - printer_name, tstruct.total_jobs )); + sharename, tstruct.total_jobs )); tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs); - get_queue_status(snum, &old_status); + get_queue_status(sharename, &old_status); if (old_status.qcount != qcount) DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n", - old_status.qcount, qcount, printer_name )); + old_status.qcount, qcount, sharename)); /* store the new queue status structure */ - slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name); + slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename); key.dptr = keystr; key.dsize = strlen(keystr); @@ -1140,11 +1109,90 @@ static void print_queue_update_internal(int snum) * as little as possible... */ - slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name); + slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename); tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL)); +} + +/**************************************************************************** + Update the internal database from the system print queue for a queue. + obtain a lock on the print queue before proceeding (needed when mutiple + smbd processes maytry to update the lpq cache concurrently). +****************************************************************************/ + +static void print_queue_update_with_lock(int snum) +{ + fstring sharename, keystr; + pstring lpq_command; + struct tdb_print_db *pdb; + struct printif *current_printif = get_printer_fns( snum ); + + fstrcpy(sharename, lp_const_servicename(snum)); + pdb = get_print_db_byname(sharename); + if (!pdb) + return; + + /* + * Check to see if someone else is doing this update. + * This is essentially a mutex on the update. + */ + + if (get_updating_pid(sharename) != -1) { + release_print_db(pdb); + return; + } + + /* Lock the queue for the database update */ + + slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename); + /* Only wait 10 seconds for this. */ + if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) { + DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", sharename)); + release_print_db(pdb); + return; + } + + /* + * Ensure that no one else got in here. + * If the updating pid is still -1 then we are + * the winner. + */ + + if (get_updating_pid(sharename) != -1) { + /* + * Someone else is doing the update, exit. + */ + tdb_unlock_bystring(pdb->tdb, keystr); + release_print_db(pdb); + return; + } + + /* + * We're going to do the update ourselves. + */ + + /* Tell others we're doing the update. */ + set_updating_pid(sharename, False); + + /* + * Allow others to enter and notice we're doing + * the update. + */ + + tdb_unlock_bystring(pdb->tdb, keystr); + + /* do the main work now */ + /* have to substitute any variables here since + print_queue_get_internal() will not */ + + pstrcpy( lpq_command, lp_lpqcommand(snum) ); + pstring_sub( lpq_command, "%p", PRINTERNAME(snum) ); + standard_sub_snum( snum, lpq_command, sizeof(lpq_command) ); + + print_queue_update_internal( sharename, current_printif, lpq_command ); + /* Delete our pid from the db. */ - set_updating_pid(printer_name, True); + set_updating_pid(sharename, True); release_print_db(pdb); } @@ -1153,9 +1201,17 @@ this is the receive function of the background lpq updater ****************************************************************************/ static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len) { - int snum; - snum=*((int *)buf); - print_queue_update_internal(snum); + struct print_queue_update_context *ctx; + + if (len != sizeof(struct print_queue_update_context)) { + DEBUG(1, ("Got invalid print queue update message\n")); + return; + } + + ctx = (struct print_queue_update_context*)buf; + print_queue_update_internal(ctx->sharename, + get_printer_fns_from_type(ctx->printing_type), + ctx->lpqcommand ); } static pid_t background_lpq_updater_pid = -1; @@ -1207,6 +1263,10 @@ void start_background_queue(void) DEBUG(10,("start_background_queue: background LPQ thread got a message\n")); message_dispatch(); + + /* process any pending print change notify messages */ + + print_notify_send_messages(0); } } } @@ -1216,19 +1276,28 @@ update the internal database from the system print queue for a queue ****************************************************************************/ static void print_queue_update(int snum) { + struct print_queue_update_context ctx; + /* - * Make sure that the backgroup queueu process exists. + * Make sure that the background queue process exists. * Otherwise just do the update ourselves */ if ( background_lpq_updater_pid != -1 ) { + fstrcpy(ctx.sharename, lp_const_servicename(snum)); + ctx.printing_type = lp_printing(snum); + + pstrcpy(ctx.lpqcommand, lp_lpqcommand(snum)); + pstring_sub( ctx.lpqcommand, "%p", PRINTERNAME(snum) ); + standard_sub_snum( snum, ctx.lpqcommand, sizeof(ctx.lpqcommand) ); + become_root(); message_send_pid(background_lpq_updater_pid, - MSG_PRINTER_UPDATE, &snum, sizeof(snum), + MSG_PRINTER_UPDATE, &ctx, sizeof(ctx), False); unbecome_root(); } else - print_queue_update_internal( snum ); + print_queue_update_with_lock( snum ); } /**************************************************************************** @@ -1416,9 +1485,9 @@ list for printer %s\n", printername)); Check if a jobid is valid. It is valid if it exists in the database. ****************************************************************************/ -BOOL print_job_exists(int snum, uint32 jobid) +BOOL print_job_exists(const char* sharename, uint32 jobid) { - struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); + struct tdb_print_db *pdb = get_print_db_byname(sharename); BOOL ret; if (!pdb) @@ -1432,9 +1501,9 @@ BOOL print_job_exists(int snum, uint32 jobid) Give the fd used for a jobid. ****************************************************************************/ -int print_job_fd(int snum, uint32 jobid) +int print_job_fd(const char* sharename, uint32 jobid) { - struct printjob *pjob = print_job_find(snum, jobid); + struct printjob *pjob = print_job_find(sharename, jobid); if (!pjob) return -1; /* don't allow another process to get this info - it is meaningless */ @@ -1449,9 +1518,9 @@ int print_job_fd(int snum, uint32 jobid) has not been spooled. ****************************************************************************/ -char *print_job_fname(int snum, uint32 jobid) +char *print_job_fname(const char* sharename, uint32 jobid) { - struct printjob *pjob = print_job_find(snum, jobid); + struct printjob *pjob = print_job_find(sharename, jobid); if (!pjob || pjob->spooled || pjob->pid != sys_getpid()) return NULL; return pjob->filename; @@ -1464,9 +1533,9 @@ char *print_job_fname(int snum, uint32 jobid) has not been spooled. ****************************************************************************/ -NT_DEVICEMODE *print_job_devmode(int snum, uint32 jobid) +NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid) { - struct printjob *pjob = print_job_find(snum, jobid); + struct printjob *pjob = print_job_find(sharename, jobid); if ( !pjob ) return NULL; @@ -1490,22 +1559,24 @@ BOOL print_job_set_place(int snum, uint32 jobid, int place) BOOL print_job_set_name(int snum, uint32 jobid, char *name) { - struct printjob *pjob = print_job_find(snum, jobid); + const char* sharename = lp_const_servicename(snum); + struct printjob *pjob; + + pjob = print_job_find(sharename, jobid); if (!pjob || pjob->pid != sys_getpid()) return False; fstrcpy(pjob->jobname, name); - return pjob_store(snum, jobid, pjob); + return pjob_store(sharename, jobid, pjob); } /*************************************************************************** Remove a jobid from the 'jobs changed' list. ***************************************************************************/ -static BOOL remove_from_jobs_changed(int snum, uint32 jobid) +static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid) { - const char *printername = lp_const_servicename(snum); - struct tdb_print_db *pdb = get_print_db_byname(printername); + struct tdb_print_db *pdb = get_print_db_byname(sharename); TDB_DATA data, key; size_t job_count, i; BOOL ret = False; @@ -1560,10 +1631,13 @@ static BOOL remove_from_jobs_changed(int snum, uint32 jobid) static BOOL print_job_delete1(int snum, uint32 jobid) { - struct printjob *pjob = print_job_find(snum, jobid); + const char* sharename = lp_const_servicename(snum); + struct printjob *pjob = print_job_find(sharename, jobid); int result = 0; struct printif *current_printif = get_printer_fns( snum ); + pjob = print_job_find(sharename, jobid); + if (!pjob) return False; @@ -1584,7 +1658,7 @@ static BOOL print_job_delete1(int snum, uint32 jobid) /* Set the tdb entry to be deleting. */ pjob->status = LPQ_DELETING; - pjob_store(snum, jobid, pjob); + pjob_store(sharename, jobid, pjob); if (pjob->spooled && pjob->sysjob != -1) result = (*(current_printif->job_delete))(snum, pjob); @@ -1593,13 +1667,12 @@ static BOOL print_job_delete1(int snum, uint32 jobid) been spooled. */ if (result == 0) { - const char *printername = lp_const_servicename(snum); - struct tdb_print_db *pdb = get_print_db_byname(printername); + struct tdb_print_db *pdb = get_print_db_byname(sharename); int njobs = 1; if (!pdb) return False; - pjob_delete(snum, jobid); + pjob_delete(sharename, jobid); /* Ensure we keep a rough count of the number of total jobs... */ tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1); release_print_db(pdb); @@ -1614,7 +1687,7 @@ static BOOL print_job_delete1(int snum, uint32 jobid) static BOOL is_owner(struct current_user *user, int snum, uint32 jobid) { - struct printjob *pjob = print_job_find(snum, jobid); + struct printjob *pjob = print_job_find(lp_const_servicename(snum), jobid); user_struct *vuser; if (!pjob || !user) @@ -1633,6 +1706,7 @@ static BOOL is_owner(struct current_user *user, int snum, uint32 jobid) BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) { + const char* sharename = lp_const_servicename( snum ); BOOL owner, deleted; char *fname; @@ -1665,7 +1739,7 @@ pause, or resume print job. User name: %s. Printer name: %s.", * spool file & return. */ - if ( (fname = print_job_fname( snum, jobid )) != NULL ) + if ( (fname = print_job_fname( sharename, jobid )) != NULL ) { /* remove the spool file */ DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname )); @@ -1685,7 +1759,7 @@ pause, or resume print job. User name: %s. Printer name: %s.", print_queue_update(snum); - deleted = !print_job_exists(snum, jobid); + deleted = !print_job_exists(sharename, jobid); if ( !deleted ) *errcode = WERR_ACCESS_DENIED; @@ -1698,9 +1772,12 @@ pause, or resume print job. User name: %s. Printer name: %s.", BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) { - struct printjob *pjob = print_job_find(snum, jobid); + const char* sharename = lp_const_servicename(snum); + struct printjob *pjob; int ret = -1; struct printif *current_printif = get_printer_fns( snum ); + + pjob = print_job_find(sharename, jobid); if (!pjob || !user) return False; @@ -1736,7 +1813,7 @@ pause, or resume print job. User name: %s. Printer name: %s.", /* Send a printer notify message */ - notify_job_status(snum, jobid, JOB_STATUS_PAUSED); + notify_job_status(sharename, jobid, JOB_STATUS_PAUSED); /* how do we tell if this succeeded? */ @@ -1749,9 +1826,12 @@ pause, or resume print job. User name: %s. Printer name: %s.", BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) { - struct printjob *pjob = print_job_find(snum, jobid); + const char *sharename = lp_const_servicename(snum); + struct printjob *pjob; int ret; struct printif *current_printif = get_printer_fns( snum ); + + pjob = print_job_find(sharename, jobid); if (!pjob || !user) return False; @@ -1785,7 +1865,7 @@ pause, or resume print job. User name: %s. Printer name: %s.", /* Send a printer notify message */ - notify_job_status(snum, jobid, JOB_STATUS_QUEUED); + notify_job_status(sharename, jobid, JOB_STATUS_QUEUED); return True; } @@ -1796,8 +1876,11 @@ pause, or resume print job. User name: %s. Printer name: %s.", int print_job_write(int snum, uint32 jobid, const char *buf, int size) { + const char* sharename = lp_const_servicename(snum); int return_code; - struct printjob *pjob = print_job_find(snum, jobid); + struct printjob *pjob; + + pjob = print_job_find(sharename, jobid); if (!pjob) return -1; @@ -1808,7 +1891,7 @@ int print_job_write(int snum, uint32 jobid, const char *buf, int size) return_code = write(pjob->fd, buf, size); if (return_code>0) { pjob->size += size; - pjob_store(snum, jobid, pjob); + pjob_store(sharename, jobid, pjob); } return return_code; } @@ -1856,12 +1939,11 @@ static BOOL print_cache_expired(int snum) Get the queue status - do not update if db is out of date. ****************************************************************************/ -static int get_queue_status(int snum, print_status_struct *status) +static int get_queue_status(const char* sharename, print_status_struct *status) { fstring keystr; TDB_DATA data, key; - const char *printername = lp_const_servicename(snum); - struct tdb_print_db *pdb = get_print_db_byname(printername); + struct tdb_print_db *pdb = get_print_db_byname(sharename); int len; if (!pdb) @@ -1869,7 +1951,7 @@ static int get_queue_status(int snum, print_status_struct *status) if (status) { ZERO_STRUCTP(status); - slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername); + slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename); key.dptr = keystr; key.dsize = strlen(keystr); data = tdb_fetch(pdb->tdb, key); @@ -1892,6 +1974,7 @@ static int get_queue_status(int snum, print_status_struct *status) int print_queue_length(int snum, print_status_struct *pstatus) { + const char* sharename = lp_const_servicename( snum ); print_status_struct status; int len; @@ -1901,7 +1984,7 @@ int print_queue_length(int snum, print_status_struct *pstatus) /* also fetch the queue status */ memset(&status, 0, sizeof(status)); - len = get_queue_status(snum, &status); + len = get_queue_status(sharename, &status); if (pstatus) *pstatus = status; @@ -1913,7 +1996,7 @@ int print_queue_length(int snum, print_status_struct *pstatus) Allocate a jobid. Hold the lock for as short a time as possible. ***************************************************************************/ -static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *printername, uint32 *pjobid) +static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid) { int i; uint32 jobid; @@ -1923,14 +2006,14 @@ static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char for (i = 0; i < 3; i++) { /* Lock the database - only wait 20 seconds. */ if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) { - DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", printername )); + DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename)); return False; } if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) { if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) { DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n", - printername )); + sharename)); return False; } jobid = 0; @@ -1947,13 +2030,13 @@ static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char /* We've finished with the INFO/nextjob lock. */ tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); - if (!print_job_exists(snum, jobid)) + if (!print_job_exists(sharename, jobid)) break; } if (i > 2) { DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n", - printername )); + sharename)); /* Probably full... */ errno = ENOSPC; return False; @@ -2005,8 +2088,8 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE char *path; struct printjob pjob; user_struct *vuser; - const char *printername = lp_const_servicename(snum); - struct tdb_print_db *pdb = get_print_db_byname(printername); + const char *sharename = lp_const_servicename(snum); + struct tdb_print_db *pdb = get_print_db_byname(sharename); int njobs; errno = 0; @@ -2051,16 +2134,16 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE /* Insure the maximum queue size is not violated */ if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) { DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n", - printername, njobs, lp_maxprintjobs(snum) )); + sharename, njobs, lp_maxprintjobs(snum) )); release_print_db(pdb); errno = ENOSPC; return (uint32)-1; } DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n", - printername, njobs, lp_maxprintjobs(snum) )); + sharename, njobs, lp_maxprintjobs(snum) )); - if (!allocate_print_jobid(pdb, snum, printername, &jobid)) + if (!allocate_print_jobid(pdb, snum, sharename, &jobid)) goto fail; /* create the database entry */ @@ -2105,7 +2188,7 @@ to open spool file %s.\n", pjob.filename)); goto fail; } - pjob_store(snum, jobid, &pjob); + pjob_store(sharename, jobid, &pjob); /* Update the 'jobs changed' entry used by print_queue_status. */ add_to_jobs_changed(pdb, jobid); @@ -2119,7 +2202,7 @@ to open spool file %s.\n", pjob.filename)); fail: if (jobid != -1) - pjob_delete(snum, jobid); + pjob_delete(sharename, jobid); release_print_db(pdb); @@ -2133,7 +2216,10 @@ to open spool file %s.\n", pjob.filename)); void print_job_endpage(int snum, uint32 jobid) { - struct printjob *pjob = print_job_find(snum, jobid); + const char* sharename = lp_const_servicename(snum); + struct printjob *pjob; + + pjob = print_job_find(sharename, jobid); if (!pjob) return; /* don't allow another process to get this info - it is meaningless */ @@ -2141,7 +2227,7 @@ void print_job_endpage(int snum, uint32 jobid) return; pjob->page_count++; - pjob_store(snum, jobid, pjob); + pjob_store(sharename, jobid, pjob); } /**************************************************************************** @@ -2152,11 +2238,14 @@ void print_job_endpage(int snum, uint32 jobid) BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) { - struct printjob *pjob = print_job_find(snum, jobid); + const char* sharename = lp_const_servicename(snum); + struct printjob *pjob; int ret; SMB_STRUCT_STAT sbuf; struct printif *current_printif = get_printer_fns( snum ); + pjob = print_job_find(sharename, jobid); + if (!pjob) return False; @@ -2187,7 +2276,7 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) DEBUG(5,("print_job_end: canceling spool of %s (%s)\n", pjob->filename, pjob->size ? "deleted" : "zero length" )); unlink(pjob->filename); - pjob_delete(snum, jobid); + pjob_delete(sharename, jobid); return True; } @@ -2202,7 +2291,7 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) pjob->spooled = True; pjob->status = LPQ_QUEUED; - pjob_store(snum, jobid, pjob); + pjob_store(sharename, jobid, pjob); /* make sure the database is up to date */ if (print_cache_expired(snum)) @@ -2215,7 +2304,7 @@ fail: /* The print job was not succesfully started. Cleanup */ /* Still need to add proper error return propagation! 010122:JRR */ unlink(pjob->filename); - pjob_delete(snum, jobid); + pjob_delete(sharename, jobid); return False; } @@ -2234,6 +2323,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun uint32 i; int max_reported_jobs = lp_max_reported_jobs(snum); BOOL ret = False; + const char* sharename = lp_servicename(snum); /* make sure the database is up to date */ if (print_cache_expired(snum)) @@ -2300,10 +2390,10 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun jobid = IVAL(cgdata.dptr, i*4); DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid)); - pjob = print_job_find(snum, jobid); + pjob = print_job_find(lp_const_servicename(snum), jobid); if (!pjob) { DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid)); - remove_from_jobs_changed(snum, jobid); + remove_from_jobs_changed(sharename, jobid); continue; } @@ -2351,7 +2441,7 @@ int print_queue_status(int snum, { fstring keystr; TDB_DATA data, key; - const char *printername; + const char *sharename; struct tdb_print_db *pdb; int count = 0; @@ -2365,8 +2455,8 @@ int print_queue_status(int snum, return 0; *ppqueue = NULL; - printername = lp_const_servicename(snum); - pdb = get_print_db_byname(printername); + sharename = lp_const_servicename(snum); + pdb = get_print_db_byname(sharename); if (!pdb) return 0; @@ -2377,7 +2467,7 @@ int print_queue_status(int snum, */ ZERO_STRUCTP(status); - slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername); + slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename); key.dptr = keystr; key.dsize = strlen(keystr); data = tdb_fetch(pdb->tdb, key); -- cgit From 79f7373b3370b6629ac3aa309bc59c543599d0e9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Nov 2004 22:46:04 +0000 Subject: r3867: Fix from david.hu@hp.com - make a copy of an incoming message rather than indirecting into it as a struct (may not be on an even byte boundary). Bug #2052. Jeremy. (This used to be commit 8a91a69961622a31851f2394c591ddaa61a36000) --- source3/printing/printing.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 1e897c962a..ca83945065 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1201,17 +1201,17 @@ this is the receive function of the background lpq updater ****************************************************************************/ static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len) { - struct print_queue_update_context *ctx; + struct print_queue_update_context ctx; if (len != sizeof(struct print_queue_update_context)) { DEBUG(1, ("Got invalid print queue update message\n")); return; } - ctx = (struct print_queue_update_context*)buf; - print_queue_update_internal(ctx->sharename, - get_printer_fns_from_type(ctx->printing_type), - ctx->lpqcommand ); + memcpy(&ctx, buf, sizeof(struct print_queue_update_context)); + print_queue_update_internal(ctx.sharename, + get_printer_fns_from_type(ctx.printing_type), + ctx.lpqcommand ); } static pid_t background_lpq_updater_pid = -1; -- cgit From 90bd2b4fd0e57e98ca97bb3a170c079fabd13bef Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 1 Dec 2004 20:11:31 +0000 Subject: r4028: * prevent the background LPQ daemon from updating the print queue cache just because multiple smbd processes sent a message that it was out of date. * add some extra debug messages while trying to track down down jobs being left in the queue after printing has completed. (This used to be commit a64505d52fcb23374711e22b3df328c9a7848b84) --- source3/printing/printing.c | 148 +++++++++++++++++++++++++------------------- 1 file changed, 85 insertions(+), 63 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index ca83945065..9d9ebba950 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -43,10 +43,12 @@ static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid); jobids are assigned when a job starts spooling. */ -/*************************************************************************** - Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32 - bit RPC jobids.... JRA. -***************************************************************************/ +struct print_queue_update_context { + fstring sharename; + enum printing_types printing_type; + pstring lpqcommand; +}; + static TDB_CONTEXT *rap_tdb; static uint16 next_rap_jobid; @@ -55,6 +57,11 @@ struct rap_jobid_key { uint32 jobid; }; +/*************************************************************************** + Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32 + bit RPC jobids.... JRA. +***************************************************************************/ + uint16 pjobid_to_rap(const char* sharename, uint32 jobid) { uint16 rap_jobid; @@ -837,7 +844,7 @@ static pid_t get_updating_pid(fstring sharename) in the tdb. ****************************************************************************/ -static void set_updating_pid(const fstring sharename, BOOL delete) +static void set_updating_pid(const fstring sharename, BOOL updating) { fstring keystr; TDB_DATA key; @@ -853,8 +860,12 @@ static void set_updating_pid(const fstring sharename, BOOL delete) slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename); key.dptr = keystr; key.dsize = strlen(keystr); + + DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n", + updating ? "" : "not ", + sharename )); - if (delete) { + if ( !updating ) { tdb_delete(pdb->tdb, key); release_print_db(pdb); return; @@ -978,11 +989,46 @@ static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid } } -struct print_queue_update_context { - fstring sharename; - enum printing_types printing_type; - pstring lpqcommand; -}; +/**************************************************************************** + Check if the print queue has been updated recently enough. +****************************************************************************/ + +static BOOL print_cache_expired(const char *sharename) +{ + fstring key; + time_t last_qscan_time, time_now = time(NULL); + struct tdb_print_db *pdb = get_print_db_byname(sharename); + + if (!pdb) + return False; + + slprintf(key, sizeof(key), "CACHE/%s", sharename); + last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key); + + /* + * Invalidate the queue for 3 reasons. + * (1). last queue scan time == -1. + * (2). Current time - last queue scan time > allowed cache time. + * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default). + * This last test picks up machines for which the clock has been moved + * forward, an lpq scan done and then the clock moved back. Otherwise + * that last lpq scan would stay around for a loooong loooong time... :-). JRA. + */ + + if (last_qscan_time == ((time_t)-1) + || (time_now - last_qscan_time) >= lp_lpqcachetime() + || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) + { + DEBUG(3, ("print cache expired for queue %s " + "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", + sharename, (int)last_qscan_time, (int)time_now, + (int)lp_lpqcachetime() )); + release_print_db(pdb); + return True; + } + release_print_db(pdb); + return False; +} /**************************************************************************** main work for updating the lpq cahe for a printer queue @@ -1003,12 +1049,20 @@ static void print_queue_update_internal( const char *sharename, fstring keystr, cachestr; struct tdb_print_db *pdb = get_print_db_byname(sharename); + DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n", + sharename, current_printif->type, lpq_command)); + + if ( !print_cache_expired(sharename) ) { + DEBUG(5,("print_queue_update_internal: print cache for %s is still ok\n", sharename)); + return; + } + /* * Update the cache time FIRST ! Stops others even * attempting to get the lock and doing this * if the lpq takes a long time. */ - + slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename); tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL)); @@ -1019,8 +1073,8 @@ static void print_queue_update_internal( const char *sharename, current_printif->type, lpq_command, &queue, &status); - DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ? - "s" : "", sharename)); + DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n", + qcount, (qcount != 1) ? "s" : "", sharename)); /* Sort the queue by submission time otherwise they are displayed in hash order. */ @@ -1084,14 +1138,14 @@ static void print_queue_update_internal( const char *sharename, SAFE_FREE(tstruct.queue); - DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n", + DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n", sharename, tstruct.total_jobs )); tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs); get_queue_status(sharename, &old_status); if (old_status.qcount != qcount) - DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n", + DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n", old_status.qcount, qcount, sharename)); /* store the new queue status structure */ @@ -1128,6 +1182,8 @@ static void print_queue_update_with_lock(int snum) struct printif *current_printif = get_printer_fns( snum ); fstrcpy(sharename, lp_const_servicename(snum)); + + DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename)); pdb = get_print_db_byname(sharename); if (!pdb) return; @@ -1147,7 +1203,7 @@ static void print_queue_update_with_lock(int snum) slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename); /* Only wait 10 seconds for this. */ if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) { - DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", sharename)); + DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename)); release_print_db(pdb); return; } @@ -1172,7 +1228,7 @@ static void print_queue_update_with_lock(int snum) */ /* Tell others we're doing the update. */ - set_updating_pid(sharename, False); + set_updating_pid(sharename, True); /* * Allow others to enter and notice we're doing @@ -1192,7 +1248,7 @@ static void print_queue_update_with_lock(int snum) print_queue_update_internal( sharename, current_printif, lpq_command ); /* Delete our pid from the db. */ - set_updating_pid(sharename, True); + set_updating_pid(sharename, False); release_print_db(pdb); } @@ -1290,6 +1346,11 @@ static void print_queue_update(int snum) pstrcpy(ctx.lpqcommand, lp_lpqcommand(snum)); pstring_sub( ctx.lpqcommand, "%p", PRINTERNAME(snum) ); standard_sub_snum( snum, ctx.lpqcommand, sizeof(ctx.lpqcommand) ); + + DEBUG(10,("print_queue_update: Sending message -> printer = %s, " + "type = %d, lpq command = [%s]\n", + ctx.sharename, ctx.printing_type, ctx.lpqcommand )); + become_root(); message_send_pid(background_lpq_updater_pid, @@ -1896,45 +1957,6 @@ int print_job_write(int snum, uint32 jobid, const char *buf, int size) return return_code; } -/**************************************************************************** - Check if the print queue has been updated recently enough. -****************************************************************************/ - -static BOOL print_cache_expired(int snum) -{ - fstring key; - time_t last_qscan_time, time_now = time(NULL); - const char *printername = lp_const_servicename(snum); - struct tdb_print_db *pdb = get_print_db_byname(printername); - - if (!pdb) - return False; - - slprintf(key, sizeof(key), "CACHE/%s", printername); - last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key); - - /* - * Invalidate the queue for 3 reasons. - * (1). last queue scan time == -1. - * (2). Current time - last queue scan time > allowed cache time. - * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default). - * This last test picks up machines for which the clock has been moved - * forward, an lpq scan done and then the clock moved back. Otherwise - * that last lpq scan would stay around for a loooong loooong time... :-). JRA. - */ - - if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() || - last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) { - DEBUG(3, ("print cache expired for queue %s \ -(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername, - (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() )); - release_print_db(pdb); - return True; - } - release_print_db(pdb); - return False; -} - /**************************************************************************** Get the queue status - do not update if db is out of date. ****************************************************************************/ @@ -1979,7 +2001,7 @@ int print_queue_length(int snum, print_status_struct *pstatus) int len; /* make sure the database is up to date */ - if (print_cache_expired(snum)) + if (print_cache_expired(lp_const_servicename(snum))) print_queue_update(snum); /* also fetch the queue status */ @@ -2294,7 +2316,7 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) pjob_store(sharename, jobid, pjob); /* make sure the database is up to date */ - if (print_cache_expired(snum)) + if (print_cache_expired(lp_const_servicename(snum))) print_queue_update(snum); return True; @@ -2326,7 +2348,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun const char* sharename = lp_servicename(snum); /* make sure the database is up to date */ - if (print_cache_expired(snum)) + if (print_cache_expired(lp_const_servicename(snum))) print_queue_update(snum); *pcount = 0; @@ -2447,7 +2469,7 @@ int print_queue_status(int snum, /* make sure the database is up to date */ - if (print_cache_expired(snum)) + if (print_cache_expired(lp_const_servicename(snum))) print_queue_update(snum); /* return if we are done */ @@ -2547,7 +2569,7 @@ BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode) } /* make sure the database is up to date */ - if (print_cache_expired(snum)) + if (print_cache_expired(lp_const_servicename(snum))) print_queue_update(snum); /* Send a printer notify message */ -- cgit From acf9d61421faa6c0055d57fdee7db300dc5431aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Dec 2004 18:25:53 +0000 Subject: r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation functions so we can funnel through some well known functions. Should help greatly with malloc checking. HEAD patch to follow. Jeremy. (This used to be commit 620f2e608f70ba92f032720c031283d295c5c06a) --- source3/printing/printing.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 9d9ebba950..5c8790e34b 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -536,7 +536,7 @@ static BOOL pjob_store(const char* sharename, uint32 jobid, struct printjob *pjo if (buflen != len) { char *tb; - tb = (char *)Realloc(buf, len); + tb = (char *)SMB_REALLOC(buf, len); if (!tb) { DEBUG(0,("pjob_store: failed to enlarge buffer!\n")); goto done; @@ -934,7 +934,7 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct queue[i].fs_file); } - if ((data.dptr = malloc(data.dsize)) == NULL) + if ((data.dptr = SMB_MALLOC(data.dsize)) == NULL) return; len = 0; @@ -1423,7 +1423,7 @@ BOOL print_notify_register_pid(int snum) if (i == data.dsize) { /* We weren't in the list. Realloc. */ - data.dptr = Realloc(data.dptr, data.dsize + 8); + data.dptr = SMB_REALLOC(data.dptr, data.dsize + 8); if (!data.dptr) { DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n", printername)); @@ -2379,7 +2379,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun if (qcount == 0 && extra_count == 0) goto out; - if ((queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(qcount + extra_count))) == NULL) + if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL) goto out; /* Retrieve the linearised queue data. */ -- cgit From bc7142ce2373993e87511ff401815efd60b1c1dd Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 8 Dec 2004 03:02:29 +0000 Subject: r4094: BUG 2107: fix memory bloating caused by large numbers of print_queue_updates() requests sent via messages.tdb (This used to be commit 56b1110c71b17eeb2ebdb7d506d86deb6b81f0d5) --- source3/printing/printing.c | 171 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 136 insertions(+), 35 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 5c8790e34b..b5785440ae 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -44,9 +44,9 @@ static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid); */ struct print_queue_update_context { - fstring sharename; + char* sharename; enum printing_types printing_type; - pstring lpqcommand; + char* lpqcommand; }; @@ -993,16 +993,17 @@ static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid Check if the print queue has been updated recently enough. ****************************************************************************/ -static BOOL print_cache_expired(const char *sharename) +static BOOL print_cache_expired(const char *sharename, BOOL check_pending) { fstring key; time_t last_qscan_time, time_now = time(NULL); struct tdb_print_db *pdb = get_print_db_byname(sharename); + BOOL result = False; if (!pdb) return False; - slprintf(key, sizeof(key), "CACHE/%s", sharename); + snprintf(key, sizeof(key), "CACHE/%s", sharename); last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key); /* @@ -1019,15 +1020,37 @@ static BOOL print_cache_expired(const char *sharename) || (time_now - last_qscan_time) >= lp_lpqcachetime() || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) { - DEBUG(3, ("print cache expired for queue %s " + time_t msg_pending_time; + + DEBUG(4, ("print_cache_expired: cache expired for queue %s " "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", sharename, (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() )); - release_print_db(pdb); - return True; + + /* check if another smbd has already sent a message to update the + queue. Give the pending message one minute to clear and + then send another message anyways. Make sure to check for + clocks that have been run forward and then back again. */ + + snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename); + + if ( check_pending + && tdb_fetch_uint32( pdb->tdb, key, &msg_pending_time ) + && msg_pending_time > 0 + && msg_pending_time <= time_now + && (time_now - msg_pending_time) < 60 ) + { + DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n", + sharename)); + goto done; + } + + result = True; } + +done: release_print_db(pdb); - return False; + return result; } /**************************************************************************** @@ -1052,7 +1075,7 @@ static void print_queue_update_internal( const char *sharename, DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n", sharename, current_printif->type, lpq_command)); - if ( !print_cache_expired(sharename) ) { + if ( !print_cache_expired(sharename, False) ) { DEBUG(5,("print_queue_update_internal: print cache for %s is still ok\n", sharename)); return; } @@ -1166,6 +1189,20 @@ static void print_queue_update_internal( const char *sharename, slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename); tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL)); + /* clear the msg pending record for this queue */ + + snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename); + + if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) { + /* log a message but continue on */ + + DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n", + sharename)); + } + + release_print_db( pdb ); + + return; } /**************************************************************************** @@ -1255,19 +1292,31 @@ static void print_queue_update_with_lock(int snum) /**************************************************************************** this is the receive function of the background lpq updater ****************************************************************************/ -static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len) +static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msglen) { struct print_queue_update_context ctx; + fstring sharename; + pstring lpqcommand; + size_t len; + + len = tdb_unpack( buf, msglen, "fdP", + sharename, + &ctx.printing_type, + lpqcommand ); - if (len != sizeof(struct print_queue_update_context)) { - DEBUG(1, ("Got invalid print queue update message\n")); + if ( len == -1 ) { + DEBUG(0,("print_queue_receive: Got invalid print queue update message\n")); return; } - memcpy(&ctx, buf, sizeof(struct print_queue_update_context)); + ctx.sharename = sharename; + ctx.lpqcommand = lpqcommand; + print_queue_update_internal(ctx.sharename, get_printer_fns_from_type(ctx.printing_type), ctx.lpqcommand ); + + return; } static pid_t background_lpq_updater_pid = -1; @@ -1333,32 +1382,84 @@ update the internal database from the system print queue for a queue static void print_queue_update(int snum) { struct print_queue_update_context ctx; + fstring key; + fstring sharename; + pstring lpqcommand; + char *buffer = NULL; + size_t len = 0; + size_t newlen; + struct tdb_print_db *pdb; /* * Make sure that the background queue process exists. * Otherwise just do the update ourselves */ - - if ( background_lpq_updater_pid != -1 ) { - fstrcpy(ctx.sharename, lp_const_servicename(snum)); - ctx.printing_type = lp_printing(snum); + + if ( background_lpq_updater_pid == -1 ) { + print_queue_update_with_lock( snum ); + return; + } + + fstrcpy( sharename, lp_const_servicename(snum)); + + ctx.printing_type = lp_printing(snum); + + pstrcpy( lpqcommand, lp_lpqcommand(snum)); + pstring_sub( lpqcommand, "%p", PRINTERNAME(snum) ); + standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) ); + + ctx.sharename = SMB_STRDUP( sharename ); + ctx.lpqcommand = SMB_STRDUP( lpqcommand ); + + /* get the length */ + + len = tdb_pack( buffer, len, "fdP", + ctx.sharename, + ctx.printing_type, + ctx.lpqcommand ); - pstrcpy(ctx.lpqcommand, lp_lpqcommand(snum)); - pstring_sub( ctx.lpqcommand, "%p", PRINTERNAME(snum) ); - standard_sub_snum( snum, ctx.lpqcommand, sizeof(ctx.lpqcommand) ); + buffer = SMB_XMALLOC_ARRAY( char, len ); - DEBUG(10,("print_queue_update: Sending message -> printer = %s, " - "type = %d, lpq command = [%s]\n", - ctx.sharename, ctx.printing_type, ctx.lpqcommand )); + /* now pack the buffer */ + newlen = tdb_pack( buffer, len, "fdP", + ctx.sharename, + ctx.printing_type, + ctx.lpqcommand ); + + SMB_ASSERT( newlen == len ); + + DEBUG(10,("print_queue_update: Sending message -> printer = %s, " + "type = %d, lpq command = [%s]\n", + ctx.sharename, ctx.printing_type, ctx.lpqcommand )); + + /* here we set a msg pending record for other smbd processes + to throttle the number of duplicate print_queue_update msgs + sent. */ + + pdb = get_print_db_byname(sharename); + snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename); + + if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) { + /* log a message but continue on */ + + DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n", + sharename)); + } + + release_print_db( pdb ); + /* finally send the message */ - become_root(); - message_send_pid(background_lpq_updater_pid, - MSG_PRINTER_UPDATE, &ctx, sizeof(ctx), - False); - unbecome_root(); - } else - print_queue_update_with_lock( snum ); + become_root(); + message_send_pid(background_lpq_updater_pid, + MSG_PRINTER_UPDATE, buffer, len, False); + unbecome_root(); + + SAFE_FREE( ctx.sharename ); + SAFE_FREE( ctx.lpqcommand ); + SAFE_FREE( buffer ); + + return; } /**************************************************************************** @@ -2001,7 +2102,7 @@ int print_queue_length(int snum, print_status_struct *pstatus) int len; /* make sure the database is up to date */ - if (print_cache_expired(lp_const_servicename(snum))) + if (print_cache_expired(lp_const_servicename(snum), True)) print_queue_update(snum); /* also fetch the queue status */ @@ -2316,7 +2417,7 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) pjob_store(sharename, jobid, pjob); /* make sure the database is up to date */ - if (print_cache_expired(lp_const_servicename(snum))) + if (print_cache_expired(lp_const_servicename(snum), True)) print_queue_update(snum); return True; @@ -2348,7 +2449,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun const char* sharename = lp_servicename(snum); /* make sure the database is up to date */ - if (print_cache_expired(lp_const_servicename(snum))) + if (print_cache_expired(lp_const_servicename(snum), True)) print_queue_update(snum); *pcount = 0; @@ -2469,7 +2570,7 @@ int print_queue_status(int snum, /* make sure the database is up to date */ - if (print_cache_expired(lp_const_servicename(snum))) + if (print_cache_expired(lp_const_servicename(snum), True)) print_queue_update(snum); /* return if we are done */ @@ -2569,7 +2670,7 @@ BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode) } /* make sure the database is up to date */ - if (print_cache_expired(lp_const_servicename(snum))) + if (print_cache_expired(lp_const_servicename(snum), True)) print_queue_update(snum); /* Send a printer notify message */ -- cgit From d097ea490525e7a35739dae6a295fd03ba52cfc0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 5 Jan 2005 16:20:35 +0000 Subject: r4539: patch from Rob -- adding real printcap name cache function to speed up printcap reloads (This used to be commit 1cad5250932b963c2eb9b775221b13db386d601b) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index b5785440ae..67b9b9f22a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -2247,7 +2247,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE } /* for autoloaded printers, check that the printcap entry still exists */ - if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) { + if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) { DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) )); release_print_db(pdb); errno = ENOENT; -- cgit From 57e3af57fd9707156e9e5f18f6cb6095360cd51f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jan 2005 01:39:06 +0000 Subject: r4662: Fix from "Jerome Borsboom" to fix missing release reference for printer tdb. Jeremy. (This used to be commit 5942bb7737fe8efc452d59cda0d6e35e309c97b7) --- source3/printing/printing.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 67b9b9f22a..b4d0f3a44b 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1077,6 +1077,7 @@ static void print_queue_update_internal( const char *sharename, if ( !print_cache_expired(sharename, False) ) { DEBUG(5,("print_queue_update_internal: print cache for %s is still ok\n", sharename)); + release_print_db(pdb); return; } -- cgit From ad4fe018c2c6c6a57ea8a57911846afdc6c71bed Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 8 Mar 2005 17:22:39 +0000 Subject: r5691: wrapping the pause/resume/purge printer commands in {become,unbecome}_root() blocks. We've already done a print_access_check() to ensure the user is admin. The means that non-root users can pause and manage printers. I really don't see how this worked before without setuid binaries on the server. Also update print_queue_update() interface to allow an smbd to update the print queue cache locally rather than going through the bg lpq daemon. This is needed for things like pjob_delete() to ensure the cache is current for the specific client. (This used to be commit f75369ec865f4ba1ae8201ae750c0f45158ed536) --- source3/printing/printing.c | 115 ++++++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 53 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index b4d0f3a44b..5483005e1b 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -810,7 +810,7 @@ static void print_cache_flush(int snum) Check if someone already thinks they are doing the update. ****************************************************************************/ -static pid_t get_updating_pid(fstring sharename) +static pid_t get_updating_pid(const char *sharename) { fstring keystr; TDB_DATA data, key; @@ -1075,12 +1075,6 @@ static void print_queue_update_internal( const char *sharename, DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n", sharename, current_printif->type, lpq_command)); - if ( !print_cache_expired(sharename, False) ) { - DEBUG(5,("print_queue_update_internal: print cache for %s is still ok\n", sharename)); - release_print_db(pdb); - return; - } - /* * Update the cache time FIRST ! Stops others even * attempting to get the lock and doing this @@ -1212,20 +1206,24 @@ static void print_queue_update_internal( const char *sharename, smbd processes maytry to update the lpq cache concurrently). ****************************************************************************/ -static void print_queue_update_with_lock(int snum) +static void print_queue_update_with_lock( const char *sharename, + struct printif *current_printif, + char *lpq_command ) { - fstring sharename, keystr; - pstring lpq_command; + fstring keystr; struct tdb_print_db *pdb; - struct printif *current_printif = get_printer_fns( snum ); - - fstrcpy(sharename, lp_const_servicename(snum)); DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename)); pdb = get_print_db_byname(sharename); if (!pdb) return; + if ( !print_cache_expired(sharename, False) ) { + DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename)); + release_print_db(pdb); + return; + } + /* * Check to see if someone else is doing this update. * This is essentially a mutex on the update. @@ -1276,12 +1274,6 @@ static void print_queue_update_with_lock(int snum) tdb_unlock_bystring(pdb->tdb, keystr); /* do the main work now */ - /* have to substitute any variables here since - print_queue_get_internal() will not */ - - pstrcpy( lpq_command, lp_lpqcommand(snum) ); - pstring_sub( lpq_command, "%p", PRINTERNAME(snum) ); - standard_sub_snum( snum, lpq_command, sizeof(lpq_command) ); print_queue_update_internal( sharename, current_printif, lpq_command ); @@ -1313,7 +1305,7 @@ static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msgle ctx.sharename = sharename; ctx.lpqcommand = lpqcommand; - print_queue_update_internal(ctx.sharename, + print_queue_update_with_lock(ctx.sharename, get_printer_fns_from_type(ctx.printing_type), ctx.lpqcommand ); @@ -1380,9 +1372,9 @@ void start_background_queue(void) /**************************************************************************** update the internal database from the system print queue for a queue ****************************************************************************/ -static void print_queue_update(int snum) + +static void print_queue_update(int snum, BOOL force) { - struct print_queue_update_context ctx; fstring key; fstring sharename; pstring lpqcommand; @@ -1390,48 +1382,49 @@ static void print_queue_update(int snum) size_t len = 0; size_t newlen; struct tdb_print_db *pdb; + enum printing_types type; + struct printif *current_printif; + fstrcpy( sharename, lp_const_servicename(snum)); + + pstrcpy( lpqcommand, lp_lpqcommand(snum)); + pstring_sub( lpqcommand, "%p", PRINTERNAME(snum) ); + standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) ); + /* * Make sure that the background queue process exists. * Otherwise just do the update ourselves */ - if ( background_lpq_updater_pid == -1 ) { - print_queue_update_with_lock( snum ); + if ( force || background_lpq_updater_pid == -1 ) { + DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename)); + current_printif = get_printer_fns( snum ); + print_queue_update_with_lock( sharename, current_printif, lpqcommand ); + return; } - fstrcpy( sharename, lp_const_servicename(snum)); - - ctx.printing_type = lp_printing(snum); - - pstrcpy( lpqcommand, lp_lpqcommand(snum)); - pstring_sub( lpqcommand, "%p", PRINTERNAME(snum) ); - standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) ); - - ctx.sharename = SMB_STRDUP( sharename ); - ctx.lpqcommand = SMB_STRDUP( lpqcommand ); - + type = lp_printing(snum); + /* get the length */ len = tdb_pack( buffer, len, "fdP", - ctx.sharename, - ctx.printing_type, - ctx.lpqcommand ); + sharename, + type, + lpqcommand ); buffer = SMB_XMALLOC_ARRAY( char, len ); /* now pack the buffer */ newlen = tdb_pack( buffer, len, "fdP", - ctx.sharename, - ctx.printing_type, - ctx.lpqcommand ); + sharename, + type, + lpqcommand ); SMB_ASSERT( newlen == len ); DEBUG(10,("print_queue_update: Sending message -> printer = %s, " - "type = %d, lpq command = [%s]\n", - ctx.sharename, ctx.printing_type, ctx.lpqcommand )); + "type = %d, lpq command = [%s]\n", sharename, type, lpqcommand )); /* here we set a msg pending record for other smbd processes to throttle the number of duplicate print_queue_update msgs @@ -1456,8 +1449,6 @@ static void print_queue_update(int snum) MSG_PRINTER_UPDATE, buffer, len, False); unbecome_root(); - SAFE_FREE( ctx.sharename ); - SAFE_FREE( ctx.lpqcommand ); SAFE_FREE( buffer ); return; @@ -1920,7 +1911,7 @@ pause, or resume print job. User name: %s. Printer name: %s.", /* force update the database and say the delete failed if the job still exists */ - print_queue_update(snum); + print_queue_update(snum, True); deleted = !print_job_exists(sharename, jobid); if ( !deleted ) @@ -2104,7 +2095,7 @@ int print_queue_length(int snum, print_status_struct *pstatus) /* make sure the database is up to date */ if (print_cache_expired(lp_const_servicename(snum), True)) - print_queue_update(snum); + print_queue_update(snum, False); /* also fetch the queue status */ memset(&status, 0, sizeof(status)); @@ -2419,7 +2410,7 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) /* make sure the database is up to date */ if (print_cache_expired(lp_const_servicename(snum), True)) - print_queue_update(snum); + print_queue_update(snum, False); return True; @@ -2451,7 +2442,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun /* make sure the database is up to date */ if (print_cache_expired(lp_const_servicename(snum), True)) - print_queue_update(snum); + print_queue_update(snum, False); *pcount = 0; *ppqueue = NULL; @@ -2572,7 +2563,7 @@ int print_queue_status(int snum, /* make sure the database is up to date */ if (print_cache_expired(lp_const_servicename(snum), True)) - print_queue_update(snum); + print_queue_update(snum, False); /* return if we are done */ if ( !ppqueue || !status ) @@ -2631,9 +2622,14 @@ BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode) *errcode = WERR_ACCESS_DENIED; return False; } + + become_root(); + ret = (*(current_printif->queue_pause))(snum); + unbecome_root(); + if (ret != 0) { *errcode = WERR_INVALID_PARAM; return False; @@ -2662,9 +2658,13 @@ BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode) *errcode = WERR_ACCESS_DENIED; return False; } - + + become_root(); + ret = (*(current_printif->queue_resume))(snum); + unbecome_root(); + if (ret != 0) { *errcode = WERR_INVALID_PARAM; return False; @@ -2672,7 +2672,7 @@ BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode) /* make sure the database is up to date */ if (print_cache_expired(lp_const_servicename(snum), True)) - print_queue_update(snum); + print_queue_update(snum, True); /* Send a printer notify message */ @@ -2693,10 +2693,13 @@ BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode) BOOL can_job_admin; /* Force and update so the count is accurate (i.e. not a cached count) */ - print_queue_update(snum); + print_queue_update(snum, True); can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER); njobs = print_queue_status(snum, &queue, &status); + + if ( can_job_admin ) + become_root(); for (i=0;i Date: Sat, 12 Mar 2005 09:58:35 +0000 Subject: r5770: Get rid of some compiler warnings (This used to be commit 96a0f7d60c973e9f74ac90e3c79f94a01770f681) --- source3/printing/printing.c | 45 +++++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 28 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 5483005e1b..b45a31a1c7 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -907,7 +907,7 @@ static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2) static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts) { - TDB_DATA data, key; + TDB_DATA data; int max_reported_jobs = lp_max_reported_jobs(pts->snum); print_queue_struct *queue = pts->queue; size_t len; @@ -951,22 +951,19 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct queue[i].fs_file); } - key.dptr = "INFO/linear_queue_array"; - key.dsize = strlen(key.dptr); - tdb_store(pdb->tdb, key, data, TDB_REPLACE); + tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data, + TDB_REPLACE); SAFE_FREE(data.dptr); return; } static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb) { - TDB_DATA data, key; + TDB_DATA data; - key.dptr = "INFO/jobs_changed"; - key.dsize = strlen(key.dptr); ZERO_STRUCT(data); - data = tdb_fetch(pdb->tdb, key); + data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed")); if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) { SAFE_FREE(data.dptr); ZERO_STRUCT(data); @@ -1736,11 +1733,11 @@ static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid) BOOL ret = False; BOOL gotlock = False; - key.dptr = "INFO/jobs_changed"; - key.dsize = strlen(key.dptr); ZERO_STRUCT(data); - if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1) + if (tdb_chainlock_with_timeout(pdb->tdb, + string_tdb_data("INFO/jobs_changed"), + 5) == -1) goto out; gotlock = True; @@ -2057,7 +2054,7 @@ int print_job_write(int snum, uint32 jobid, const char *buf, int size) static int get_queue_status(const char* sharename, print_status_struct *status) { fstring keystr; - TDB_DATA data, key; + TDB_DATA data; struct tdb_print_db *pdb = get_print_db_byname(sharename); int len; @@ -2066,10 +2063,8 @@ static int get_queue_status(const char* sharename, print_status_struct *status) if (status) { ZERO_STRUCTP(status); - slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename); - key.dptr = keystr; - key.dsize = strlen(keystr); - data = tdb_fetch(pdb->tdb, key); + fstr_sprintf(keystr, "STATUS/%s", sharename); + data = tdb_fetch(pdb->tdb, string_tdb_data(keystr)); if (data.dptr) { if (data.dsize == sizeof(print_status_struct)) /* this memcpy is ok since the status struct was @@ -2179,18 +2174,17 @@ static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid) { - TDB_DATA data, key; + TDB_DATA data; uint32 store_jobid; - key.dptr = "INFO/jobs_changed"; - key.dsize = strlen(key.dptr); SIVAL(&store_jobid, 0, jobid); data.dptr = (char *)&store_jobid; data.dsize = 4; DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid )); - return (tdb_append(pdb->tdb, key, data) == 0); + return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"), + data) == 0); } /*************************************************************************** @@ -2429,7 +2423,7 @@ fail: static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue) { - TDB_DATA data, key, cgdata; + TDB_DATA data, cgdata; print_queue_struct *queue = NULL; uint32 qcount = 0; uint32 extra_count = 0; @@ -2449,20 +2443,15 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun ZERO_STRUCT(data); ZERO_STRUCT(cgdata); - key.dptr = "INFO/linear_queue_array"; - key.dsize = strlen(key.dptr); /* Get the stored queue data. */ - data = tdb_fetch(pdb->tdb, key); + data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array")); if (data.dptr && data.dsize >= sizeof(qcount)) len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount); /* Get the changed jobs list. */ - key.dptr = "INFO/jobs_changed"; - key.dsize = strlen(key.dptr); - - cgdata = tdb_fetch(pdb->tdb, key); + cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed")); if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0)) extra_count = cgdata.dsize/4; -- cgit From cacc3e18885f55a49a066d5e3eb602473ea76898 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 15 Mar 2005 20:27:17 +0000 Subject: r5807: fix segfault after compiler warning clean up (and cleanup another warning) (This used to be commit 2dae527e217ff9da2ad9f434bf1280744e93fad7) --- source3/printing/printing.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index b45a31a1c7..26d4311770 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1032,7 +1032,7 @@ static BOOL print_cache_expired(const char *sharename, BOOL check_pending) snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename); if ( check_pending - && tdb_fetch_uint32( pdb->tdb, key, &msg_pending_time ) + && tdb_fetch_uint32( pdb->tdb, key, (uint32*)&msg_pending_time ) && msg_pending_time > 0 && msg_pending_time <= time_now && (time_now - msg_pending_time) < 60 ) @@ -1735,9 +1735,9 @@ static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid) ZERO_STRUCT(data); - if (tdb_chainlock_with_timeout(pdb->tdb, - string_tdb_data("INFO/jobs_changed"), - 5) == -1) + key = string_tdb_data("INFO/jobs_changed"); + + if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1) goto out; gotlock = True; -- cgit From 9b38ced168d4db50126c4259b31cb15e2ee2231b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 22 Mar 2005 14:54:12 +0000 Subject: r5950: more compiler warning's from Jason Mader (This used to be commit 27c6e85ad59a86ab45ae3297c7445c4ff15546c8) --- source3/printing/printing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 26d4311770..7a68fa16be 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -235,7 +235,7 @@ void printing_end(void) when asked for (and only when supported) ****************************************************************************/ -static struct printif *get_printer_fns_from_type( enum printing_types type ) +static struct printif *get_printer_fns_from_type( int type ) { struct printif *printer_fns = &generic_printif; @@ -1379,7 +1379,7 @@ static void print_queue_update(int snum, BOOL force) size_t len = 0; size_t newlen; struct tdb_print_db *pdb; - enum printing_types type; + int type; struct printif *current_printif; fstrcpy( sharename, lp_const_servicename(snum)); -- cgit From a49c567d4a6983098c74c23e3e65acbcbea1721b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 23 Mar 2005 14:28:27 +0000 Subject: r5993: compiler warning fix (This used to be commit 4e8b868e6e29513a0c4c1b8992a502d5b6cf2c3d) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 7a68fa16be..572ecb373a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -45,7 +45,7 @@ static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid); struct print_queue_update_context { char* sharename; - enum printing_types printing_type; + int printing_type; char* lpqcommand; }; -- cgit From fd237d99031d2903e62364fbafcff2b57636a9f6 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 26 Apr 2005 14:14:16 +0000 Subject: r6490: BUG 1998: patch from Olaf Imig ; fix byte ordering bug when storing 16-bit RAP print job ids (This used to be commit 2c66a4098a3c9ca0a12160d4193d65085ece1dfe) --- source3/printing/printing.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 572ecb373a..03bdb7d421 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -67,6 +67,7 @@ uint16 pjobid_to_rap(const char* sharename, uint32 jobid) uint16 rap_jobid; TDB_DATA data, key; struct rap_jobid_key jinfo; + uint8 buf[2]; DEBUG(10,("pjobid_to_rap: called.\n")); @@ -96,7 +97,8 @@ uint16 pjobid_to_rap(const char* sharename, uint32 jobid) rap_jobid = ++next_rap_jobid; if (rap_jobid == 0) rap_jobid = ++next_rap_jobid; - data.dptr = (char *)&rap_jobid; + SSVAL(buf,0,rap_jobid); + data.dptr = buf; data.dsize = sizeof(rap_jobid); tdb_store(rap_tdb, key, data, TDB_REPLACE); tdb_store(rap_tdb, data, key, TDB_REPLACE); @@ -109,13 +111,15 @@ uint16 pjobid_to_rap(const char* sharename, uint32 jobid) BOOL rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid) { TDB_DATA data, key; + uint8 buf[2]; DEBUG(10,("rap_to_pjobid called.\n")); if (!rap_tdb) return False; - key.dptr = (char *)&rap_jobid; + SSVAL(buf,0,rap_jobid); + key.dptr = buf; key.dsize = sizeof(rap_jobid); data = tdb_fetch(rap_tdb, key); if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) ) @@ -140,6 +144,7 @@ static void rap_jobid_delete(const char* sharename, uint32 jobid) TDB_DATA key, data; uint16 rap_jobid; struct rap_jobid_key jinfo; + uint8 buf[2]; DEBUG(10,("rap_jobid_delete: called.\n")); @@ -165,7 +170,8 @@ static void rap_jobid_delete(const char* sharename, uint32 jobid) rap_jobid = SVAL(data.dptr, 0); SAFE_FREE(data.dptr); - data.dptr = (char *)&rap_jobid; + SSVAL(buf,0,rap_jobid); + data.dptr=buf; data.dsize = sizeof(rap_jobid); tdb_delete(rap_tdb, key); tdb_delete(rap_tdb, data); -- cgit From fe0ce8dd8e18de6110404661f26db7a66ebac5ad Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 18 May 2005 18:02:15 +0000 Subject: r6890: Refactor printing interface to take offset into job. Fixes bug where large print jobs can have out-of-order offsets. Bug found by Arcady Chernyak Jeremy. (This used to be commit 482f7e0e3706098b71aa0b31a134994acb1e9fcf) --- source3/printing/printing.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 03bdb7d421..ab86db53f3 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -2031,7 +2031,7 @@ pause, or resume print job. User name: %s. Printer name: %s.", Write to a print file. ****************************************************************************/ -int print_job_write(int snum, uint32 jobid, const char *buf, int size) +ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size) { const char* sharename = lp_const_servicename(snum); int return_code; @@ -2045,7 +2045,8 @@ int print_job_write(int snum, uint32 jobid, const char *buf, int size) if (pjob->pid != sys_getpid()) return -1; - return_code = write(pjob->fd, buf, size); + return_code = write_data_at_offset(pjob->fd, buf, size, pos); + if (return_code>0) { pjob->size += size; pjob_store(sharename, jobid, pjob); -- cgit From 18dc1009e61873017237eee0ff2e032f913d7357 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 22 Jun 2005 02:51:22 +0000 Subject: r7829: fix unitialized printer status field that was breaking migration of print queues (This used to be commit ada1d326aeef4a2f33a360a8ea4a874e59fcfee6) --- source3/printing/printing.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index ab86db53f3..0737cf00d1 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -2094,6 +2094,8 @@ int print_queue_length(int snum, print_status_struct *pstatus) const char* sharename = lp_const_servicename( snum ); print_status_struct status; int len; + + ZERO_STRUCT( status ); /* make sure the database is up to date */ if (print_cache_expired(lp_const_servicename(snum), True)) -- cgit From eb1123e5009c900c0eb741c0a075f918b16bbeab Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 15 Jul 2005 17:38:55 +0000 Subject: r8506: BUG 2853: don't strip out characters like '$' from printer names when substituting for the lpq command. (This used to be commit 2f5de718a98e56fe55d8905b12505dfc3e432544) --- source3/printing/printing.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 0737cf00d1..b49f0716ea 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -43,13 +43,6 @@ static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid); jobids are assigned when a job starts spooling. */ -struct print_queue_update_context { - char* sharename; - int printing_type; - char* lpqcommand; -}; - - static TDB_CONTEXT *rap_tdb; static uint16 next_rap_jobid; struct rap_jobid_key { @@ -1290,14 +1283,14 @@ this is the receive function of the background lpq updater ****************************************************************************/ static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msglen) { - struct print_queue_update_context ctx; fstring sharename; pstring lpqcommand; + int printing_type; size_t len; len = tdb_unpack( buf, msglen, "fdP", sharename, - &ctx.printing_type, + &printing_type, lpqcommand ); if ( len == -1 ) { @@ -1305,12 +1298,9 @@ static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msgle return; } - ctx.sharename = sharename; - ctx.lpqcommand = lpqcommand; - - print_queue_update_with_lock(ctx.sharename, - get_printer_fns_from_type(ctx.printing_type), - ctx.lpqcommand ); + print_queue_update_with_lock(sharename, + get_printer_fns_from_type(printing_type), + lpqcommand ); return; } @@ -1390,8 +1380,10 @@ static void print_queue_update(int snum, BOOL force) fstrcpy( sharename, lp_const_servicename(snum)); + /* don't strip out characters like '$' from the printername */ + pstrcpy( lpqcommand, lp_lpqcommand(snum)); - pstring_sub( lpqcommand, "%p", PRINTERNAME(snum) ); + string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), False ); standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) ); /* -- cgit From 0b98400cc0b8fa51f995d6cb90382b5f2526b3f5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 21 Jul 2005 17:40:20 +0000 Subject: r8686: Revert %LOGONSERVER%-substitution. The substition is done on the client, not on the server. We now preserve this windows variable (important for vampired setups) and correctly substitute only the "%L"s in strings like: "%LOGONSERVER% %L %lOgOnSeRvEr% %L". Guenther (This used to be commit dccf777f42ce1d3f788548842fb8a606bed5708c) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index b49f0716ea..2a7cd5d3a7 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1383,7 +1383,7 @@ static void print_queue_update(int snum, BOOL force) /* don't strip out characters like '$' from the printername */ pstrcpy( lpqcommand, lp_lpqcommand(snum)); - string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), False ); + string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), False, False ); standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) ); /* -- cgit From 4ae6b9765f5a60e22bb4dc00d328b3d739941aba Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 11 Aug 2005 20:44:18 +0000 Subject: r9244: Fix bugs found by Coverity. Jeremy. (This used to be commit bf80edeea70cb4ed90f9e1e7adeedeb9cf3b38c1) --- source3/printing/printing.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 2a7cd5d3a7..52a3070466 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -399,8 +399,10 @@ uint32 sysjob_to_jobid(int unix_jobid) if (!lp_print_ok(snum)) continue; pdb = get_print_db_byname(lp_const_servicename(snum)); - if (pdb) - tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid); + if (!pdb) { + continue; + } + tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid); release_print_db(pdb); if (sysjob_to_jobid_value != (uint32)-1) return sysjob_to_jobid_value; @@ -1067,6 +1069,10 @@ static void print_queue_update_internal( const char *sharename, TDB_DATA jcdata; fstring keystr, cachestr; struct tdb_print_db *pdb = get_print_db_byname(sharename); + + if (!pdb) { + return; + } DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n", sharename, current_printif->type, lpq_command)); @@ -1426,6 +1432,11 @@ static void print_queue_update(int snum, BOOL force) sent. */ pdb = get_print_db_byname(sharename); + if (!pdb) { + SAFE_FREE(buffer); + return; + } + snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename); if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) { @@ -1731,6 +1742,10 @@ static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid) BOOL ret = False; BOOL gotlock = False; + if (!pdb) { + return False; + } + ZERO_STRUCT(data); key = string_tdb_data("INFO/jobs_changed"); @@ -2057,11 +2072,14 @@ static int get_queue_status(const char* sharename, print_status_struct *status) struct tdb_print_db *pdb = get_print_db_byname(sharename); int len; + if (status) { + ZERO_STRUCTP(status); + } + if (!pdb) return 0; if (status) { - ZERO_STRUCTP(status); fstr_sprintf(keystr, "STATUS/%s", sharename); data = tdb_fetch(pdb->tdb, string_tdb_data(keystr)); if (data.dptr) { -- cgit From c762908074c45baacde1df04b633e01308030864 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Sep 2005 23:28:22 +0000 Subject: r10371: Adding iPrint printing backend written by Joel J. Smith @ Novell. Jeremy. (This used to be commit 155dc2d52a971bfb8d7565c06f3efc637e130b11) --- source3/printing/printing.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 52a3070466..397ed3b355 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -244,6 +244,12 @@ static struct printif *get_printer_fns_from_type( int type ) } #endif /* HAVE_CUPS */ +#ifdef HAVE_IPRINT + if ( type == PRINT_IPRINT ) { + printer_fns = &iprint_printif; + } +#endif /* HAVE_IPRINT */ + printer_fns->type = type; return printer_fns; -- cgit From 291963446795813098fc1c89bf7e4db55414806f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 27 Sep 2005 19:34:19 +0000 Subject: r10555: a few compile warnings from jason Mader (This used to be commit 88998fa0b919fec4966d171a9c7b4f875bc1e26a) --- source3/printing/printing.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 397ed3b355..61470f1510 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -91,7 +91,7 @@ uint16 pjobid_to_rap(const char* sharename, uint32 jobid) if (rap_jobid == 0) rap_jobid = ++next_rap_jobid; SSVAL(buf,0,rap_jobid); - data.dptr = buf; + data.dptr = (char*)buf; data.dsize = sizeof(rap_jobid); tdb_store(rap_tdb, key, data, TDB_REPLACE); tdb_store(rap_tdb, data, key, TDB_REPLACE); @@ -112,7 +112,7 @@ BOOL rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid) return False; SSVAL(buf,0,rap_jobid); - key.dptr = buf; + key.dptr = (char*)buf; key.dsize = sizeof(rap_jobid); data = tdb_fetch(rap_tdb, key); if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) ) @@ -164,7 +164,7 @@ static void rap_jobid_delete(const char* sharename, uint32 jobid) rap_jobid = SVAL(data.dptr, 0); SAFE_FREE(data.dptr); SSVAL(buf,0,rap_jobid); - data.dptr=buf; + data.dptr = (char*)buf; data.dsize = sizeof(rap_jobid); tdb_delete(rap_tdb, key); tdb_delete(rap_tdb, data); -- cgit From 54abd2aa66069e6baf7769c496f46d9dba18db39 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 30 Sep 2005 17:13:37 +0000 Subject: r10656: BIG merge from trunk. Features not copied over * \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3) --- source3/printing/printing.c | 159 +++++++++++++++++++++++++++++++------------- 1 file changed, 113 insertions(+), 46 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 61470f1510..6e74095f71 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -691,6 +691,8 @@ struct traverse_struct { int qcount, snum, maxcount, total_jobs; const char *sharename; time_t lpq_time; + const char *lprm_command; + struct printif *print_if; }; /**************************************************************************** @@ -737,7 +739,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void /* if a job is not spooled and the process doesn't exist then kill it. This cleans up after smbd deaths */ - if (!process_exists(pjob.pid)) { + if (!process_exists_by_pid(pjob.pid)) { DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n", (unsigned int)jobid, (unsigned int)pjob.pid )); pjob_delete(ts->sharename, jobid); @@ -750,9 +752,38 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void if ( pjob.smbjob ) { for (i=0;iqcount;i++) { - uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file); - if (jobid == curr_jobid) + uint32 curr_jobid; + + if ( pjob.status == LPQ_DELETED ) + continue; + + curr_jobid = print_parse_jobid(ts->queue[i].fs_file); + + if (jobid == curr_jobid) { + + /* try to clean up any jobs that need to be deleted */ + + if ( pjob.status == LPQ_DELETING ) { + int result; + + result = (*(ts->print_if->job_delete))( + ts->sharename, ts->lprm_command, &pjob ); + + if ( result != 0 ) { + /* if we can't delete, then reset the job status */ + pjob.status = LPQ_QUEUED; + pjob_store(ts->sharename, jobid, &pjob); + } + else { + /* if we deleted the job, the remove the tdb record */ + pjob_delete(ts->sharename, jobid); + pjob.status = LPQ_DELETED; + } + + } + break; + } } } @@ -779,9 +810,10 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void return 0; } - /* Save the pjob attributes we will store. */ - /* FIXME!!! This is the only place where queue->job + /* Save the pjob attributes we will store. + FIXME!!! This is the only place where queue->job represents the SMB jobid --jerry */ + ts->queue[i].job = jobid; ts->queue[i].size = pjob.size; ts->queue[i].page_count = pjob.page_count; @@ -840,7 +872,7 @@ static pid_t get_updating_pid(const char *sharename) updating_pid = IVAL(data.dptr, 0); SAFE_FREE(data.dptr); - if (process_exists(updating_pid)) + if (process_exists_by_pid(updating_pid)) return updating_pid; return (pid_t)-1; @@ -910,6 +942,7 @@ static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2) /**************************************************************************** Store the sorted queue representation for later portmon retrieval. + Skip deleted jobs ****************************************************************************/ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts) @@ -923,13 +956,17 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct if (max_reported_jobs && (max_reported_jobs < pts->qcount)) pts->qcount = max_reported_jobs; - qcount = pts->qcount; + qcount = 0; /* Work out the size. */ data.dsize = 0; data.dsize += tdb_pack(NULL, 0, "d", qcount); for (i = 0; i < pts->qcount; i++) { + if ( queue[i].status == LPQ_DELETED ) + continue; + + qcount++; data.dsize += tdb_pack(NULL, 0, "ddddddff", (uint32)queue[i].job, (uint32)queue[i].size, @@ -947,6 +984,9 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct len = 0; len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount); for (i = 0; i < pts->qcount; i++) { + if ( queue[i].status == LPQ_DELETED ) + continue; + len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff", (uint32)queue[i].job, (uint32)queue[i].size, @@ -1024,6 +1064,7 @@ static BOOL print_cache_expired(const char *sharename, BOOL check_pending) || (time_now - last_qscan_time) >= lp_lpqcachetime() || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) { + uint32 u; time_t msg_pending_time; DEBUG(4, ("print_cache_expired: cache expired for queue %s " @@ -1039,8 +1080,8 @@ static BOOL print_cache_expired(const char *sharename, BOOL check_pending) snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename); if ( check_pending - && tdb_fetch_uint32( pdb->tdb, key, (uint32*)&msg_pending_time ) - && msg_pending_time > 0 + && tdb_fetch_uint32( pdb->tdb, key, &u ) + && (msg_pending_time=u) > 0 && msg_pending_time <= time_now && (time_now - msg_pending_time) < 60 ) { @@ -1063,7 +1104,7 @@ done: static void print_queue_update_internal( const char *sharename, struct printif *current_printif, - char *lpq_command ) + char *lpq_command, char *lprm_command ) { int i, qcount; print_queue_struct *queue = NULL; @@ -1141,8 +1182,14 @@ static void print_queue_update_internal( const char *sharename, } pjob->sysjob = queue[i].job; - pjob->status = queue[i].status; + + /* don't reset the status on jobs to be deleted */ + + if ( pjob->status != LPQ_DELETING ) + pjob->status = queue[i].status; + pjob_store(sharename, jobid, pjob); + check_job_changed(sharename, jcdata, jobid); } @@ -1156,6 +1203,8 @@ static void print_queue_update_internal( const char *sharename, tstruct.total_jobs = 0; tstruct.lpq_time = time(NULL); tstruct.sharename = sharename; + tstruct.lprm_command = lprm_command; + tstruct.print_if = current_printif; tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct); @@ -1216,7 +1265,7 @@ static void print_queue_update_internal( const char *sharename, static void print_queue_update_with_lock( const char *sharename, struct printif *current_printif, - char *lpq_command ) + char *lpq_command, char *lprm_command ) { fstring keystr; struct tdb_print_db *pdb; @@ -1283,7 +1332,8 @@ static void print_queue_update_with_lock( const char *sharename, /* do the main work now */ - print_queue_update_internal( sharename, current_printif, lpq_command ); + print_queue_update_internal( sharename, current_printif, + lpq_command, lprm_command ); /* Delete our pid from the db. */ set_updating_pid(sharename, False); @@ -1293,17 +1343,19 @@ static void print_queue_update_with_lock( const char *sharename, /**************************************************************************** this is the receive function of the background lpq updater ****************************************************************************/ -static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msglen) +static void print_queue_receive(int msg_type, struct process_id src, + void *buf, size_t msglen) { fstring sharename; - pstring lpqcommand; + pstring lpqcommand, lprmcommand; int printing_type; size_t len; - len = tdb_unpack( buf, msglen, "fdP", + len = tdb_unpack( buf, msglen, "fdPP", sharename, &printing_type, - lpqcommand ); + lpqcommand, + lprmcommand ); if ( len == -1 ) { DEBUG(0,("print_queue_receive: Got invalid print queue update message\n")); @@ -1312,7 +1364,7 @@ static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msgle print_queue_update_with_lock(sharename, get_printer_fns_from_type(printing_type), - lpqcommand ); + lpqcommand, lprmcommand ); return; } @@ -1382,7 +1434,7 @@ static void print_queue_update(int snum, BOOL force) { fstring key; fstring sharename; - pstring lpqcommand; + pstring lpqcommand, lprmcommand; char *buffer = NULL; size_t len = 0; size_t newlen; @@ -1398,6 +1450,10 @@ static void print_queue_update(int snum, BOOL force) string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), False, False ); standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) ); + pstrcpy( lprmcommand, lp_lprmcommand(snum)); + string_sub2( lprmcommand, "%p", PRINTERNAME(snum), sizeof(lprmcommand), False, False ); + standard_sub_snum( snum, lprmcommand, sizeof(lprmcommand) ); + /* * Make sure that the background queue process exists. * Otherwise just do the update ourselves @@ -1406,7 +1462,7 @@ static void print_queue_update(int snum, BOOL force) if ( force || background_lpq_updater_pid == -1 ) { DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename)); current_printif = get_printer_fns( snum ); - print_queue_update_with_lock( sharename, current_printif, lpqcommand ); + print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand ); return; } @@ -1415,23 +1471,26 @@ static void print_queue_update(int snum, BOOL force) /* get the length */ - len = tdb_pack( buffer, len, "fdP", + len = tdb_pack( buffer, len, "fdPP", sharename, type, - lpqcommand ); + lpqcommand, + lprmcommand ); buffer = SMB_XMALLOC_ARRAY( char, len ); /* now pack the buffer */ - newlen = tdb_pack( buffer, len, "fdP", + newlen = tdb_pack( buffer, len, "fdPP", sharename, type, - lpqcommand ); + lpqcommand, + lprmcommand ); SMB_ASSERT( newlen == len ); DEBUG(10,("print_queue_update: Sending message -> printer = %s, " - "type = %d, lpq command = [%s]\n", sharename, type, lpqcommand )); + "type = %d, lpq command = [%s] lprm command = [%s]\n", + sharename, type, lpqcommand, lprmcommand )); /* here we set a msg pending record for other smbd processes to throttle the number of duplicate print_queue_update msgs @@ -1457,7 +1516,7 @@ static void print_queue_update(int snum, BOOL force) /* finally send the message */ become_root(); - message_send_pid(background_lpq_updater_pid, + message_send_pid(pid_to_procid(background_lpq_updater_pid), MSG_PRINTER_UPDATE, buffer, len, False); unbecome_root(); @@ -1806,8 +1865,6 @@ static BOOL print_job_delete1(int snum, uint32 jobid) int result = 0; struct printif *current_printif = get_printer_fns( snum ); - pjob = print_job_find(sharename, jobid); - if (!pjob) return False; @@ -1819,7 +1876,9 @@ static BOOL print_job_delete1(int snum, uint32 jobid) return True; /* Hrm - we need to be able to cope with deleting a job before it - has reached the spooler. */ + has reached the spooler. Just mark it as LPQ_DELETING and + let the print_queue_update() code rmeove the record */ + if (pjob->sysjob == -1) { DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid)); @@ -1830,24 +1889,31 @@ static BOOL print_job_delete1(int snum, uint32 jobid) pjob->status = LPQ_DELETING; pjob_store(sharename, jobid, pjob); - if (pjob->spooled && pjob->sysjob != -1) - result = (*(current_printif->job_delete))(snum, pjob); + if (pjob->spooled && pjob->sysjob != -1) + { + result = (*(current_printif->job_delete))( + PRINTERNAME(snum), + lp_lprmcommand(snum), + pjob); - /* Delete the tdb entry if the delete succeeded or the job hasn't - been spooled. */ + /* Delete the tdb entry if the delete succeeded or the job hasn't + been spooled. */ - if (result == 0) { - struct tdb_print_db *pdb = get_print_db_byname(sharename); - int njobs = 1; + if (result == 0) { + struct tdb_print_db *pdb = get_print_db_byname(sharename); + int njobs = 1; - if (!pdb) - return False; - pjob_delete(sharename, jobid); - /* Ensure we keep a rough count of the number of total jobs... */ - tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1); - release_print_db(pdb); + if (!pdb) + return False; + pjob_delete(sharename, jobid); + /* Ensure we keep a rough count of the number of total jobs... */ + tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1); + release_print_db(pdb); + } } + remove_from_jobs_changed( sharename, jobid ); + return (result == 0); } @@ -1877,7 +1943,8 @@ static BOOL is_owner(struct current_user *user, int snum, uint32 jobid) BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) { const char* sharename = lp_const_servicename( snum ); - BOOL owner, deleted; + struct printjob *pjob; + BOOL owner; char *fname; *errcode = WERR_OK; @@ -1929,11 +1996,11 @@ pause, or resume print job. User name: %s. Printer name: %s.", print_queue_update(snum, True); - deleted = !print_job_exists(sharename, jobid); - if ( !deleted ) + pjob = print_job_find(sharename, jobid); + if ( pjob && (pjob->status != LPQ_DELETING) ) *errcode = WERR_ACCESS_DENIED; - return deleted; + return (pjob == NULL ); } /**************************************************************************** -- cgit From d14af63e6ab600eb3ac705f2f425c860e927553a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 2 Feb 2006 20:44:50 +0000 Subject: r13293: Rather a big patch I'm afraid, but this should fix bug #3347 by saving the UNIX token used to set a delete on close flag, and using it when doing the delete. libsmbsharemodes.so still needs updating to cope with this change. Samba4 torture tests to follow. Jeremy. (This used to be commit 23f16cbc2e8cde97c486831e26bcafd4ab4a9654) --- source3/printing/printing.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 6e74095f71..82b9a7f74e 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1932,7 +1932,7 @@ static BOOL is_owner(struct current_user *user, int snum, uint32 jobid) if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { return strequal(pjob->user, vuser->user.smb_name); } else { - return strequal(pjob->user, uidtoname(user->uid)); + return strequal(pjob->user, uidtoname(user->ut.uid)); } } @@ -1963,7 +1963,7 @@ BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR sys_adminlog( LOG_ERR, "Permission denied-- user not allowed to delete, \ pause, or resume print job. User name: %s. Printer name: %s.", - uidtoname(user->uid), PRINTERNAME(snum) ); + uidtoname(user->ut.uid), PRINTERNAME(snum) ); /* END_ADMIN_LOG */ return False; @@ -2030,7 +2030,7 @@ BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR * sys_adminlog( LOG_ERR, "Permission denied-- user not allowed to delete, \ pause, or resume print job. User name: %s. Printer name: %s.", - uidtoname(user->uid), PRINTERNAME(snum) ); + uidtoname(user->ut.uid), PRINTERNAME(snum) ); /* END_ADMIN_LOG */ *errcode = WERR_ACCESS_DENIED; @@ -2085,7 +2085,7 @@ BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR sys_adminlog( LOG_ERR, "Permission denied-- user not allowed to delete, \ pause, or resume print job. User name: %s. Printer name: %s.", - uidtoname(user->uid), PRINTERNAME(snum) ); + uidtoname(user->ut.uid), PRINTERNAME(snum) ); /* END_ADMIN_LOG */ return False; } @@ -2366,7 +2366,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { fstrcpy(pjob.user, vuser->user.smb_name); } else { - fstrcpy(pjob.user, uidtoname(user->uid)); + fstrcpy(pjob.user, uidtoname(user->ut.uid)); } fstrcpy(pjob.queuename, lp_const_servicename(snum)); @@ -2437,7 +2437,7 @@ void print_job_endpage(int snum, uint32 jobid) error. ****************************************************************************/ -BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) +BOOL print_job_end(int snum, uint32 jobid, enum file_close_type close_type) { const char* sharename = lp_const_servicename(snum); struct printjob *pjob; @@ -2453,7 +2453,8 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) if (pjob->spooled || pjob->pid != sys_getpid()) return False; - if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) { + if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) && + (sys_fstat(pjob->fd, &sbuf) == 0)) { pjob->size = sbuf.st_size; close(pjob->fd); pjob->fd = -1; -- cgit From cab298856ab1179cdaec2ef89121f7c66c6b6d76 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 22 Feb 2006 10:28:02 +0000 Subject: r13622: Allow to rename machine accounts in a Samba Domain. This still uses the "rename user script" to do the rename of the posix machine account (this might be changed later). Fixes #2331. Guenther (This used to be commit b2eac2e6eb6ddd1bcb4ed5172e7cd64144c18d16) --- source3/printing/printing.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 82b9a7f74e..315034879e 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1447,11 +1447,13 @@ static void print_queue_update(int snum, BOOL force) /* don't strip out characters like '$' from the printername */ pstrcpy( lpqcommand, lp_lpqcommand(snum)); - string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), False, False ); + string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), + False, False, False ); standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) ); pstrcpy( lprmcommand, lp_lprmcommand(snum)); - string_sub2( lprmcommand, "%p", PRINTERNAME(snum), sizeof(lprmcommand), False, False ); + string_sub2( lprmcommand, "%p", PRINTERNAME(snum), sizeof(lprmcommand), + False, False, False ); standard_sub_snum( snum, lprmcommand, sizeof(lprmcommand) ); /* -- cgit From 894358a8f3e338b339b6c37233edef794b312087 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Mar 2006 06:31:04 +0000 Subject: r13915: Fixed a very interesting class of realloc() bugs found by Coverity. realloc can return NULL in one of two cases - (1) the realloc failed, (2) realloc succeeded but the new size requested was zero, in which case this is identical to a free() call. The error paths dealing with these two cases should be different, but mostly weren't. Secondly the standard idiom for dealing with realloc when you know the new size is non-zero is the following : tmp = realloc(p, size); if (!tmp) { SAFE_FREE(p); return error; } else { p = tmp; } However, there were *many* *many* places in Samba where we were using the old (broken) idiom of : p = realloc(p, size) if (!p) { return error; } which will leak the memory pointed to by p on realloc fail. This commit (hopefully) fixes all these cases by moving to a standard idiom of : p = SMB_REALLOC(p, size) if (!p) { return error; } Where if the realloc returns null due to the realloc failing or size == 0 we *guarentee* that the storage pointed to by p has been freed. This allows me to remove a lot of code that was dealing with the standard (more verbose) method that required a tmp pointer. This is almost always what you want. When a realloc fails you never usually want the old memory, you want to free it and get into your error processing asap. For the 11 remaining cases where we really do need to keep the old pointer I have invented the new macro SMB_REALLOC_KEEP_OLD_ON_ERROR, which can be used as follows : tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size); if (!tmp) { SAFE_FREE(p); return error; } else { p = tmp; } SMB_REALLOC_KEEP_OLD_ON_ERROR guarentees never to free the pointer p, even on size == 0 or realloc fail. All this is done by a hidden extra argument to Realloc(), BOOL free_old_on_error which is set appropriately by the SMB_REALLOC and SMB_REALLOC_KEEP_OLD_ON_ERROR macros (and their array counterparts). It remains to be seen what this will do to our Coverity bug count :-). Jeremy. (This used to be commit 1d710d06a214f3f1740e80e0bffd6aab44aac2b0) --- source3/printing/printing.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 315034879e..452031368d 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -541,15 +541,11 @@ static BOOL pjob_store(const char* sharename, uint32 jobid, struct printjob *pjo len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len); if (buflen != len) { - char *tb; - - tb = (char *)SMB_REALLOC(buf, len); - if (!tb) { + buf = (char *)SMB_REALLOC(buf, len); + if (!buf) { DEBUG(0,("pjob_store: failed to enlarge buffer!\n")); goto done; } - else - buf = tb; newlen = len; } } while ( buflen != len ); -- cgit From 4fa555980070d78b39711ef21d77628d26055bc2 Mon Sep 17 00:00:00 2001 From: James Peach Date: Tue, 4 Apr 2006 00:27:50 +0000 Subject: r14898: This change is an attempt to improve the quality of the information that is produced when a process exits abnormally. First, we coalesce the core dumping code so that we greatly improve our odds of being able to produce a core file, even in the case of a memory fault. I've removed duplicates of dump_core() and split it in two to reduce the amount of work needed to actually do the dump. Second, we refactor the exit_server code path to always log an explanation and a stack trace. My goal is to always produce enough log information for us to be able to explain any server exit, though there is a risk that this could produce too much log information on a flaky network. Finally, smbcontrol has gained a smbd fault injection operation to test the changes above. This is only enabled for developer builds. (This used to be commit 56bc02d64498eb3faf89f0c5452b9299daea8e95) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 452031368d..0448eac3cd 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1400,7 +1400,7 @@ void start_background_queue(void) /* check for some essential signals first */ if (got_sig_term) { - exit_server("Caught TERM signal"); + exit_server_cleanly(); } if (reload_after_sighup) { -- cgit From cc8ba23e8d503c41ccd316f5b1d64d927cece2b8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Apr 2006 22:57:12 +0000 Subject: r15025: Fix exit_server_cleanly call. Jeremy. (This used to be commit a64976b94482ef4397d5b791a0e266edba5a3d0c) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 0448eac3cd..d9acd2de72 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1400,7 +1400,7 @@ void start_background_queue(void) /* check for some essential signals first */ if (got_sig_term) { - exit_server_cleanly(); + exit_server_cleanly(NULL); } if (reload_after_sighup) { -- cgit From e17302200c138eec7df504a7f4b2bde46073a810 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 17 Apr 2006 11:49:06 +0000 Subject: r15101: Little step towards getting Samba4 tdb into 3: tdb_lock_bystring does not have the timeout argument in Samba4. Add a new routine tdb_lock_bystring_with_timeout. Volker (This used to be commit b9c6e3f55602fa505859a4b2cd137b74105d685f) --- source3/printing/printing.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index d9acd2de72..b131727f8a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -197,7 +197,7 @@ BOOL print_backend_init(void) pdb = get_print_db_byname(lp_const_servicename(snum)); if (!pdb) continue; - if (tdb_lock_bystring(pdb->tdb, sversion, 0) == -1) { + if (tdb_lock_bystring(pdb->tdb, sversion) == -1) { DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) )); release_print_db(pdb); return False; @@ -1291,7 +1291,7 @@ static void print_queue_update_with_lock( const char *sharename, slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename); /* Only wait 10 seconds for this. */ - if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) { + if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) { DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename)); release_print_db(pdb); return; @@ -1563,7 +1563,7 @@ BOOL print_notify_register_pid(int snum) tdb = pdb->tdb; } - if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { + if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n", printername)); if (pdb) @@ -1653,7 +1653,7 @@ BOOL print_notify_deregister_pid(int snum) tdb = pdb->tdb; } - if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { + if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { DEBUG(0,("print_notify_register_pid: Failed to lock \ printer %s database\n", printername)); if (pdb) @@ -2205,7 +2205,7 @@ static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char for (i = 0; i < 3; i++) { /* Lock the database - only wait 20 seconds. */ - if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) { + if (tdb_lock_bystring_with_timeout(pdb->tdb, "INFO/nextjob", 20) == -1) { DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename)); return False; } -- cgit From 2e8b3ca0cb6956e5ce28fcafe85f6951a8955cd5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 14 Jun 2006 02:06:28 +0000 Subject: r16216: Add debug messages to make it possible to try and debug why a job pause or resume command is not being done. Jeremy. (This used to be commit e6aacb1426bd04c4006f7be66228f9f8d9a7065d) --- source3/printing/printing.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index b131727f8a..c7ca917af0 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -337,27 +337,38 @@ static struct printjob *print_job_find(const char *sharename, uint32 jobid) TDB_DATA ret; struct tdb_print_db *pdb = get_print_db_byname(sharename); + DEBUG(10,("print_job_find: looking up job %u for share %s\n", + (unsigned int)jobid, sharename )); - if (!pdb) + if (!pdb) { return NULL; + } ret = tdb_fetch(pdb->tdb, print_key(jobid)); release_print_db(pdb); - if (!ret.dptr) + if (!ret.dptr) { + DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid )); return NULL; + } - if ( pjob.nt_devmode ) + if ( pjob.nt_devmode ) { free_nt_devicemode( &pjob.nt_devmode ); + } ZERO_STRUCT( pjob ); if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) { + DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid )); SAFE_FREE(ret.dptr); return NULL; } - SAFE_FREE(ret.dptr); + SAFE_FREE(ret.dptr); + + DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n", + (int)pjob.sysjob, (unsigned int)jobid )); + return &pjob; } @@ -2014,11 +2025,17 @@ BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR * pjob = print_job_find(sharename, jobid); - if (!pjob || !user) + if (!pjob || !user) { + DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n", + (unsigned int)jobid )); return False; + } - if (!pjob->spooled || pjob->sysjob == -1) + if (!pjob->spooled || pjob->sysjob == -1) { + DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n", + (int)pjob->sysjob, (unsigned int)jobid )); return False; + } if (!is_owner(user, snum, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { @@ -2068,11 +2085,17 @@ BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR pjob = print_job_find(sharename, jobid); - if (!pjob || !user) + if (!pjob || !user) { + DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n", + (unsigned int)jobid )); return False; + } - if (!pjob->spooled || pjob->sysjob == -1) + if (!pjob->spooled || pjob->sysjob == -1) { + DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n", + (int)pjob->sysjob, (unsigned int)jobid )); return False; + } if (!is_owner(user, snum, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { -- cgit From fc77e332e3be72d208ff33aa6ea0849b5a62b349 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Jun 2006 02:02:26 +0000 Subject: r16599: Make it clear to Klocwork we're not dereferencing. Issue #2026. Jeremy. (This used to be commit 9402bf0d4cc6d04283ed69a6dedac7767df84626) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index c7ca917af0..fed9c005d0 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1480,7 +1480,7 @@ static void print_queue_update(int snum, BOOL force) /* get the length */ - len = tdb_pack( buffer, len, "fdPP", + len = tdb_pack( NULL, 0, "fdPP", sharename, type, lpqcommand, -- cgit From 57ba729facf9fe83c15d4490ff62020f5c429c0f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Jun 2006 17:26:48 +0000 Subject: r16626: Fix bug #3878. Reported by jason@ncac.gwu.edu. Jeremy. (This used to be commit 4c3019eb99d0a18a33ef1fa90d01b9c99c0b25c3) --- source3/printing/printing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index fed9c005d0..d06b34454a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -234,7 +234,7 @@ void printing_end(void) when asked for (and only when supported) ****************************************************************************/ -static struct printif *get_printer_fns_from_type( int type ) +static struct printif *get_printer_fns_from_type( enum printing_types type ) { struct printif *printer_fns = &generic_printif; @@ -257,7 +257,7 @@ static struct printif *get_printer_fns_from_type( int type ) static struct printif *get_printer_fns( int snum ) { - return get_printer_fns_from_type( lp_printing(snum) ); + return get_printer_fns_from_type( (enum printing_types)lp_printing(snum) ); } -- cgit From e5f766aac82dee8474d66580626033b6018c4108 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Jun 2006 21:35:46 +0000 Subject: r16648: Fix bug #3889 reported by jason@ncac.gwu.edu. Jeremy. (This used to be commit 2eefe9b6f52e64927c0ae23adce111a42d821206) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index d06b34454a..9dd6bec0be 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1370,7 +1370,7 @@ static void print_queue_receive(int msg_type, struct process_id src, } print_queue_update_with_lock(sharename, - get_printer_fns_from_type(printing_type), + get_printer_fns_from_type((enum printing_types)printing_type), lpqcommand, lprmcommand ); return; -- cgit From fbdcf2663b56007a438ac4f0d8d82436b1bfe688 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jul 2006 18:01:26 +0000 Subject: r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need to do the upper layer directories but this is what everyone is waiting for.... Jeremy. (This used to be commit 9dafb7f48ca3e7af956b0a7d1720c2546fc4cfb8) --- source3/printing/printing.c | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 9dd6bec0be..bb756c8870 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -839,10 +839,9 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void Check if the print queue has been updated recently enough. ****************************************************************************/ -static void print_cache_flush(int snum) +static void print_cache_flush(const char *sharename) { fstring key; - const char *sharename = lp_const_servicename(snum); struct tdb_print_db *pdb = get_print_db_byname(sharename); if (!pdb) @@ -1439,6 +1438,8 @@ update the internal database from the system print queue for a queue static void print_queue_update(int snum, BOOL force) { + extern struct current_user current_user; + extern userdom_struct current_user_info; fstring key; fstring sharename; pstring lpqcommand, lprmcommand; @@ -1456,12 +1457,22 @@ static void print_queue_update(int snum, BOOL force) pstrcpy( lpqcommand, lp_lpqcommand(snum)); string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), False, False, False ); - standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) ); + standard_sub_advanced(lp_servicename(snum), + current_user_info.unix_name, "", + current_user.ut.gid, + get_current_username(), + current_user_info.domain, + lpqcommand, sizeof(lpqcommand) ); pstrcpy( lprmcommand, lp_lprmcommand(snum)); string_sub2( lprmcommand, "%p", PRINTERNAME(snum), sizeof(lprmcommand), False, False, False ); - standard_sub_snum( snum, lprmcommand, sizeof(lprmcommand) ); + standard_sub_advanced(lp_servicename(snum), + current_user_info.unix_name, "", + current_user.ut.gid, + get_current_username(), + current_user_info.domain, + lprmcommand, sizeof(lprmcommand) ); /* * Make sure that the background queue process exists. @@ -1781,7 +1792,7 @@ NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid) Set the place in the queue for a job. ****************************************************************************/ -BOOL print_job_set_place(int snum, uint32 jobid, int place) +BOOL print_job_set_place(const char *sharename, uint32 jobid, int place) { DEBUG(2,("print_job_set_place not implemented yet\n")); return False; @@ -1791,9 +1802,8 @@ BOOL print_job_set_place(int snum, uint32 jobid, int place) Set the name of a job. Only possible for owner. ****************************************************************************/ -BOOL print_job_set_name(int snum, uint32 jobid, char *name) +BOOL print_job_set_name(const char *sharename, uint32 jobid, char *name) { - const char* sharename = lp_const_servicename(snum); struct printjob *pjob; pjob = print_job_find(sharename, jobid); @@ -1930,9 +1940,10 @@ static BOOL print_job_delete1(int snum, uint32 jobid) Return true if the current user owns the print job. ****************************************************************************/ -static BOOL is_owner(struct current_user *user, int snum, uint32 jobid) +static BOOL is_owner(struct current_user *user, const char *servicename, + uint32 jobid) { - struct printjob *pjob = print_job_find(lp_const_servicename(snum), jobid); + struct printjob *pjob = print_job_find(servicename, jobid); user_struct *vuser; if (!pjob || !user) @@ -1958,7 +1969,7 @@ BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode = WERR_OK; - owner = is_owner(user, snum, jobid); + owner = is_owner(user, lp_const_servicename(snum), jobid); /* Check access against security descriptor or whether the user owns their job. */ @@ -2037,7 +2048,7 @@ BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR * return False; } - if (!is_owner(user, snum, jobid) && + if (!is_owner(user, lp_const_servicename(snum), jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("pause denied by security descriptor\n")); @@ -2061,7 +2072,7 @@ pause, or resume print job. User name: %s. Printer name: %s.", } /* force update the database */ - print_cache_flush(snum); + print_cache_flush(lp_const_servicename(snum)); /* Send a printer notify message */ @@ -2097,7 +2108,7 @@ BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR return False; } - if (!is_owner(user, snum, jobid) && + if (!is_owner(user, lp_const_servicename(snum), jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("resume denied by security descriptor\n")); *errcode = WERR_ACCESS_DENIED; @@ -2119,7 +2130,7 @@ pause, or resume print job. User name: %s. Printer name: %s.", } /* force update the database */ - print_cache_flush(snum); + print_cache_flush(lp_const_servicename(snum)); /* Send a printer notify message */ @@ -2325,7 +2336,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE return (uint32)-1; } - if (!print_time_access_check(snum)) { + if (!print_time_access_check(lp_servicename(snum))) { DEBUG(3, ("print_job_start: job start denied by time check\n")); release_print_db(pdb); return (uint32)-1; @@ -2739,7 +2750,7 @@ BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode) } /* force update the database */ - print_cache_flush(snum); + print_cache_flush(lp_const_servicename(snum)); /* Send a printer notify message */ @@ -2805,7 +2816,7 @@ BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode) become_root(); for (i=0;i Date: Fri, 28 Jul 2006 22:42:39 +0000 Subject: r17293: After the results from the cluster tests in Germany, fix the messaging code to call the efficient calls : save_re_uid() set_effective_uid(0); messaging_op restore_re_uid(); instead of using heavyweight become_root()/unbecome_root() pairs around all messaging code. Fixup the messaging code to ensure sec_init() is called (only once) so that non-root processes still work when sending messages. This is a lighter weight solution to become_root()/unbecome_root() (which swaps all the supplemental groups) and should be more efficient. I will migrate all server code over to using this (a similar technique should be used in the passdb backend where needed). Jeremy. (This used to be commit 4ace291278d9a44f5c577bdd3b282c1231e543df) --- source3/printing/printing.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index bb756c8870..fbb8166565 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1535,10 +1535,8 @@ static void print_queue_update(int snum, BOOL force) /* finally send the message */ - become_root(); message_send_pid(pid_to_procid(background_lpq_updater_pid), MSG_PRINTER_UPDATE, buffer, len, False); - unbecome_root(); SAFE_FREE( buffer ); -- cgit From 08e308fe2cdf6b9c7d7c96f3e29ff7209a4a63a9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 17 Aug 2006 14:28:03 +0000 Subject: r17590: Some C++ Warnings (This used to be commit b7ec240880af0072ef20b2c0d688ef3cc386d484) --- source3/printing/printing.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index fbb8166565..0d9ae02545 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -271,7 +271,7 @@ static TDB_DATA print_key(uint32 jobid) TDB_DATA ret; SIVAL(&j, 0, jobid); - ret.dptr = (void *)&j; + ret.dptr = (char *)&j; ret.dsize = sizeof(j); return ret; } @@ -917,7 +917,7 @@ static void set_updating_pid(const fstring sharename, BOOL updating) } SIVAL( buffer, 0, updating_pid); - data.dptr = (void *)buffer; + data.dptr = (char *)buffer; data.dsize = 4; /* we always assume this is a 4 byte value */ tdb_store(pdb->tdb, key, data, TDB_REPLACE); @@ -984,7 +984,7 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct queue[i].fs_file); } - if ((data.dptr = SMB_MALLOC(data.dsize)) == NULL) + if ((data.dptr = (char *)SMB_MALLOC(data.dsize)) == NULL) return; len = 0; @@ -1235,7 +1235,7 @@ static void print_queue_update_internal( const char *sharename, key.dsize = strlen(keystr); status.qcount = qcount; - data.dptr = (void *)&status; + data.dptr = (char *)&status; data.dsize = sizeof(status); tdb_store(pdb->tdb, key, data, TDB_REPLACE); @@ -1357,7 +1357,7 @@ static void print_queue_receive(int msg_type, struct process_id src, int printing_type; size_t len; - len = tdb_unpack( buf, msglen, "fdPP", + len = tdb_unpack( (char *)buf, msglen, "fdPP", sharename, &printing_type, lpqcommand, @@ -1605,7 +1605,7 @@ BOOL print_notify_register_pid(int snum) if (i == data.dsize) { /* We weren't in the list. Realloc. */ - data.dptr = SMB_REALLOC(data.dptr, data.dsize + 8); + data.dptr = (char *)SMB_REALLOC(data.dptr, data.dsize + 8); if (!data.dptr) { DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n", printername)); -- cgit From 791f48f167de339c8ae371e5c80706511fd10018 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 12 Dec 2006 17:38:42 +0000 Subject: r20124: clean up nested extern declaration warnings (This used to be commit ac3eb7813e33b9a2e78c9158433f7ed62c3b62bb) --- source3/printing/printing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 0d9ae02545..2f1d123a20 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -25,6 +25,8 @@ extern SIG_ATOMIC_T got_sig_term; extern SIG_ATOMIC_T reload_after_sighup; +extern struct current_user current_user; +extern userdom_struct current_user_info; /* Current printer interface */ static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid); @@ -1438,8 +1440,6 @@ update the internal database from the system print queue for a queue static void print_queue_update(int snum, BOOL force) { - extern struct current_user current_user; - extern userdom_struct current_user_info; fstring key; fstring sharename; pstring lpqcommand, lprmcommand; -- cgit From caf8c6a76be051559ffcfe97084edca43e0a3cee Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 30 Jan 2007 22:22:06 +0000 Subject: r21064: The core of this patch is void message_register(int msg_type, void (*fn)(int msg_type, struct process_id pid, - void *buf, size_t len)) + void *buf, size_t len, + void *private_data), + void *private_data) { struct dispatch_fns *dfn; So this adds a (so far unused) private pointer that is passed from message_register to the message handler. A prerequisite to implement a tiny samba4-API compatible wrapper around our messaging system. That itself is necessary for the Samba4 notify system. Yes, I know, I could import the whole Samba4 messaging system, but I want to do it step by step and I think getting notify in is more important in this step. Volker (This used to be commit c8ae60ed65dcce9660ee39c75488f2838cf9a28b) --- source3/printing/printing.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 2f1d123a20..588641358f 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1352,7 +1352,8 @@ static void print_queue_update_with_lock( const char *sharename, this is the receive function of the background lpq updater ****************************************************************************/ static void print_queue_receive(int msg_type, struct process_id src, - void *buf, size_t msglen) + void *buf, size_t msglen, + void *private_data) { fstring sharename; pstring lpqcommand, lprmcommand; @@ -1403,7 +1404,8 @@ void start_background_queue(void) exit(1); } - message_register(MSG_PRINTER_UPDATE, print_queue_receive); + message_register(MSG_PRINTER_UPDATE, print_queue_receive, + NULL); DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n")); while (1) { -- cgit From 8dbeb4dbebb3e8cdcb83df195a91e77ac86f240a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 19 Feb 2007 13:30:07 +0000 Subject: r21446: Karolins "printjob username" (This used to be commit 19ee6779255a269830fa8ee51468a4738dadf942) --- source3/printing/printing.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 588641358f..39efe19604 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -2396,7 +2396,11 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE fstrcpy(pjob.jobname, jobname); if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { - fstrcpy(pjob.user, vuser->user.smb_name); + fstrcpy(pjob.user, lp_printjob_username(snum)); + standard_sub_basic(vuser->user.smb_name, vuser->user.domain, + pjob.user, sizeof(pjob.user)-1); + /* ensure NULL termination */ + pjob.user[sizeof(pjob.user)-1] = '\0'; } else { fstrcpy(pjob.user, uidtoname(user->ut.uid)); } -- cgit From 2d118cef3fe16c69cd290642c0aeadd303441a2d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 27 Mar 2007 11:20:55 +0000 Subject: r21988: make use of string_tdb_data() to avoid creating the TDB_DATA struct from strings "by hand" metze (This used to be commit 2f52df71039befff8646aa67c1123df7be3591d2) --- source3/printing/printing.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 39efe19604..5aac04aa8d 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -867,8 +867,7 @@ static pid_t get_updating_pid(const char *sharename) if (!pdb) return (pid_t)-1; slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename); - key.dptr = keystr; - key.dsize = strlen(keystr); + key = string_tdb_data(keystr); data = tdb_fetch(pdb->tdb, key); release_print_db(pdb); @@ -905,8 +904,7 @@ static void set_updating_pid(const fstring sharename, BOOL updating) return; slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename); - key.dptr = keystr; - key.dsize = strlen(keystr); + key = string_tdb_data(keystr); DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n", updating ? "" : "not ", @@ -1233,8 +1231,7 @@ static void print_queue_update_internal( const char *sharename, /* store the new queue status structure */ slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename); - key.dptr = keystr; - key.dsize = strlen(keystr); + key = string_tdb_data(keystr); status.qcount = qcount; data.dptr = (char *)&status; @@ -2701,8 +2698,8 @@ int print_queue_status(int snum, ZERO_STRUCTP(status); slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename); - key.dptr = keystr; - key.dsize = strlen(keystr); + key = string_tdb_data(keystr); + data = tdb_fetch(pdb->tdb, key); if (data.dptr) { if (data.dsize == sizeof(*status)) { -- cgit From bc2b6436d0f5f3e9ffdfaeb7f1b32996a83d5478 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Mar 2007 09:35:51 +0000 Subject: r22009: change TDB_DATA from char * to unsigned char * and fix all compiler warnings in the users metze (This used to be commit 3a28443079c141a6ce8182c65b56ca210e34f37f) --- source3/printing/printing.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 5aac04aa8d..8b61f07680 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -76,7 +76,7 @@ uint16 pjobid_to_rap(const char* sharename, uint32 jobid) ZERO_STRUCT( jinfo ); fstrcpy( jinfo.sharename, sharename ); jinfo.jobid = jobid; - key.dptr = (char*)&jinfo; + key.dptr = (uint8 *)&jinfo; key.dsize = sizeof(jinfo); data = tdb_fetch(rap_tdb, key); @@ -93,7 +93,7 @@ uint16 pjobid_to_rap(const char* sharename, uint32 jobid) if (rap_jobid == 0) rap_jobid = ++next_rap_jobid; SSVAL(buf,0,rap_jobid); - data.dptr = (char*)buf; + data.dptr = buf; data.dsize = sizeof(rap_jobid); tdb_store(rap_tdb, key, data, TDB_REPLACE); tdb_store(rap_tdb, data, key, TDB_REPLACE); @@ -114,7 +114,7 @@ BOOL rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid) return False; SSVAL(buf,0,rap_jobid); - key.dptr = (char*)buf; + key.dptr = buf; key.dsize = sizeof(rap_jobid); data = tdb_fetch(rap_tdb, key); if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) ) @@ -149,7 +149,7 @@ static void rap_jobid_delete(const char* sharename, uint32 jobid) ZERO_STRUCT( jinfo ); fstrcpy( jinfo.sharename, sharename ); jinfo.jobid = jobid; - key.dptr = (char*)&jinfo; + key.dptr = (uint8 *)&jinfo; key.dsize = sizeof(jinfo); data = tdb_fetch(rap_tdb, key); @@ -166,7 +166,7 @@ static void rap_jobid_delete(const char* sharename, uint32 jobid) rap_jobid = SVAL(data.dptr, 0); SAFE_FREE(data.dptr); SSVAL(buf,0,rap_jobid); - data.dptr = (char*)buf; + data.dptr = buf; data.dsize = sizeof(rap_jobid); tdb_delete(rap_tdb, key); tdb_delete(rap_tdb, data); @@ -273,7 +273,7 @@ static TDB_DATA print_key(uint32 jobid) TDB_DATA ret; SIVAL(&j, 0, jobid); - ret.dptr = (char *)&j; + ret.dptr = (uint8 *)&j; ret.dsize = sizeof(j); return ret; } @@ -282,7 +282,7 @@ static TDB_DATA print_key(uint32 jobid) unpack a pjob from a tdb buffer ***********************************************************************/ -int unpack_pjob( char* buf, int buflen, struct printjob *pjob ) +int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob ) { int len = 0; int used; @@ -518,7 +518,7 @@ static BOOL pjob_store(const char* sharename, uint32 jobid, struct printjob *pjo TDB_DATA old_data, new_data; BOOL ret = False; struct tdb_print_db *pdb = get_print_db_byname(sharename); - char *buf = NULL; + uint8 *buf = NULL; int len, newlen, buflen; @@ -554,7 +554,7 @@ static BOOL pjob_store(const char* sharename, uint32 jobid, struct printjob *pjo len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len); if (buflen != len) { - buf = (char *)SMB_REALLOC(buf, len); + buf = (uint8 *)SMB_REALLOC(buf, len); if (!buf) { DEBUG(0,("pjob_store: failed to enlarge buffer!\n")); goto done; @@ -917,7 +917,7 @@ static void set_updating_pid(const fstring sharename, BOOL updating) } SIVAL( buffer, 0, updating_pid); - data.dptr = (char *)buffer; + data.dptr = buffer; data.dsize = 4; /* we always assume this is a 4 byte value */ tdb_store(pdb->tdb, key, data, TDB_REPLACE); @@ -984,7 +984,7 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct queue[i].fs_file); } - if ((data.dptr = (char *)SMB_MALLOC(data.dsize)) == NULL) + if ((data.dptr = (uint8 *)SMB_MALLOC(data.dsize)) == NULL) return; len = 0; @@ -1234,7 +1234,7 @@ static void print_queue_update_internal( const char *sharename, key = string_tdb_data(keystr); status.qcount = qcount; - data.dptr = (char *)&status; + data.dptr = (uint8 *)&status; data.dsize = sizeof(status); tdb_store(pdb->tdb, key, data, TDB_REPLACE); @@ -1357,7 +1357,7 @@ static void print_queue_receive(int msg_type, struct process_id src, int printing_type; size_t len; - len = tdb_unpack( (char *)buf, msglen, "fdPP", + len = tdb_unpack( buf, msglen, "fdPP", sharename, &printing_type, lpqcommand, @@ -1442,7 +1442,7 @@ static void print_queue_update(int snum, BOOL force) fstring key; fstring sharename; pstring lpqcommand, lprmcommand; - char *buffer = NULL; + uint8 *buffer = NULL; size_t len = 0; size_t newlen; struct tdb_print_db *pdb; @@ -1496,7 +1496,7 @@ static void print_queue_update(int snum, BOOL force) lpqcommand, lprmcommand ); - buffer = SMB_XMALLOC_ARRAY( char, len ); + buffer = SMB_XMALLOC_ARRAY( uint8, len ); /* now pack the buffer */ newlen = tdb_pack( buffer, len, "fdPP", @@ -1604,7 +1604,7 @@ BOOL print_notify_register_pid(int snum) if (i == data.dsize) { /* We weren't in the list. Realloc. */ - data.dptr = (char *)SMB_REALLOC(data.dptr, data.dsize + 8); + data.dptr = (uint8 *)SMB_REALLOC(data.dptr, data.dsize + 8); if (!data.dptr) { DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n", printername)); @@ -2299,7 +2299,7 @@ static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid) uint32 store_jobid; SIVAL(&store_jobid, 0, jobid); - data.dptr = (char *)&store_jobid; + data.dptr = (uint8 *)&store_jobid; data.dsize = 4; DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid )); -- cgit From e6383f47629368d9dd4e803f17566a24e9d7359e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 May 2007 09:35:35 +0000 Subject: r22736: Start to merge the low-hanging fruit from the now 7000-line cluster patch. This changes "struct process_id" to "struct server_id", keeping both is just too much hassle. No functional change (I hope ;-)) Volker (This used to be commit 0ad4b1226c9d91b72136310d3bbb640d2c5d67b8) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 8b61f07680..92e0ba6585 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1348,7 +1348,7 @@ static void print_queue_update_with_lock( const char *sharename, /**************************************************************************** this is the receive function of the background lpq updater ****************************************************************************/ -static void print_queue_receive(int msg_type, struct process_id src, +static void print_queue_receive(int msg_type, struct server_id src, void *buf, size_t msglen, void *private_data) { -- cgit From 71921605995fa95d84301534760a6bc2db3fa74b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 May 2007 15:07:49 +0000 Subject: r22747: Fix some C++ warnings (This used to be commit a66a04e9f11f6c4462f2b56b447bae4eca7b177c) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 92e0ba6585..2e259a8f51 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1357,7 +1357,7 @@ static void print_queue_receive(int msg_type, struct server_id src, int printing_type; size_t len; - len = tdb_unpack( buf, msglen, "fdPP", + len = tdb_unpack( (uint8 *)buf, msglen, "fdPP", sharename, &printing_type, lpqcommand, -- cgit From fad7dd8a60e6637598b17fa89ec92d98db51fffe Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 May 2007 20:31:28 +0000 Subject: r22868: Replace some message_send_pid calls with messaging_send_pid calls. More tomorrow. (This used to be commit 74fa57ca5d7fa8eace72bbe948a08a0bca3cc4ca) --- source3/printing/printing.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 2e259a8f51..fd1649737b 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1428,7 +1428,8 @@ void start_background_queue(void) /* process any pending print change notify messages */ - print_notify_send_messages(0); + print_notify_send_messages(smbd_messaging_context(), + 0); } } } -- cgit From fb99bbe67597555109ebd65613a5aab395b43499 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 15 May 2007 10:50:44 +0000 Subject: r22895: Convert some more calls from message_send_buf to messaging_send_buf (This used to be commit c8b98273406242a89a7e5d1fb5d79120ebe5822a) --- source3/printing/printing.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index fd1649737b..9bae768c19 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1535,8 +1535,9 @@ static void print_queue_update(int snum, BOOL force) /* finally send the message */ - message_send_pid(pid_to_procid(background_lpq_updater_pid), - MSG_PRINTER_UPDATE, buffer, len, False); + messaging_send_buf(smbd_messaging_context(), + pid_to_procid(background_lpq_updater_pid), + MSG_PRINTER_UPDATE, (uint8 *)buffer, len); SAFE_FREE( buffer ); -- cgit From e95942ed84fef4dd34c380d59145d3e182b01702 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 16 May 2007 20:56:39 +0000 Subject: r22954: More messaging_register (This used to be commit 9b8df24107ffe3016031e5257c5680689f061886) --- source3/printing/printing.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 9bae768c19..6717f473cc 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -178,7 +178,7 @@ static int get_queue_status(const char* sharename, print_status_struct *); Initialise the printing backend. Called once at startup before the fork(). ****************************************************************************/ -BOOL print_backend_init(void) +BOOL print_backend_init(struct messaging_context *msg_ctx) { const char *sversion = "INFO/version"; pstring printing_path; @@ -215,7 +215,7 @@ BOOL print_backend_init(void) close_all_print_db(); /* Don't leave any open. */ /* do NT print initialization... */ - return nt_printing_init(); + return nt_printing_init(msg_ctx); } /**************************************************************************** @@ -1348,16 +1348,18 @@ static void print_queue_update_with_lock( const char *sharename, /**************************************************************************** this is the receive function of the background lpq updater ****************************************************************************/ -static void print_queue_receive(int msg_type, struct server_id src, - void *buf, size_t msglen, - void *private_data) +static void print_queue_receive(struct messaging_context *msg, + void *private_data, + uint32_t msg_type, + struct server_id server_id, + DATA_BLOB *data) { fstring sharename; pstring lpqcommand, lprmcommand; int printing_type; size_t len; - len = tdb_unpack( (uint8 *)buf, msglen, "fdPP", + len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP", sharename, &printing_type, lpqcommand, @@ -1401,8 +1403,8 @@ void start_background_queue(void) exit(1); } - message_register(MSG_PRINTER_UPDATE, print_queue_receive, - NULL); + messaging_register(smbd_messaging_context(), NULL, + MSG_PRINTER_UPDATE, print_queue_receive); DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n")); while (1) { -- cgit From ac3f08ddbe0b484375624db0e35999a8584b57f4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 21 May 2007 22:17:13 +0000 Subject: r23055: Rewrite messages.c to use auto-generated marshalling in the tdb. I'm doing this because for the clustering the marshalling is needed in more than one place, so I wanted a decent routine to marshall a message_rec struct which was not there before. Tridge, this seems about the same speed as it used to be before, the librpc/ndr overhead in my tests was under the noise. Volker (This used to be commit eaefd00563173dfabb7716c5695ac0a2f7139bb6) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 6717f473cc..6101f9a0f5 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1426,7 +1426,7 @@ void start_background_queue(void) /* now check for messages */ DEBUG(10,("start_background_queue: background LPQ thread got a message\n")); - message_dispatch(); + message_dispatch(smbd_messaging_context()); /* process any pending print change notify messages */ -- cgit From f3c477c631e7318ccaa6f277731b721a462112b8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 27 May 2007 16:22:12 +0000 Subject: r23167: Remove an unused parameter (This used to be commit 3452a870d58cdddf03ddf6ee698bca8416e05cbf) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 6101f9a0f5..780880cbe7 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1396,7 +1396,7 @@ void start_background_queue(void) /* Child. */ DEBUG(5,("start_background_queue: background LPQ thread started\n")); - claim_connection( NULL, "smbd lpq backend", 0, False, + claim_connection( NULL, "smbd lpq backend", 0, FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL); if (!locking_init(0)) { -- cgit From 14e25f10d6a3da34fb8b29c4331571efa11ee3b8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 27 May 2007 16:34:49 +0000 Subject: r23168: Move the lp_max_connections() into service.c. (This used to be commit 4afe37d431b6eb475769a2057025da9aa8d1bb14) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 780880cbe7..3453598480 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1396,7 +1396,7 @@ void start_background_queue(void) /* Child. */ DEBUG(5,("start_background_queue: background LPQ thread started\n")); - claim_connection( NULL, "smbd lpq backend", 0, + claim_connection( NULL, "smbd lpq backend", FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL); if (!locking_init(0)) { -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 3453598480..de2e4150d2 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/printing/printing.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index de2e4150d2..e793651cb6 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From 470ebf8a3504474dea5c324d01282e59c034a236 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Sep 2007 01:32:08 +0000 Subject: r25399: Excise uint - > uint32 (where appropriate) or unsigned int. Jeremy. (This used to be commit b4ee924000f4a21b16a70e08e58331d209c4d114) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index e793651cb6..868a72cb32 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -957,7 +957,7 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct print_queue_struct *queue = pts->queue; size_t len; size_t i; - uint qcount; + unsigned int qcount; if (max_reported_jobs && (max_reported_jobs < pts->qcount)) pts->qcount = max_reported_jobs; -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/printing/printing.c | 74 ++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 37 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 868a72cb32..af87b8f2c2 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -28,7 +28,7 @@ extern struct current_user current_user; extern userdom_struct current_user_info; /* Current printer interface */ -static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid); +static bool remove_from_jobs_changed(const char* sharename, uint32 jobid); /* the printing backend revolves around a tdb database that stores the @@ -102,7 +102,7 @@ uint16 pjobid_to_rap(const char* sharename, uint32 jobid) return rap_jobid; } -BOOL rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid) +bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid) { TDB_DATA data, key; uint8 buf[2]; @@ -177,7 +177,7 @@ static int get_queue_status(const char* sharename, print_status_struct *); Initialise the printing backend. Called once at startup before the fork(). ****************************************************************************/ -BOOL print_backend_init(struct messaging_context *msg_ctx) +bool print_backend_init(struct messaging_context *msg_ctx) { const char *sversion = "INFO/version"; pstring printing_path; @@ -469,7 +469,7 @@ static uint32 map_to_spoolss_status(uint32 lpq_status) static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data, struct printjob *new_data) { - BOOL new_job = False; + bool new_job = False; if (!old_data) new_job = True; @@ -512,10 +512,10 @@ static void pjob_store_notify(const char* sharename, uint32 jobid, struct printj Store a job structure back to the database. ****************************************************************************/ -static BOOL pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob) +static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob) { TDB_DATA old_data, new_data; - BOOL ret = False; + bool ret = False; struct tdb_print_db *pdb = get_print_db_byname(sharename); uint8 *buf = NULL; int len, newlen, buflen; @@ -889,7 +889,7 @@ static pid_t get_updating_pid(const char *sharename) in the tdb. ****************************************************************************/ -static void set_updating_pid(const fstring sharename, BOOL updating) +static void set_updating_pid(const fstring sharename, bool updating) { fstring keystr; TDB_DATA key; @@ -1042,12 +1042,12 @@ static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid Check if the print queue has been updated recently enough. ****************************************************************************/ -static BOOL print_cache_expired(const char *sharename, BOOL check_pending) +static bool print_cache_expired(const char *sharename, bool check_pending) { fstring key; time_t last_qscan_time, time_now = time(NULL); struct tdb_print_db *pdb = get_print_db_byname(sharename); - BOOL result = False; + bool result = False; if (!pdb) return False; @@ -1439,7 +1439,7 @@ void start_background_queue(void) update the internal database from the system print queue for a queue ****************************************************************************/ -static void print_queue_update(int snum, BOOL force) +static void print_queue_update(int snum, bool force) { fstring key; fstring sharename; @@ -1550,14 +1550,14 @@ static void print_queue_update(int snum, BOOL force) updates only to interested smbd's. ****************************************************************************/ -BOOL print_notify_register_pid(int snum) +bool print_notify_register_pid(int snum) { TDB_DATA data; struct tdb_print_db *pdb = NULL; TDB_CONTEXT *tdb = NULL; const char *printername; uint32 mypid = (uint32)sys_getpid(); - BOOL ret = False; + bool ret = False; size_t i; /* if (snum == -1), then the change notify request was @@ -1641,7 +1641,7 @@ list for printer %s\n", printername)); updates only to interested smbd's. ****************************************************************************/ -BOOL print_notify_deregister_pid(int snum) +bool print_notify_deregister_pid(int snum) { TDB_DATA data; struct tdb_print_db *pdb = NULL; @@ -1649,7 +1649,7 @@ BOOL print_notify_deregister_pid(int snum) const char *printername; uint32 mypid = (uint32)sys_getpid(); size_t i; - BOOL ret = False; + bool ret = False; /* if ( snum == -1 ), we are deregister a print server handle which means to deregister on all print queues */ @@ -1730,10 +1730,10 @@ list for printer %s\n", printername)); Check if a jobid is valid. It is valid if it exists in the database. ****************************************************************************/ -BOOL print_job_exists(const char* sharename, uint32 jobid) +bool print_job_exists(const char* sharename, uint32 jobid) { struct tdb_print_db *pdb = get_print_db_byname(sharename); - BOOL ret; + bool ret; if (!pdb) return False; @@ -1792,7 +1792,7 @@ NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid) Set the place in the queue for a job. ****************************************************************************/ -BOOL print_job_set_place(const char *sharename, uint32 jobid, int place) +bool print_job_set_place(const char *sharename, uint32 jobid, int place) { DEBUG(2,("print_job_set_place not implemented yet\n")); return False; @@ -1802,7 +1802,7 @@ BOOL print_job_set_place(const char *sharename, uint32 jobid, int place) Set the name of a job. Only possible for owner. ****************************************************************************/ -BOOL print_job_set_name(const char *sharename, uint32 jobid, char *name) +bool print_job_set_name(const char *sharename, uint32 jobid, char *name) { struct printjob *pjob; @@ -1818,13 +1818,13 @@ BOOL print_job_set_name(const char *sharename, uint32 jobid, char *name) Remove a jobid from the 'jobs changed' list. ***************************************************************************/ -static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid) +static bool remove_from_jobs_changed(const char* sharename, uint32 jobid) { struct tdb_print_db *pdb = get_print_db_byname(sharename); TDB_DATA data, key; size_t job_count, i; - BOOL ret = False; - BOOL gotlock = False; + bool ret = False; + bool gotlock = False; if (!pdb) { return False; @@ -1877,7 +1877,7 @@ static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid) Delete a print job - don't update queue. ****************************************************************************/ -static BOOL print_job_delete1(int snum, uint32 jobid) +static bool print_job_delete1(int snum, uint32 jobid) { const char* sharename = lp_const_servicename(snum); struct printjob *pjob = print_job_find(sharename, jobid); @@ -1940,7 +1940,7 @@ static BOOL print_job_delete1(int snum, uint32 jobid) Return true if the current user owns the print job. ****************************************************************************/ -static BOOL is_owner(struct current_user *user, const char *servicename, +static bool is_owner(struct current_user *user, const char *servicename, uint32 jobid) { struct printjob *pjob = print_job_find(servicename, jobid); @@ -1960,11 +1960,11 @@ static BOOL is_owner(struct current_user *user, const char *servicename, Delete a print job. ****************************************************************************/ -BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) +bool print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) { const char* sharename = lp_const_servicename( snum ); struct printjob *pjob; - BOOL owner; + bool owner; char *fname; *errcode = WERR_OK; @@ -2027,7 +2027,7 @@ pause, or resume print job. User name: %s. Printer name: %s.", Pause a job. ****************************************************************************/ -BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) +bool print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) { const char* sharename = lp_const_servicename(snum); struct printjob *pjob; @@ -2087,7 +2087,7 @@ pause, or resume print job. User name: %s. Printer name: %s.", Resume a job. ****************************************************************************/ -BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) +bool print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) { const char *sharename = lp_const_servicename(snum); struct printjob *pjob; @@ -2230,7 +2230,7 @@ int print_queue_length(int snum, print_status_struct *pstatus) Allocate a jobid. Hold the lock for as short a time as possible. ***************************************************************************/ -static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid) +static bool allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid) { int i; uint32 jobid; @@ -2296,7 +2296,7 @@ static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char Append a jobid to the 'jobs changed' list. ***************************************************************************/ -static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid) +static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid) { TDB_DATA data; uint32 store_jobid; @@ -2473,7 +2473,7 @@ void print_job_endpage(int snum, uint32 jobid) error. ****************************************************************************/ -BOOL print_job_end(int snum, uint32 jobid, enum file_close_type close_type) +bool print_job_end(int snum, uint32 jobid, enum file_close_type close_type) { const char* sharename = lp_const_servicename(snum); struct printjob *pjob; @@ -2550,7 +2550,7 @@ fail: Get a snapshot of jobs in the system without traversing. ****************************************************************************/ -static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue) +static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue) { TDB_DATA data, cgdata; print_queue_struct *queue = NULL; @@ -2560,7 +2560,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun size_t len = 0; uint32 i; int max_reported_jobs = lp_max_reported_jobs(snum); - BOOL ret = False; + bool ret = False; const char* sharename = lp_servicename(snum); /* make sure the database is up to date */ @@ -2731,7 +2731,7 @@ int print_queue_status(int snum, Pause a queue. ****************************************************************************/ -BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode) +bool print_queue_pause(struct current_user *user, int snum, WERROR *errcode) { int ret; struct printif *current_printif = get_printer_fns( snum ); @@ -2767,7 +2767,7 @@ BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode) Resume a queue. ****************************************************************************/ -BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode) +bool print_queue_resume(struct current_user *user, int snum, WERROR *errcode) { int ret; struct printif *current_printif = get_printer_fns( snum ); @@ -2803,12 +2803,12 @@ BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode) Purge a queue - implemented by deleting all jobs that we can delete. ****************************************************************************/ -BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode) +bool print_queue_purge(struct current_user *user, int snum, WERROR *errcode) { print_queue_struct *queue; print_status_struct status; int njobs, i; - BOOL can_job_admin; + bool can_job_admin; /* Force and update so the count is accurate (i.e. not a cached count) */ print_queue_update(snum, True); @@ -2820,7 +2820,7 @@ BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode) become_root(); for (i=0;i Date: Mon, 19 Nov 2007 18:56:22 -0800 Subject: Remove more pstring. Unify talloc_sub functions to make them a better match for replacing string_sub. Remove more unused code. Jeremy. (This used to be commit ae7885711f504f1442335f09088cbe149a7e00f9) --- source3/printing/printing.c | 81 ++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 30 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index af87b8f2c2..48ac54d797 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -180,13 +180,11 @@ static int get_queue_status(const char* sharename, print_status_struct *); bool print_backend_init(struct messaging_context *msg_ctx) { const char *sversion = "INFO/version"; - pstring printing_path; int services = lp_numservices(); int snum; unlink(lock_path("printing.tdb")); - pstrcpy(printing_path,lock_path("printing")); - mkdir(printing_path,0755); + mkdir(lock_path("printing"),0755); /* handle a Samba upgrade */ @@ -1443,43 +1441,66 @@ static void print_queue_update(int snum, bool force) { fstring key; fstring sharename; - pstring lpqcommand, lprmcommand; + char *lpqcommand = NULL; + char *lprmcommand = NULL; uint8 *buffer = NULL; size_t len = 0; size_t newlen; struct tdb_print_db *pdb; int type; struct printif *current_printif; + TALLOC_CTX *ctx = talloc_tos(); fstrcpy( sharename, lp_const_servicename(snum)); /* don't strip out characters like '$' from the printername */ - - pstrcpy( lpqcommand, lp_lpqcommand(snum)); - string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), - False, False, False ); - standard_sub_advanced(lp_servicename(snum), - current_user_info.unix_name, "", - current_user.ut.gid, - get_current_username(), - current_user_info.domain, - lpqcommand, sizeof(lpqcommand) ); - + + lpqcommand = talloc_string_sub2(ctx, + lp_lpqcommand(snum), + "%p", + PRINTERNAME(snum), + false, false, false); + if (!lpqcommand) { + return; + } + lpqcommand = talloc_sub_advanced(ctx, + lp_servicename(snum), + current_user_info.unix_name, + "", + current_user.ut.gid, + get_current_username(), + current_user_info.domain, + lpqcommand); + if (!lpqcommand) { + return; + } + pstrcpy( lprmcommand, lp_lprmcommand(snum)); - string_sub2( lprmcommand, "%p", PRINTERNAME(snum), sizeof(lprmcommand), - False, False, False ); - standard_sub_advanced(lp_servicename(snum), - current_user_info.unix_name, "", - current_user.ut.gid, - get_current_username(), - current_user_info.domain, - lprmcommand, sizeof(lprmcommand) ); - - /* - * Make sure that the background queue process exists. - * Otherwise just do the update ourselves + lprmcommand = talloc_string_sub2(ctx, + lp_lprmcommand(snum), + "%p", + PRINTERNAME(snum), + false, false, false); + if (!lprmcommand) { + return; + } + lprmcommand = talloc_sub_advanced(ctx, + lp_servicename(snum), + current_user_info.unix_name, + "", + current_user.ut.gid, + get_current_username(), + current_user_info.domain, + lprmcommand); + if (!lprmcommand) { + return; + } + + /* + * Make sure that the background queue process exists. + * Otherwise just do the update ourselves */ - + if ( force || background_lpq_updater_pid == -1 ) { DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename)); current_printif = get_printer_fns( snum ); @@ -1489,13 +1510,13 @@ static void print_queue_update(int snum, bool force) } type = lp_printing(snum); - + /* get the length */ len = tdb_pack( NULL, 0, "fdPP", sharename, type, - lpqcommand, + lpqcommand, lprmcommand ); buffer = SMB_XMALLOC_ARRAY( uint8, len ); -- cgit From cdad0409c43c1190a95c72168eb2b4276bd8efe9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Nov 2007 19:05:30 -0800 Subject: Remove pstrcpy I missed. Jeremy. (This used to be commit f5701756154e4e113414d8dd6c850685a2594801) --- source3/printing/printing.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 48ac54d797..d331e897f9 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1475,7 +1475,6 @@ static void print_queue_update(int snum, bool force) return; } - pstrcpy( lprmcommand, lp_lprmcommand(snum)); lprmcommand = talloc_string_sub2(ctx, lp_lprmcommand(snum), "%p", -- cgit From bcf033b38ee2f6c76cd56cae5cd84a6e321ffafa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 3 Dec 2007 14:54:06 -0800 Subject: Change tdb_unpack "P" to return a malloc'ed string rather than expect a pstring space to put data into. Fix the (few) callers. Jeremy. (This used to be commit 7722a7d2c63f84b8105aa775b39f0ceedd4ed513) --- source3/printing/printing.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index d331e897f9..1613828b79 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1352,17 +1352,19 @@ static void print_queue_receive(struct messaging_context *msg, DATA_BLOB *data) { fstring sharename; - pstring lpqcommand, lprmcommand; + char *lpqcommand = NULL, *lprmcommand = NULL; int printing_type; size_t len; len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP", sharename, &printing_type, - lpqcommand, - lprmcommand ); + &lpqcommand, + &lprmcommand ); if ( len == -1 ) { + SAFE_FREE(lpqcommand); + SAFE_FREE(lprmcommand); DEBUG(0,("print_queue_receive: Got invalid print queue update message\n")); return; } @@ -1371,6 +1373,8 @@ static void print_queue_receive(struct messaging_context *msg, get_printer_fns_from_type((enum printing_types)printing_type), lpqcommand, lprmcommand ); + SAFE_FREE(lpqcommand); + SAFE_FREE(lprmcommand); return; } -- cgit From a1ceee904cec146c3c904ff69f47312e6c114abe Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 5 Dec 2007 18:46:53 +0100 Subject: remove a static (This used to be commit 0006b14d38b80562458b37f616c9b68a3168fe64) --- source3/printing/printing.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 1613828b79..1c7ad158d4 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -264,14 +264,13 @@ static struct printif *get_printer_fns( int snum ) Useful function to generate a tdb key. ****************************************************************************/ -static TDB_DATA print_key(uint32 jobid) +static TDB_DATA print_key(uint32 jobid, uint32 *tmp) { - static uint32 j; TDB_DATA ret; - SIVAL(&j, 0, jobid); - ret.dptr = (uint8 *)&j; - ret.dsize = sizeof(j); + SIVAL(tmp, 0, jobid); + ret.dptr = (uint8 *)tmp; + ret.dsize = sizeof(*tmp); return ret; } @@ -333,6 +332,7 @@ int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob ) static struct printjob *print_job_find(const char *sharename, uint32 jobid) { static struct printjob pjob; + uint32_t tmp; TDB_DATA ret; struct tdb_print_db *pdb = get_print_db_byname(sharename); @@ -343,7 +343,7 @@ static struct printjob *print_job_find(const char *sharename, uint32 jobid) return NULL; } - ret = tdb_fetch(pdb->tdb, print_key(jobid)); + ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp)); release_print_db(pdb); if (!ret.dptr) { @@ -430,7 +430,7 @@ uint32 sysjob_to_jobid(int unix_jobid) Send notifications based on what has changed after a pjob_store. ****************************************************************************/ -static struct { +static const struct { uint32 lpq_status; uint32 spoolss_status; } lpq_to_spoolss_status_map[] = { @@ -512,6 +512,7 @@ static void pjob_store_notify(const char* sharename, uint32 jobid, struct printj static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob) { + uint32_t tmp; TDB_DATA old_data, new_data; bool ret = False; struct tdb_print_db *pdb = get_print_db_byname(sharename); @@ -524,7 +525,7 @@ static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjo /* Get old data */ - old_data = tdb_fetch(pdb->tdb, print_key(jobid)); + old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp)); /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */ @@ -565,7 +566,8 @@ static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjo new_data.dptr = buf; new_data.dsize = len; - ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0); + ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data, + TDB_REPLACE) == 0); release_print_db(pdb); @@ -601,6 +603,7 @@ done: void pjob_delete(const char* sharename, uint32 jobid) { + uint32_t tmp; struct printjob *pjob; uint32 job_status = 0; struct tdb_print_db *pdb; @@ -628,7 +631,7 @@ void pjob_delete(const char* sharename, uint32 jobid) /* Remove from printing.tdb */ - tdb_delete(pdb->tdb, print_key(jobid)); + tdb_delete(pdb->tdb, print_key(jobid, &tmp)); remove_from_jobs_changed(sharename, jobid); release_print_db( pdb ); rap_jobid_delete(sharename, jobid); @@ -1758,10 +1761,11 @@ bool print_job_exists(const char* sharename, uint32 jobid) { struct tdb_print_db *pdb = get_print_db_byname(sharename); bool ret; + uint32_t tmp; if (!pdb) return False; - ret = tdb_exists(pdb->tdb, print_key(jobid)); + ret = tdb_exists(pdb->tdb, print_key(jobid, &tmp)); release_print_db(pdb); return ret; } @@ -2302,10 +2306,12 @@ static bool allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char /* Store a dummy placeholder. */ { + uint32_t tmp; TDB_DATA dum; dum.dptr = NULL; dum.dsize = 0; - if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) { + if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum, + TDB_INSERT) == -1) { DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n", jobid )); return False; -- cgit From d60fac2a5a789680b6dd9f05ab15a3033ec2887c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 5 Dec 2007 20:53:22 +0100 Subject: Tiny simplifications locking.c:open_read_only was unused don't export the silly boolean flag locking_init(bool read_only) (This used to be commit 2f3c865707010bc7c463a02782dbee3dc2479da1) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 1c7ad158d4..fa6ed89edd 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1403,7 +1403,7 @@ void start_background_queue(void) claim_connection( NULL, "smbd lpq backend", FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL); - if (!locking_init(0)) { + if (!locking_init()) { exit(1); } -- cgit From d826fcf6dfb0e2203a114cbd427badc0abeea559 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 28 Dec 2007 17:16:35 +0100 Subject: Remove a global (This used to be commit 515f6a8cff7e28b0e98136f3214ef52512cfaf37) --- source3/printing/printing.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index fa6ed89edd..9f2c08629d 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -373,13 +373,17 @@ static struct printjob *print_job_find(const char *sharename, uint32 jobid) /* Convert a unix jobid to a smb jobid */ -static uint32 sysjob_to_jobid_value; +struct unixjob_traverse_state { + int sysjob; + uint32 sysjob_to_jobid_value; +}; static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, - TDB_DATA data, void *state) + TDB_DATA data, void *private_data) { struct printjob *pjob; - int *sysjob = (int *)state; + struct unixjob_traverse_state *state = + (struct unixjob_traverse_state *)private_data; if (!data.dptr || data.dsize == 0) return 0; @@ -388,10 +392,10 @@ static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, if (key.dsize != sizeof(uint32)) return 0; - if (*sysjob == pjob->sysjob) { + if (state->sysjob == pjob->sysjob) { uint32 jobid = IVAL(key.dptr,0); - sysjob_to_jobid_value = jobid; + state->sysjob_to_jobid_value = jobid; return 1; } @@ -407,8 +411,10 @@ uint32 sysjob_to_jobid(int unix_jobid) { int services = lp_numservices(); int snum; + struct unixjob_traverse_state state; - sysjob_to_jobid_value = (uint32)-1; + state.sysjob = unix_jobid; + state.sysjob_to_jobid_value = (uint32)-1; for (snum = 0; snum < services; snum++) { struct tdb_print_db *pdb; @@ -418,10 +424,10 @@ uint32 sysjob_to_jobid(int unix_jobid) if (!pdb) { continue; } - tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid); + tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state); release_print_db(pdb); - if (sysjob_to_jobid_value != (uint32)-1) - return sysjob_to_jobid_value; + if (state.sysjob_to_jobid_value != (uint32)-1) + return state.sysjob_to_jobid_value; } return (uint32)-1; } -- cgit From 2a6a2288c5fae908f431bd79332554e0a23dbeed Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Fri, 8 Feb 2008 09:28:57 +0100 Subject: Fix some typos. Karolin (This used to be commit 2bec0a1fb7857e6fb8ec15e5f597b2d4125f105b) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 9f2c08629d..221e79b337 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -2575,7 +2575,7 @@ bool print_job_end(int snum, uint32 jobid, enum file_close_type close_type) fail: - /* The print job was not succesfully started. Cleanup */ + /* The print job was not successfully started. Cleanup */ /* Still need to add proper error return propagation! 010122:JRR */ unlink(pjob->filename); pjob_delete(sharename, jobid); -- cgit From aaa59713155b63b2597f955622be9019bb3cbe89 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 25 Mar 2008 14:18:08 +0100 Subject: util_tdb: add a wrapper tdb_wipe() for traverse with tdb_traverse_delete_fn(). Replace all callers of traverse with this tdb_traverse_delete_fn() and don't export tdb_traverse_delete_fn() anymore. Michael (This used to be commit d4be4e30cd8c3bdc303da30e42280f892a45a8c9) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 221e79b337..c9736b70bb 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -202,7 +202,7 @@ bool print_backend_init(struct messaging_context *msg_ctx) return False; } if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) { - tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL); + tdb_wipe(pdb->tdb); tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION); } tdb_unlock_bystring(pdb->tdb, sversion); -- cgit From da27c770467d7e0494fbea70d5e424e76851819f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 26 Mar 2008 10:50:08 +0100 Subject: use tdb_wipe_all() instead of tdb_wipe() - it is faster... Michael (This used to be commit 3d2fdcd50fdbfb66a14360516836445d47eceeb0) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index c9736b70bb..4c2f7b9627 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -202,7 +202,7 @@ bool print_backend_init(struct messaging_context *msg_ctx) return False; } if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) { - tdb_wipe(pdb->tdb); + tdb_wipe_all(pdb->tdb); tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION); } tdb_unlock_bystring(pdb->tdb, sversion); -- cgit From a8124367b4fcfea165569e4ce1e3401deacb0142 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Wed, 9 Apr 2008 16:14:04 +0200 Subject: Fix typos. Karolin (This used to be commit 6cee34703503fbf3629057345fe221b866560648) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 4c2f7b9627..eb304e7641 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -2561,7 +2561,7 @@ bool print_job_end(int snum, uint32 jobid, enum file_close_type close_type) if (ret) goto fail; - /* The print job has been sucessfully handed over to the back-end */ + /* The print job has been successfully handed over to the back-end */ pjob->spooled = True; pjob->status = LPQ_QUEUED; -- cgit From c5615c6113a72b2665efab1c1fcf50f0a85dfc8f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Apr 2008 01:48:44 +0200 Subject: printing: call reinit_after_fork() in the backgroundqueue process metze (This used to be commit 9adb675a86e81c90e2bddfe984b5ac8f201fec75) --- source3/printing/printing.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index eb304e7641..fdf5e6cc22 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1406,6 +1406,11 @@ void start_background_queue(void) /* Child. */ DEBUG(5,("start_background_queue: background LPQ thread started\n")); + if (!reinit_after_fork(smbd_messaging_context())) { + DEBUG(0,("reinit_after_fork() failed\n")); + smb_panic("reinit_after_fork() failed"); + } + claim_connection( NULL, "smbd lpq backend", FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL); -- cgit From 0c4093a234dfaca6d363a6e1358f2fbf421dcd3c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 23 Apr 2008 17:13:50 +0200 Subject: Fix CLEAR_IF_FIRST handling of messages.tdb We now open messages.tdb even before we do the become_daemon. become_daemon() involves a fork and an immediate exit of the parent, thus the parent_is_longlived argument must be set to false in this case. The parent is not really long lived :-) (This used to be commit 4f4781c6d17fe2db34dd5945fec52a7685448aec) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index fdf5e6cc22..c5fe53f042 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1406,7 +1406,7 @@ void start_background_queue(void) /* Child. */ DEBUG(5,("start_background_queue: background LPQ thread started\n")); - if (!reinit_after_fork(smbd_messaging_context())) { + if (!reinit_after_fork(smbd_messaging_context(), true)) { DEBUG(0,("reinit_after_fork() failed\n")); smb_panic("reinit_after_fork() failed"); } -- cgit From bec1dfab27be3db888eeb451b4547f16e08e93c3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 30 Apr 2008 17:42:39 +0200 Subject: Remove "userdom_struct user" from "struct user_struct" (This used to be commit 420de035237bb08bc470c9eb820f3da2edaa6805) --- source3/printing/printing.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index c5fe53f042..aa67f08d82 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1989,7 +1989,8 @@ static bool is_owner(struct current_user *user, const char *servicename, return False; if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { - return strequal(pjob->user, vuser->user.smb_name); + return strequal(pjob->user, + vuser->server_info->sanitized_username); } else { return strequal(pjob->user, uidtoname(user->ut.uid)); } @@ -2438,8 +2439,10 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { fstrcpy(pjob.user, lp_printjob_username(snum)); - standard_sub_basic(vuser->user.smb_name, vuser->user.domain, - pjob.user, sizeof(pjob.user)-1); + standard_sub_basic( + vuser->server_info->sanitized_username, + pdb_get_domain(vuser->server_info->sam_account), + pjob.user, sizeof(pjob.user)-1); /* ensure NULL termination */ pjob.user[sizeof(pjob.user)-1] = '\0'; } else { -- cgit From a3c0be63256b7db6325d8dcb599497e8e7905f08 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 24 Jun 2008 16:03:28 +0200 Subject: Change print_access_check to take auth_serversupplied_info instead of current_user Reason: This is the main user of p->current_user which I would like to remove (This used to be commit fd43059b3dfa8cdac9814de1c76f963ba5de9bcb) --- source3/printing/printing.c | 93 +++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 45 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index aa67f08d82..a425b87907 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1979,28 +1979,24 @@ static bool print_job_delete1(int snum, uint32 jobid) Return true if the current user owns the print job. ****************************************************************************/ -static bool is_owner(struct current_user *user, const char *servicename, +static bool is_owner(struct auth_serversupplied_info *server_info, + const char *servicename, uint32 jobid) { struct printjob *pjob = print_job_find(servicename, jobid); - user_struct *vuser; - if (!pjob || !user) + if (!pjob || !server_info) return False; - if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { - return strequal(pjob->user, - vuser->server_info->sanitized_username); - } else { - return strequal(pjob->user, uidtoname(user->ut.uid)); - } + return strequal(pjob->user, server_info->sanitized_username); } /**************************************************************************** Delete a print job. ****************************************************************************/ -bool print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) +bool print_job_delete(struct auth_serversupplied_info *server_info, int snum, + uint32 jobid, WERROR *errcode) { const char* sharename = lp_const_servicename( snum ); struct printjob *pjob; @@ -2009,13 +2005,13 @@ bool print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode = WERR_OK; - owner = is_owner(user, lp_const_servicename(snum), jobid); + owner = is_owner(server_info, lp_const_servicename(snum), jobid); /* Check access against security descriptor or whether the user owns their job. */ if (!owner && - !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { + !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("delete denied by security descriptor\n")); *errcode = WERR_ACCESS_DENIED; @@ -2023,7 +2019,8 @@ bool print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR sys_adminlog( LOG_ERR, "Permission denied-- user not allowed to delete, \ pause, or resume print job. User name: %s. Printer name: %s.", - uidtoname(user->ut.uid), PRINTERNAME(snum) ); + uidtoname(server_info->utok.uid), + PRINTERNAME(snum) ); /* END_ADMIN_LOG */ return False; @@ -2067,7 +2064,8 @@ pause, or resume print job. User name: %s. Printer name: %s.", Pause a job. ****************************************************************************/ -bool print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) +bool print_job_pause(struct auth_serversupplied_info *server_info, int snum, + uint32 jobid, WERROR *errcode) { const char* sharename = lp_const_servicename(snum); struct printjob *pjob; @@ -2076,7 +2074,7 @@ bool print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR * pjob = print_job_find(sharename, jobid); - if (!pjob || !user) { + if (!pjob || !server_info) { DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n", (unsigned int)jobid )); return False; @@ -2088,15 +2086,16 @@ bool print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR * return False; } - if (!is_owner(user, lp_const_servicename(snum), jobid) && - !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { + if (!is_owner(server_info, lp_const_servicename(snum), jobid) && + !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("pause denied by security descriptor\n")); /* BEGIN_ADMIN_LOG */ sys_adminlog( LOG_ERR, "Permission denied-- user not allowed to delete, \ pause, or resume print job. User name: %s. Printer name: %s.", - uidtoname(user->ut.uid), PRINTERNAME(snum) ); + uidtoname(server_info->utok.uid), + PRINTERNAME(snum) ); /* END_ADMIN_LOG */ *errcode = WERR_ACCESS_DENIED; @@ -2127,7 +2126,8 @@ pause, or resume print job. User name: %s. Printer name: %s.", Resume a job. ****************************************************************************/ -bool print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) +bool print_job_resume(struct auth_serversupplied_info *server_info, int snum, + uint32 jobid, WERROR *errcode) { const char *sharename = lp_const_servicename(snum); struct printjob *pjob; @@ -2135,8 +2135,8 @@ bool print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR struct printif *current_printif = get_printer_fns( snum ); pjob = print_job_find(sharename, jobid); - - if (!pjob || !user) { + + if (!pjob || !server_info) { DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n", (unsigned int)jobid )); return False; @@ -2148,8 +2148,8 @@ bool print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR return False; } - if (!is_owner(user, lp_const_servicename(snum), jobid) && - !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { + if (!is_owner(server_info, lp_const_servicename(snum), jobid) && + !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("resume denied by security descriptor\n")); *errcode = WERR_ACCESS_DENIED; @@ -2157,7 +2157,8 @@ bool print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR sys_adminlog( LOG_ERR, "Permission denied-- user not allowed to delete, \ pause, or resume print job. User name: %s. Printer name: %s.", - uidtoname(user->ut.uid), PRINTERNAME(snum) ); + uidtoname(server_info->utok.uid), + PRINTERNAME(snum) ); /* END_ADMIN_LOG */ return False; } @@ -2357,12 +2358,12 @@ static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid) Start spooling a job - return the jobid. ***************************************************************************/ -uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode ) +uint32 print_job_start(struct auth_serversupplied_info *server_info, int snum, + char *jobname, NT_DEVICEMODE *nt_devmode ) { uint32 jobid; char *path; struct printjob pjob; - user_struct *vuser; const char *sharename = lp_const_servicename(snum); struct tdb_print_db *pdb = get_print_db_byname(sharename); int njobs; @@ -2372,7 +2373,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE if (!pdb) return (uint32)-1; - if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) { + if (!print_access_check(server_info, snum, PRINTER_ACCESS_USE)) { DEBUG(3, ("print_job_start: job start denied by security descriptor\n")); release_print_db(pdb); return (uint32)-1; @@ -2437,17 +2438,12 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE fstrcpy(pjob.jobname, jobname); - if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { - fstrcpy(pjob.user, lp_printjob_username(snum)); - standard_sub_basic( - vuser->server_info->sanitized_username, - pdb_get_domain(vuser->server_info->sam_account), - pjob.user, sizeof(pjob.user)-1); - /* ensure NULL termination */ - pjob.user[sizeof(pjob.user)-1] = '\0'; - } else { - fstrcpy(pjob.user, uidtoname(user->ut.uid)); - } + fstrcpy(pjob.user, lp_printjob_username(snum)); + standard_sub_basic(server_info->sanitized_username, + pdb_get_domain(server_info->sam_account), + pjob.user, sizeof(pjob.user)-1); + /* ensure NULL termination */ + pjob.user[sizeof(pjob.user)-1] = '\0'; fstrcpy(pjob.queuename, lp_const_servicename(snum)); @@ -2775,12 +2771,14 @@ int print_queue_status(int snum, Pause a queue. ****************************************************************************/ -bool print_queue_pause(struct current_user *user, int snum, WERROR *errcode) +bool print_queue_pause(struct auth_serversupplied_info *server_info, int snum, + WERROR *errcode) { int ret; struct printif *current_printif = get_printer_fns( snum ); - if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { + if (!print_access_check(server_info, snum, + PRINTER_ACCESS_ADMINISTER)) { *errcode = WERR_ACCESS_DENIED; return False; } @@ -2811,12 +2809,14 @@ bool print_queue_pause(struct current_user *user, int snum, WERROR *errcode) Resume a queue. ****************************************************************************/ -bool print_queue_resume(struct current_user *user, int snum, WERROR *errcode) +bool print_queue_resume(struct auth_serversupplied_info *server_info, int snum, + WERROR *errcode) { int ret; struct printif *current_printif = get_printer_fns( snum ); - if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { + if (!print_access_check(server_info, snum, + PRINTER_ACCESS_ADMINISTER)) { *errcode = WERR_ACCESS_DENIED; return False; } @@ -2847,7 +2847,8 @@ bool print_queue_resume(struct current_user *user, int snum, WERROR *errcode) Purge a queue - implemented by deleting all jobs that we can delete. ****************************************************************************/ -bool print_queue_purge(struct current_user *user, int snum, WERROR *errcode) +bool print_queue_purge(struct auth_serversupplied_info *server_info, int snum, + WERROR *errcode) { print_queue_struct *queue; print_status_struct status; @@ -2857,14 +2858,16 @@ bool print_queue_purge(struct current_user *user, int snum, WERROR *errcode) /* Force and update so the count is accurate (i.e. not a cached count) */ print_queue_update(snum, True); - can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER); + can_job_admin = print_access_check(server_info, snum, + JOB_ACCESS_ADMINISTER); njobs = print_queue_status(snum, &queue, &status); if ( can_job_admin ) become_root(); for (i=0;i Date: Wed, 16 Jul 2008 12:37:48 -0400 Subject: Allow %u parameters for print job username - use advanced sub Based on 3.0 and 3.2 patch from Bo Yang Bo, please verify this version works for you. (This used to be commit 9e6760cfeaf77e80df3b84004090d934f3c2d574) --- source3/printing/printing.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/printing/printing.c') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index a425b87907..1016e6183d 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -2439,9 +2439,11 @@ uint32 print_job_start(struct auth_serversupplied_info *server_info, int snum, fstrcpy(pjob.jobname, jobname); fstrcpy(pjob.user, lp_printjob_username(snum)); - standard_sub_basic(server_info->sanitized_username, - pdb_get_domain(server_info->sam_account), - pjob.user, sizeof(pjob.user)-1); + standard_sub_advanced(sharename, server_info->sanitized_username, + path, server_info->utok.gid, + server_info->sanitized_username, + pdb_get_domain(server_info->sam_account), + pjob.user, sizeof(pjob.user)-1); /* ensure NULL termination */ pjob.user[sizeof(pjob.user)-1] = '\0'; -- cgit