From 45b291b851834f4c4dffb1a2eb8d5afd53d5823d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 13 Apr 2002 00:58:04 +0000 Subject: when background printing wasn't enabled printing was completely broken as the pid was 0 (This used to be commit f16033635f5125758a3d2c3b0780d5bd2bd7bdbd) --- source3/printing/printing.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/printing') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index ad5acb1505..a28d95fcc8 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -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 1667a821060b8bbc1cef3db473f6967cd02f5886 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 15 Apr 2002 04:07:13 +0000 Subject: Merge of print server permission handling fixes from HEAD. Unit tests rock! (This used to be commit bc673c42045ceb46d9569bc4d88f9c64897fc85a) --- source3/printing/nt_printing.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'source3/printing') diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 907c3fd8e6..29bc185a6d 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -56,6 +56,22 @@ STANDARD_MAPPING printer_std_mapping = { PRINTER_ALL_ACCESS }; +/* Map generic permissions to print server object specific permissions */ + +GENERIC_MAPPING printserver_generic_mapping = { + SERVER_READ, + SERVER_WRITE, + SERVER_EXECUTE, + SERVER_ALL_ACCESS +}; + +STANDARD_MAPPING printserver_std_mapping = { + SERVER_READ, + SERVER_WRITE, + SERVER_EXECUTE, + SERVER_ALL_ACCESS +}; + /* We need one default form to support our default printer. Msoft adds the forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an array index). Letter is always first, so (for the current code) additions -- cgit From baf8e2e7127eb037264472ceb463cd61d1425a65 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 19 Apr 2002 17:10:56 +0000 Subject: When opening a tdb fails - don't expect to be able to do tdb_errstr ! (Doh!). Jeremy. (This used to be commit 9209d8e718e860e6a58937376cbb437b6b7adbbb) --- source3/printing/printing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/printing') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index a28d95fcc8..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(); -- cgit From 16e1ff4f3a09a1207e5c7b1d26c0fbe961de76d1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 19 Apr 2002 17:59:13 +0000 Subject: Added Martin's lpq parse fixes from 2.2. Jeremy. (This used to be commit 3853234c2649c501e9876f940f802be86cb6383d) --- source3/printing/lpq_parse.c | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) (limited to 'source3/printing') diff --git a/source3/printing/lpq_parse.c b/source3/printing/lpq_parse.c index 13b87045cd..9d8b1cc2aa 100644 --- a/source3/printing/lpq_parse.c +++ b/source3/printing/lpq_parse.c @@ -149,21 +149,17 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) StrnCpy(buf->fs_file,tok[FILETOK],sizeof(buf->fs_file)-1); if ((FILETOK + 1) != TOTALTOK) { - int bufsize; int i; - bufsize = sizeof(buf->fs_file) - strlen(buf->fs_file) - 1; - for (i = (FILETOK + 1); i < TOTALTOK; i++) { - safe_strcat(buf->fs_file," ",bufsize); - safe_strcat(buf->fs_file,tok[i],bufsize - 1); - bufsize = sizeof(buf->fs_file) - strlen(buf->fs_file) - 1; - if (bufsize <= 0) { - break; - } + /* FIXME: Using fstrcat rather than other means is a bit + * inefficient; this might be a problem for enormous queues with + * many fields. */ + fstrcat(buf->fs_file, " "); + fstrcat(buf->fs_file, tok[i]); } /* Ensure null termination. */ - buf->fs_file[sizeof(buf->fs_file)-1] = '\0'; + fstrterminate(buf->fs_file); } #ifdef PRIOTOK @@ -282,21 +278,17 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first) StrnCpy(buf->fs_file,tokarr[LPRNG_FILETOK],sizeof(buf->fs_file)-1); if ((LPRNG_FILETOK + 1) != LPRNG_TOTALTOK) { - int bufsize; int i; - bufsize = sizeof(buf->fs_file) - strlen(buf->fs_file) - 1; - for (i = (LPRNG_FILETOK + 1); i < LPRNG_TOTALTOK; i++) { - safe_strcat(buf->fs_file," ",bufsize); - safe_strcat(buf->fs_file,tokarr[i],bufsize - 1); - bufsize = sizeof(buf->fs_file) - strlen(buf->fs_file) - 1; - if (bufsize <= 0) { - break; - } + /* FIXME: Using fstrcat rather than other means is a bit + * inefficient; this might be a problem for enormous queues with + * many fields. */ + fstrcat(buf->fs_file, " "); + fstrcat(buf->fs_file, tokarr[i]); } /* Ensure null termination. */ - buf->fs_file[sizeof(buf->fs_file)-1] = '\0'; + fstrterminate(buf->fs_file); } return(True); -- cgit From 059da8fb3b7197bd6a9bfe57940a96a2546e63a5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 9 May 2002 19:54:47 +0000 Subject: Merged in printing fixes... There were many missing ! Jeremy (This used to be commit 32fa089adead6ff3279172fd36560f4f9e2aeef0) --- source3/printing/nt_printing.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'source3/printing') diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 29bc185a6d..9b79eac3e0 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -314,6 +314,11 @@ BOOL nt_printing_init(void) update_c_setprinter(True); + /* + * register callback to handle updating printers as new + * drivers are installed + */ + message_register(MSG_PRINTER_DRVUPGRADE, do_drv_upgrade_printer); return True; } @@ -2959,6 +2964,30 @@ uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level) return result; } +/**************************************************************************** + Delete driver init data stored for a specified driver +****************************************************************************/ + +BOOL del_driver_init(char *drivername) +{ + pstring key; + TDB_DATA kbuf; + + if (!drivername || !*drivername) { + DEBUG(3,("del_driver_init: No drivername specified!\n")); + return False; + } + + slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, drivername); + + kbuf.dptr = key; + kbuf.dsize = strlen(key)+1; + + DEBUG(6,("del_driver_init: Removing driver init data for [%s]\n", drivername)); + + return (tdb_delete(tdb_drivers, kbuf) == 0); +} + /**************************************************************************** Pack up the DEVMODE and specifics for a printer into a 'driver init' entry in the tdb. Note: this is different from the driver entry and the printer -- cgit From 961352403f169cbcbf899e7e24dd31473948f785 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 10 May 2002 00:07:37 +0000 Subject: Fix build. Changed MSG_PRINTER_UPDATE to MSG_PRINTER_DRVUPGRADE. Jeremy, please verify that this was ok... (This used to be commit f191563c7f1cfb7250327333a9470edc4dbedde1) --- source3/printing/printing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/printing') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index d7ac1f49c7..b599d8d7ea 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -520,7 +520,7 @@ void start_background_queue(void) if (!print_backend_init()) exit(1); - message_register(MSG_PRINTER_UPDATE, print_queue_receive); + message_register(MSG_PRINTER_DRVUPGRADE, print_queue_receive); DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n")); while (1) { @@ -537,7 +537,7 @@ 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, + message_send_pid(background_lpq_updater_pid, MSG_PRINTER_DRVUPGRADE, &snum, sizeof(snum), False); } } -- cgit From 6b623b68d4ff5178b592e9d59c2f495b8c4c2953 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 10 May 2002 00:08:54 +0000 Subject: Ok, ok, I was too impatient... (This used to be commit af35c5a57ca5544441bd82b695d878f388cd5e73) --- source3/printing/printing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/printing') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index b599d8d7ea..d7ac1f49c7 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -520,7 +520,7 @@ void start_background_queue(void) if (!print_backend_init()) exit(1); - message_register(MSG_PRINTER_DRVUPGRADE, print_queue_receive); + message_register(MSG_PRINTER_UPDATE, print_queue_receive); DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n")); while (1) { @@ -537,7 +537,7 @@ 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_DRVUPGRADE, + message_send_pid(background_lpq_updater_pid, MSG_PRINTER_UPDATE, &snum, sizeof(snum), False); } } -- cgit From b0ffabdcca53507a99ce8f00fccf2d4cac78fd6d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 7 Jun 2002 14:33:33 +0000 Subject: Globally replace 'global_sam_sid' with get_global_sam_sid(), a self initialising function. This patch thanks to the work of "Stefan (metze) Metzmacher" This is partly to enable the transition to SIDs in the the passdb. Andrew Bartlett (This used to be commit 96afea638e15d4cbadc57023a511094a770c6adc) --- source3/printing/nt_printing.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/printing') diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 9b79eac3e0..ecf873c1ba 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -3683,7 +3683,6 @@ WERROR nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr) static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx) { - extern DOM_SID global_sam_sid; SEC_ACE ace[3]; SEC_ACCESS sa; SEC_ACL *psa = NULL; @@ -3709,7 +3708,7 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx) This should emulate a lanman printer as security settings can't be changed. */ - sid_copy(&owner_sid, &global_sam_sid); + sid_copy(&owner_sid, get_global_sam_sid()); sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN); } -- cgit From 7ed56087329bd972c7402f710469d427c3159327 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 21 Jun 2002 01:19:31 +0000 Subject: Format tidyup before I start working on scalability fixes (one file per print queue). Jeremy. (This used to be commit 6544a500d0696c9fe1f1abc067a8b963a0e2b8da) --- source3/printing/printing.c | 208 ++++++++++++++++++++++++++++---------------- 1 file changed, 134 insertions(+), 74 deletions(-) (limited to 'source3/printing') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index d7ac1f49c7..47fc019d64 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -80,8 +80,9 @@ BOOL print_backend_init(void) } /**************************************************************************** -useful function to generate a tdb key + Useful function to generate a tdb key. ****************************************************************************/ + static TDB_DATA print_key(int jobid) { static int j; @@ -94,15 +95,17 @@ 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 pjob; TDB_DATA ret; ret = tdb_fetch(tdb, print_key(jobid)); - if (!ret.dptr || ret.dsize != sizeof(pjob)) return NULL; + if (!ret.dptr || ret.dsize != sizeof(pjob)) + return NULL; memcpy(&pjob, ret.dptr, sizeof(pjob)); free(ret.dptr); @@ -110,8 +113,9 @@ static struct printjob *print_job_find(int jobid) } /**************************************************************************** -store a job structure back to the database + Store a job structure back to the database. ****************************************************************************/ + static BOOL print_job_store(int jobid, struct printjob *pjob) { TDB_DATA d; @@ -124,25 +128,28 @@ static BOOL print_job_store(int jobid, struct printjob *pjob) } /**************************************************************************** -parse a file name from the system spooler to generate a jobid + Parse a file name from the system spooler to generate a jobid. ****************************************************************************/ + static int 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 -1; fname += strlen(PRINT_SPOOL_PREFIX); jobid = atoi(fname); - if (jobid <= 0) return -1; + if (jobid <= 0) + return -1; return 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; @@ -176,14 +183,18 @@ 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) { 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; + if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) + return 0; memcpy(&jobid, key.dptr, sizeof(jobid)); memcpy(&pjob, data.dptr, sizeof(pjob)); @@ -197,7 +208,8 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void /* 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 (jobid == ts->queue[i].job + UNIX_JOB_START) + break; } if (i == ts->qcount) tdb_delete(tdb, key); @@ -220,7 +232,8 @@ 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].fs_file); - if (jobid == qid) break; + if (jobid == qid) + break; } /* The job isn't in the system queue - we have to assume it has @@ -249,8 +262,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 + Check if the print queue has been updated recently enough. ****************************************************************************/ + static void print_cache_flush(int snum) { fstring key; @@ -327,7 +341,7 @@ static void send_queue_message(const char *printer_name, uint32 high, uint32 low } /**************************************************************************** -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 in the background ****************************************************************************/ static void print_queue_update_background(int snum) @@ -484,8 +498,9 @@ static void print_queue_update_background(int snum) } /**************************************************************************** -this is the receive function of the background lpq updater + 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; @@ -496,8 +511,9 @@ static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len) static pid_t background_lpq_updater_pid; /**************************************************************************** -main thread of the background lpq updater + Main thread of the background lpq updater. ****************************************************************************/ + void start_background_queue(void) { DEBUG(3,("start_background_queue: Starting background LPQ thread\n")); @@ -532,8 +548,9 @@ void start_background_queue(void) } /**************************************************************************** -update the internal database from the system print queue for a queue + 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) { @@ -543,8 +560,9 @@ static void print_queue_update(int snum) } /**************************************************************************** -check if a jobid is valid. It is valid if it exists in the database + 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)); @@ -552,46 +570,53 @@ BOOL print_job_exists(int 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 + 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) { 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) { 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) { 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) { DEBUG(2,("print_job_set_place not implemented yet\n")); @@ -599,27 +624,30 @@ BOOL print_job_set_place(int jobid, int place) } /**************************************************************************** -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) { 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); } - /**************************************************************************** -delete a print job - don't update queue + Delete a print job - don't update queue. ****************************************************************************/ + static BOOL print_job_delete1(int 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. @@ -638,8 +666,7 @@ 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 %d not seen by lpr\n", jobid)); } /* Set the tdb entry to be deleting. */ @@ -661,14 +688,16 @@ static BOOL print_job_delete1(int jobid) } /**************************************************************************** -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) { 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,8 +707,9 @@ 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) { int snum = print_job_snum(jobid); @@ -703,7 +733,8 @@ 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 */ @@ -719,19 +750,21 @@ BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode) return !print_job_exists(jobid); } - /**************************************************************************** -pause a job + Pause a job. ****************************************************************************/ + BOOL print_job_pause(struct current_user *user, int 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) { @@ -773,17 +806,20 @@ 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) { 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); @@ -814,8 +850,9 @@ BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode) } /**************************************************************************** -write to a print file + Write to a print file. ****************************************************************************/ + int print_job_write(int jobid, const char *buf, int size) { int return_code; @@ -870,6 +907,7 @@ 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; @@ -913,12 +951,14 @@ int print_queue_length(int snum, print_status_struct *pstatus) /**************************************************************************** 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); + if (print_cache_expired(snum)) + print_queue_update(snum); total_jobs = tdb_fetch_int32(tdb, "INFO/total_jobs"); if (total_jobs >0) @@ -930,6 +970,7 @@ static int get_total_jobs(int snum) /*************************************************************************** start spooling a job - return the jobid ***************************************************************************/ + int print_job_start(struct current_user *user, int snum, char *jobname) { int jobid; @@ -1075,7 +1116,7 @@ to open spool file %s.\n", pjob.filename)); } /**************************************************************************** - Update the number of pages spooled to jobid + Update the number of pages spooled to jobid. ****************************************************************************/ void print_job_endpage(int jobid) @@ -1169,14 +1210,18 @@ fail: 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; - 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 +1229,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,14 +1252,18 @@ 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; - 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)); @@ -1226,25 +1276,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) @@ -1255,7 +1312,8 @@ int print_queue_status(int snum, TDB_DATA data, key; /* 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); *queue = NULL; @@ -1289,8 +1347,7 @@ int print_queue_status(int snum, /* 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; /* @@ -1314,21 +1371,22 @@ 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 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; @@ -1359,8 +1417,9 @@ BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode) } /**************************************************************************** - resume a queue + Resume a queue. ****************************************************************************/ + BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode) { char *printer_name; @@ -1391,8 +1450,9 @@ BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode) } /**************************************************************************** - 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; -- cgit From 900fb62238be30cdc87bfd2bede6fdff611ebae5 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 24 Jun 2002 19:51:23 +0000 Subject: printing merge from SAMBA_2_2. Ther server code looks to be in sync now. Mostly formatting and s/free/SAFE_FREE/g changes with the two exceptions being * John driver init changes * Tim's printer enumeration bug fix (This used to be commit f7536762863811f96364e8acd3716bdb7d665bbf) --- source3/printing/nt_printing.c | 19 ++++++++++++------- source3/printing/pcap.c | 22 +++++++++++----------- source3/printing/print_cups.c | 2 +- source3/printing/printing.c | 20 ++++++++++---------- 4 files changed, 34 insertions(+), 29 deletions(-) (limited to 'source3/printing') diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index ecf873c1ba..08d5ea430a 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -2838,7 +2838,7 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level) Initialize printer devmode & data with previously saved driver init values. ****************************************************************************/ -static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr) +static BOOL set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr) { int len = 0; pstring key; @@ -2891,9 +2891,14 @@ static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr) * NT/2k does not change out the entire DeviceMode of a printer * when changing the driver. Only the driverextra, private, & * driverversion fields. --jerry (Thu Mar 14 08:58:43 CST 2002) + * + * Later e4xamination revealed that Windows NT/2k does reset the + * the printer's device mode, bit **only** when you change a + * property of the device mode such as the page orientation. + * --jerry */ -#if 0 /* JERRY */ +#if 1 /* JERRY */ /* * Bind the saved DEVMODE to the new the printer. @@ -2945,19 +2950,19 @@ static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr) is bound to the new printer. ****************************************************************************/ -uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level) +BOOL set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level) { - uint32 result; + BOOL result = False; switch (level) { case 2: - { result=set_driver_init_2(printer->info_2); break; - } + default: - result=1; + DEBUG(0,("set_driver_init: Programmer's error! Unknown driver_init level [%d]\n", + level)); break; } diff --git a/source3/printing/pcap.c b/source3/printing/pcap.c index 920c6f354e..01e03c7c6b 100644 --- a/source3/printing/pcap.c +++ b/source3/printing/pcap.c @@ -111,7 +111,7 @@ static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *)) iEtat = 0; /* scan qconfig file for searching : */ - for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line)) + for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); SAFE_FREE(line)) { if (*line == '*' || *line == 0) continue; @@ -181,7 +181,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername) if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL) { DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz)); - free(pName); + SAFE_FREE(pName); return(False); } slprintf(pName, iLg + 9, "%s:",pszPrintername); @@ -189,7 +189,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername) /*DEBUG(3,( " Looking for entry %s\n",pName));*/ iEtat = 0; /* scan qconfig file for searching : */ - for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line)) + for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); SAFE_FREE(line)) { if (*line == '*' || *line == 0) continue; @@ -208,8 +208,8 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername) { /* name is found without stanza device */ /* probably a good printer ??? */ - free (line); - free(pName); + SAFE_FREE (line); + SAFE_FREE(pName); fclose(pfile); return(True); } @@ -222,15 +222,15 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername) else if (strlocate(line,"device")) { /* it's a good virtual printer */ - free (line); - free(pName); + SAFE_FREE (line); + SAFE_FREE(pName); fclose(pfile); return(True); } break; } } - free (pName); + SAFE_FREE (pName); x_fclose(pfile); return(False); } @@ -288,7 +288,7 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname) return(False); } - for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line)) + for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); SAFE_FREE(line)) { if (*line == '#' || *line == 0) continue; @@ -307,7 +307,7 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname) { /* normalise the case */ pstrcpy(pszPrintername,p); - free(line); + SAFE_FREE(line); x_fclose(pfile); return(True); } @@ -369,7 +369,7 @@ void pcap_printer_fn(void (*fn)(char *, char *)) return; } - for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line)) + for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); SAFE_FREE(line)) { if (*line == '#' || *line == 0) continue; diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c index b5315e10b2..51ebb739a3 100644 --- a/source3/printing/print_cups.c +++ b/source3/printing/print_cups.c @@ -824,7 +824,7 @@ cups_queue_get(int snum, print_queue_struct **q, print_status_struct *status) ippDelete(response); httpClose(http); - free (queue); + SAFE_FREE(queue); return (0); } diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 47fc019d64..aa9df5e47f 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -52,7 +52,8 @@ BOOL print_backend_init(void) { char *sversion = "INFO/version"; - if (tdb && local_pid == sys_getpid()) return True; + 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", @@ -108,7 +109,7 @@ static struct printjob *print_job_find(int jobid) return NULL; memcpy(&pjob, ret.dptr, sizeof(pjob)); - free(ret.dptr); + SAFE_FREE(ret.dptr); return &pjob; } @@ -291,7 +292,7 @@ static pid_t get_updating_pid(fstring printer_name) 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; @@ -568,10 +569,9 @@ 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 + 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. ****************************************************************************/ @@ -922,7 +922,7 @@ static int get_queue_status(int snum, print_status_struct *status) 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; } @@ -968,7 +968,7 @@ static int get_total_jobs(int snum) } /*************************************************************************** -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) @@ -1116,7 +1116,7 @@ to open spool file %s.\n", pjob.filename)); } /**************************************************************************** - Update the number of pages spooled to jobid. + Update the number of pages spooled to jobid ****************************************************************************/ void print_job_endpage(int jobid) @@ -1330,7 +1330,7 @@ int print_queue_status(int snum, if (data.dsize == sizeof(*status)) { memcpy(status, data.dptr, sizeof(*status)); } - free(data.dptr); + SAFE_FREE(data.dptr); } /* -- cgit From 86e2e9b8a3d1c598634308d91cf1fb2c52efd9bd Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 24 Jun 2002 20:26:37 +0000 Subject: backing out changes for now (This used to be commit e3422addeb2a74ba92e3b5374d1a1efbcc825d5a) --- source3/printing/pcap.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'source3/printing') diff --git a/source3/printing/pcap.c b/source3/printing/pcap.c index 01e03c7c6b..920c6f354e 100644 --- a/source3/printing/pcap.c +++ b/source3/printing/pcap.c @@ -111,7 +111,7 @@ static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *)) iEtat = 0; /* scan qconfig file for searching : */ - for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); SAFE_FREE(line)) + for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line)) { if (*line == '*' || *line == 0) continue; @@ -181,7 +181,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername) if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL) { DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz)); - SAFE_FREE(pName); + free(pName); return(False); } slprintf(pName, iLg + 9, "%s:",pszPrintername); @@ -189,7 +189,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername) /*DEBUG(3,( " Looking for entry %s\n",pName));*/ iEtat = 0; /* scan qconfig file for searching : */ - for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); SAFE_FREE(line)) + for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line)) { if (*line == '*' || *line == 0) continue; @@ -208,8 +208,8 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername) { /* name is found without stanza device */ /* probably a good printer ??? */ - SAFE_FREE (line); - SAFE_FREE(pName); + free (line); + free(pName); fclose(pfile); return(True); } @@ -222,15 +222,15 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername) else if (strlocate(line,"device")) { /* it's a good virtual printer */ - SAFE_FREE (line); - SAFE_FREE(pName); + free (line); + free(pName); fclose(pfile); return(True); } break; } } - SAFE_FREE (pName); + free (pName); x_fclose(pfile); return(False); } @@ -288,7 +288,7 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname) return(False); } - for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); SAFE_FREE(line)) + for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line)) { if (*line == '#' || *line == 0) continue; @@ -307,7 +307,7 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname) { /* normalise the case */ pstrcpy(pszPrintername,p); - SAFE_FREE(line); + free(line); x_fclose(pfile); return(True); } @@ -369,7 +369,7 @@ void pcap_printer_fn(void (*fn)(char *, char *)) return; } - for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); SAFE_FREE(line)) + for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line)) { if (*line == '#' || *line == 0) continue; -- cgit From 96c00daefa18c756b8e7a6163a29b39841bda105 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 24 Jun 2002 21:14:30 +0000 Subject: replacing free() with SAFE_FREE() where possible (This used to be commit 5a4a7e5a88f4fdc5891436b05e44b05d1e7ad3f1) --- source3/printing/pcap.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/printing') diff --git a/source3/printing/pcap.c b/source3/printing/pcap.c index 920c6f354e..4bca63fffb 100644 --- a/source3/printing/pcap.c +++ b/source3/printing/pcap.c @@ -111,7 +111,7 @@ static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *)) iEtat = 0; /* scan qconfig file for searching : */ - for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line)) + for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line)) { if (*line == '*' || *line == 0) continue; @@ -181,7 +181,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername) if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL) { DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz)); - free(pName); + SAFE_FREE(pName); return(False); } slprintf(pName, iLg + 9, "%s:",pszPrintername); @@ -189,7 +189,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername) /*DEBUG(3,( " Looking for entry %s\n",pName));*/ iEtat = 0; /* scan qconfig file for searching : */ - for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line)) + for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line)) { if (*line == '*' || *line == 0) continue; @@ -209,7 +209,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername) /* name is found without stanza device */ /* probably a good printer ??? */ free (line); - free(pName); + SAFE_FREE(pName); fclose(pfile); return(True); } @@ -223,7 +223,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername) { /* it's a good virtual printer */ free (line); - free(pName); + SAFE_FREE(pName); fclose(pfile); return(True); } @@ -288,7 +288,7 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname) return(False); } - for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line)) + for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line)) { if (*line == '#' || *line == 0) continue; @@ -307,7 +307,7 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname) { /* normalise the case */ pstrcpy(pszPrintername,p); - free(line); + SAFE_FREE(line); x_fclose(pfile); return(True); } @@ -369,7 +369,7 @@ void pcap_printer_fn(void (*fn)(char *, char *)) return; } - for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line)) + for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line)) { if (*line == '#' || *line == 0) continue; -- cgit From a9093a1b5819d74e6dc21c413dc84f8fd3f181dc Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 27 Jun 2002 18:10:56 +0000 Subject: It's fairly obvious that no one has tried to upload a driver to a Samba print server running HEAD in a while. This has been broken since tridge's changes to make_connection() to not do the chdir() to the connect_path. Sorry it took me so long to get around to fixing it. The problem occured with our internal use of make_connection(). jerry (This used to be commit b5bc8aa0f68ceebfb5c0ec15ff93b0172cec36d8) --- source3/printing/nt_printing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/printing') diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 08d5ea430a..0ec960b3f0 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -1064,7 +1064,7 @@ static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in, /* Null password is ok - we are already an authenticated user... */ null_pw = data_blob(NULL, 0); become_root(); - conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status); + conn = make_connection_with_chdir("print$", null_pw, "A:", user->vuid, &nt_status); unbecome_root(); if (conn == NULL) { @@ -1382,7 +1382,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, become_root(); null_pw = data_blob(NULL, 0); - conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status); + conn = make_connection_with_chdir("print$", null_pw, "A:", user->vuid, &nt_status); unbecome_root(); if (conn == NULL) { -- cgit From 452eb38df0553886313c9b19a945385d853e19ab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Jun 2002 00:17:15 +0000 Subject: Proper merge of all the working printing stuff from APPLIANCE_HEAD. Now let's keep this in sync ! Jeremy. (This used to be commit 3603cd4947df2c10df604447dc542932cb9e5d5a) --- source3/printing/notify.c | 230 ++++++++++++++++++++++++++++ source3/printing/printing.c | 363 +++++++++++++++++++++++++------------------- 2 files changed, 435 insertions(+), 158 deletions(-) create mode 100644 source3/printing/notify.c (limited to 'source3/printing') diff --git a/source3/printing/notify.c b/source3/printing/notify.c new file mode 100644 index 0000000000..5ba7faba59 --- /dev/null +++ b/source3/printing/notify.c @@ -0,0 +1,230 @@ +/* + Unix SMB/Netbios implementation. + Version 2.2 + printing backend routines + Copyright (C) Tim Potter, 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 + 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 "printing.h" + +/* + * Print notification routines + */ + +static void send_spoolss_notify2_msg(struct spoolss_notify_msg *msg) +{ + char *buf = NULL; + int buflen = 0, len; + TDB_CONTEXT *tdb; + + /* Let's not waste any time with this */ + + if (lp_disable_spoolss()) + return; + + /* Flatten data into a message */ + +again: + len = 0; + + /* Pack header */ + + len += tdb_pack(buf + len, buflen - len, "f", msg->printer); + + len += tdb_pack(buf + len, buflen - len, "ddddd", + msg->type, msg->field, msg->id, msg->len, msg->flags); + + /* Pack data */ + + if (msg->len == 0) + len += tdb_pack(buf + len, buflen - len, "dd", + msg->notify.value[0], msg->notify.value[1]); + else + len += tdb_pack(buf + len, buflen - len, "B", + msg->len, msg->notify.data); + + if (buflen != len) { + buf = Realloc(buf, len); + buflen = len; + goto again; + } + + /* Send message */ + + tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0); + + if (!tdb) { + DEBUG(3, ("Failed to open connections database in send_spoolss_notify2_msg\n")); + return; + } + + message_send_all(tdb, MSG_PRINTER_NOTIFY2, buf, + buflen, False, NULL); + + SAFE_FREE(buf); + tdb_close(tdb); +} + +static void send_notify_field_values(const char *printer_name, uint32 type, + uint32 field, uint32 id, uint32 value1, + uint32 value2, uint32 flags) +{ + struct spoolss_notify_msg msg; + + ZERO_STRUCT(msg); + + fstrcpy(msg.printer, printer_name); + msg.type = type; + msg.field = field; + msg.id = id; + msg.notify.value[0] = value1; + msg.notify.value[1] = value2; + msg.flags = flags; + + send_spoolss_notify2_msg(&msg); +} + +static void send_notify_field_buffer(const char *printer_name, uint32 type, + uint32 field, uint32 id, uint32 len, + char *buffer) +{ + struct spoolss_notify_msg msg; + + ZERO_STRUCT(msg); + + fstrcpy(msg.printer, printer_name); + msg.type = type; + msg.field = field; + msg.id = id; + msg.len = len; + msg.notify.data = buffer; + + send_spoolss_notify2_msg(&msg); +} + +/* Send a message that the printer status has changed */ + +void notify_printer_status_byname(char *printer_name, uint32 status) +{ + /* Printer status stored in value1 */ + + send_notify_field_values(printer_name, PRINTER_NOTIFY_TYPE, + PRINTER_NOTIFY_STATUS, 0, + status, 0, 0); +} + +void notify_printer_status(int snum, uint32 status) +{ + char *printer_name = PRINTERNAME(snum); + + if (printer_name) + notify_printer_status_byname(printer_name, status); +} + +void notify_job_status_byname(char *printer_name, uint32 jobid, uint32 status, + uint32 flags) +{ + /* Job id stored in id field, status in value1 */ + + send_notify_field_values(printer_name, JOB_NOTIFY_TYPE, + JOB_NOTIFY_STATUS, jobid, + status, 0, flags); +} + +void notify_job_status(int snum, uint32 jobid, uint32 status) +{ + char *printer_name = PRINTERNAME(snum); + + notify_job_status_byname(printer_name, jobid, status, 0); +} + +void notify_job_total_bytes(int snum, uint32 jobid, uint32 size) +{ + char *printer_name = PRINTERNAME(snum); + + /* Job id stored in id field, status in value1 */ + + send_notify_field_values(printer_name, JOB_NOTIFY_TYPE, + JOB_NOTIFY_TOTAL_BYTES, jobid, + size, 0, 0); +} + +void notify_job_total_pages(int snum, uint32 jobid, uint32 pages) +{ + char *printer_name = PRINTERNAME(snum); + + /* Job id stored in id field, status in value1 */ + + send_notify_field_values(printer_name, JOB_NOTIFY_TYPE, + JOB_NOTIFY_TOTAL_PAGES, jobid, + pages, 0, 0); +} + +void notify_job_username(int snum, uint32 jobid, char *name) +{ + char *printer_name = PRINTERNAME(snum); + + send_notify_field_buffer( + printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, + jobid, strlen(name) + 1, name); +} + +void notify_job_name(int snum, uint32 jobid, char *name) +{ + char *printer_name = PRINTERNAME(snum); + + send_notify_field_buffer( + printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, + jobid, strlen(name) + 1, name); +} + +void notify_job_submitted(int snum, uint32 jobid, time_t submitted) +{ + char *printer_name = PRINTERNAME(snum); + + send_notify_field_buffer( + printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, + jobid, sizeof(submitted), (char *)&submitted); +} + +void notify_printer_delete(char *printer_name) +{ +} + +void notify_printer_add(char *printer_name) +{ +} + +void notify_printer_driver(int num, char *driver_name) +{ +} + +void notify_printer_comment(int num, char *comment) +{ +} + +void notify_printer_sharename(int num, char *share_name) +{ +} + +void notify_printer_port(int num, char *port_name) +{ +} + +void notify_printer_location(int num, char *location) +{ +} diff --git a/source3/printing/printing.c b/source3/printing/printing.c index aa9df5e47f..6ecaf3c9bf 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1,5 +1,6 @@ /* - Unix SMB/CIFS implementation. + Unix SMB/Netbios implementation. + Version 3.0 printing backend routines Copyright (C) Andrew Tridgell 1992-2000 @@ -56,8 +57,8 @@ BOOL print_backend_init(void) 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") )); + DEBUG(0,("print_backend_init: Failed to open printing backend database %s.\n", + lock_path("printing.tdb") )); return False; } local_pid = sys_getpid(); @@ -113,21 +114,178 @@ static struct printjob *print_job_find(int jobid) return &pjob; } +/* Convert a unix jobid to a smb jobid */ + +static int 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(int)) + return 0; + + if (*sysjob == pjob->sysjob) { + int *jobid = (int *)key.dptr; + + sysjob_to_jobid_value = *jobid; + return 1; + } + + return 0; +} + +int sysjob_to_jobid(int unix_jobid) +{ + sysjob_to_jobid_value = -1; + tdb_traverse(tdb, unixjob_traverse_fn, &unix_jobid); + + return sysjob_to_jobid_value; +} + +/**************************************************************************** +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) +{ + 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(int 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 print_job_store(int jobid, struct printjob *pjob) +static BOOL pjob_store(int jobid, struct printjob *pjob) { - TDB_DATA d; + TDB_DATA old_data, new_data; BOOL ret; - d.dptr = (void *)pjob; - d.dsize = sizeof(*pjob); - ret = (tdb_store(tdb, print_key(jobid), d, TDB_REPLACE) == 0); + /* Get old data */ + + old_data = tdb_fetch(tdb, print_key(jobid)); + + /* Store new data */ + + new_data.dptr = (void *)pjob; + new_data.dsize = sizeof(*pjob); + ret = (tdb_store(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); + } + return ret; } +/**************************************************************************** +remove a job structure from the database +****************************************************************************/ +static void pjob_delete(int jobid) +{ + int snum; + struct printjob *pjob = print_job_find(jobid); + uint32 job_status = 0; + + if (!pjob) { + DEBUG(5, ("pjob_delete(): we were asked to delete nonexistent job %d\n", 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(tdb, print_key(jobid)); +} + /**************************************************************************** Parse a file name from the system spooler to generate a jobid. ****************************************************************************/ @@ -175,7 +333,7 @@ static void print_unix_job(int snum, print_queue_struct *q) fstrcpy(pj.user, q->fs_user); fstrcpy(pj.queuename, lp_servicename(snum)); - print_job_store(jobid, &pj); + pjob_store(jobid, &pj); } @@ -213,7 +371,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void break; } if (i == ts->qcount) - tdb_delete(tdb, key); + pjob_delete(jobid); else ts->total_jobs++; return 0; @@ -225,7 +383,7 @@ 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; @@ -252,7 +410,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++; } @@ -328,24 +486,10 @@ static void set_updating_pid(fstring printer_name, BOOL delete) } /**************************************************************************** - 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 +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; @@ -356,6 +500,8 @@ static void print_queue_update_background(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)); /* @@ -448,7 +594,7 @@ static void print_queue_update_background(int snum) pjob->sysjob = 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 @@ -460,21 +606,12 @@ static void print_queue_update_background(int snum) tdb_traverse(tdb, traverse_fn_delete, (void *)&tstruct); - safe_free(tstruct.queue); + SAFE_FREE(tstruct.queue); tdb_store_int32(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 - * "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 )); - send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB); - } + 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 )); /* store the new queue status structure */ slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name); @@ -492,74 +629,12 @@ 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(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. -****************************************************************************/ - -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) -{ - 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); - } -} - /**************************************************************************** Check if a jobid is valid. It is valid if it exists in the database. ****************************************************************************/ @@ -634,7 +709,7 @@ BOOL print_job_set_name(int jobid, char *name) return False; fstrcpy(pjob->jobname, name); - return print_job_store(jobid, pjob); + return pjob_store(jobid, pjob); } /**************************************************************************** @@ -672,7 +747,7 @@ static BOOL print_job_delete1(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); @@ -680,9 +755,8 @@ 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); } @@ -713,7 +787,6 @@ static BOOL is_owner(struct current_user *user, int jobid) 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) { @@ -733,7 +806,7 @@ BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode) return False; } - if (!print_job_delete1(jobid)) + if (!print_job_delete1(jobid)) return False; /* force update the database and say the delete failed if the @@ -741,12 +814,6 @@ BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode) 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); } @@ -758,12 +825,11 @@ BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode) { struct printjob *pjob = print_job_find(jobid); int snum, ret = -1; - char *printer_name; - if (!pjob || !user) + if (!pjob || !user) return False; - if (!pjob->spooled || pjob->sysjob == -1) + if (!pjob->spooled || pjob->sysjob == -1) return False; snum = print_job_snum(jobid); @@ -771,10 +837,6 @@ BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode) 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)) { @@ -796,9 +858,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? */ @@ -812,7 +872,6 @@ BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode) BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode) { struct printjob *pjob = print_job_find(jobid); - char *printer_name; int snum, ret; if (!pjob || !user) @@ -822,6 +881,10 @@ BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode) return False; snum = print_job_snum(jobid); + 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)) { @@ -842,9 +905,7 @@ 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; } @@ -867,7 +928,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; } @@ -1060,8 +1121,8 @@ int print_job_start(struct current_user *user, int snum, char *jobname) 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", + if (jobid == next_jobid || !pjob_store(jobid, &pjob)) { + DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or pjob_store failed.\n", jobid, next_jobid )); jobid = -1; goto fail; @@ -1087,7 +1148,7 @@ 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"); @@ -1105,9 +1166,8 @@ 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"); @@ -1129,7 +1189,7 @@ void print_job_endpage(int jobid) return; pjob->page_count++; - print_job_store(jobid, pjob); + pjob_store(jobid, pjob); } /**************************************************************************** @@ -1180,7 +1240,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; } @@ -1193,7 +1253,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)) @@ -1206,7 +1266,7 @@ 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; } @@ -1389,7 +1449,6 @@ int print_queue_snum(char *qname) 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)) { @@ -1409,9 +1468,7 @@ 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; } @@ -1422,7 +1479,6 @@ BOOL print_queue_pause(struct current_user *user, int snum, WERROR *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)) { @@ -1442,9 +1498,7 @@ BOOL print_queue_resume(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_OK); return True; } @@ -1457,7 +1511,6 @@ 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; @@ -1475,13 +1528,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 e7a866dd3d4fc476599af0e2d5ff8889b1a7941e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Jun 2002 23:11:31 +0000 Subject: Shut down printing tdb correctly - this will be more important when I go to a tdb per-queue for scalability. Jeremy. (This used to be commit e808eb2758ff4ad1eed7b50a02865b87ba0c068e) --- source3/printing/printing.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'source3/printing') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 6ecaf3c9bf..f8b3c9cef0 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -81,6 +81,18 @@ BOOL print_backend_init(void) return nt_printing_init(); } +/**************************************************************************** + Shut down printing backend. Called once at shutdown to close the tdb. +****************************************************************************/ + +void printing_end(void) +{ + if (tdb) { + tdb_close(tdb); + tdb = NULL; + } +} + /**************************************************************************** Useful function to generate a tdb key. ****************************************************************************/ @@ -253,8 +265,9 @@ static BOOL pjob_store(int jobid, struct printjob *pjob) } /**************************************************************************** -remove a job structure from the database + Remove a job structure from the database. ****************************************************************************/ + static void pjob_delete(int jobid) { int snum; @@ -486,7 +499,7 @@ 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. ****************************************************************************/ static void print_queue_update(int snum) @@ -1494,7 +1507,8 @@ 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 */ -- cgit From 9930b0b0650ae3e38c033c28672398425dd8228c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Jul 2002 09:12:41 +0000 Subject: used findstatic.pl to make some variables static and remove some dead code (This used to be commit 91ad9041e9507d36eb3f40c23c5d4df61f139ef0) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/printing') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index f8b3c9cef0..654d79365b 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -22,7 +22,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 -- cgit From 82176f4d85225c2aae15f9ce3e03730f019934f5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 2 Jul 2002 06:34:27 +0000 Subject: Address the string_sub problem by changing len = 0 to mean "no expand". Went through and checked all string_subs I could to ensure they're being used correctly. Jeremy. (This used to be commit 17cae0d683be404be69554cd0e84117bdcc56c87) --- source3/printing/lpq_parse.c | 16 ++++++++-------- source3/printing/print_generic.c | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/printing') diff --git a/source3/printing/lpq_parse.c b/source3/printing/lpq_parse.c index 9d8b1cc2aa..5deb85425e 100644 --- a/source3/printing/lpq_parse.c +++ b/source3/printing/lpq_parse.c @@ -314,7 +314,7 @@ 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 */ - pstring_sub(line,"standard input","STDIN"); + string_sub(line,"standard input","STDIN",0); all_string_sub(line,"(","\"",0); all_string_sub(line,")","\"",0); @@ -431,7 +431,7 @@ 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 */ - pstring_sub(line,"standard input","STDIN"); + string_sub(line,"standard input","STDIN",0); all_string_sub(line,"(","\"",0); all_string_sub(line,")","\"",0); @@ -469,7 +469,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 */ - pstring_sub(line,"-"," "); + string_sub(line,"-"," ",0); for (count=0; count<12 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ; @@ -593,14 +593,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 */ - pstring_sub(line,"standard input","STDIN"); + string_sub(line,"standard input","STDIN",0); 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,"]",""); + string_sub(line,"[job #","",0); + string_sub(line,"]","",0); DEBUG(4,("despues 2 [%s]\n", line)); @@ -656,7 +656,7 @@ 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 */ - pstring_sub(line,"stdin","STDIN"); + string_sub(line,"stdin","STDIN",0); all_string_sub(line,"(","\"",0); all_string_sub(line,")","\"",0); @@ -726,7 +726,7 @@ static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first) int count=0; /* mung all the ":"s to spaces*/ - pstring_sub(line,":"," "); + string_sub(line,":"," ",0); for (count=0; count<10 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ; diff --git a/source3/printing/print_generic.c b/source3/printing/print_generic.c index e1517c5dcb..a32521c721 100644 --- a/source3/printing/print_generic.c +++ b/source3/printing/print_generic.c @@ -78,7 +78,7 @@ static int print_run_command(int snum,char *command, int *outfd, ...) p = PRINTERNAME(snum); pstring_sub(syscmd, "%p", p); - standard_sub_snum(snum,syscmd); + standard_sub_snum(snum,syscmd,sizeof(syscmd)); ret = smbrun(syscmd,outfd); -- cgit From 429400e449e6561ee9a443a728619c43e26ef874 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 8 Jul 2002 18:24:59 +0000 Subject: Fix for LPRng from James Henstridge james@daa.com.au. Jeremy. (This used to be commit 9c93f8908919a02099884d393312ef27d4a2d24e) --- source3/printing/lpq_parse.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/printing') diff --git a/source3/printing/lpq_parse.c b/source3/printing/lpq_parse.c index 5deb85425e..1307cdb3f8 100644 --- a/source3/printing/lpq_parse.c +++ b/source3/printing/lpq_parse.c @@ -255,6 +255,8 @@ 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 (strequal(tokarr[LPRNG_RANKTOK],"done")) { + buf->status = LPQ_PRINTED; } else if (isdigit((int)*tokarr[LPRNG_RANKTOK])) { buf->status = LPQ_QUEUED; } else { -- cgit From 25148a148c1bec680924909722d59d0d47c795ae Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 11 Jul 2002 00:06:29 +0000 Subject: *Experimental* new large-scaling printer code. Splits printing.tdb into a separate tdb per printer, but only keeps (currently one) tdb open at a time (although this is easily changed by changing a #define). Needs scalability testing with large numbers of printers now.... Jeremy. (This used to be commit b0909cfa14fc7ef29d2b98b56d52723570da782a) --- source3/printing/notify.c | 18 +- source3/printing/nt_printing.c | 8 +- source3/printing/print_generic.c | 6 +- source3/printing/printing.c | 534 +++++++++++++++++++++++++++++---------- 4 files changed, 411 insertions(+), 155 deletions(-) (limited to 'source3/printing') diff --git a/source3/printing/notify.c b/source3/printing/notify.c index 5ba7faba59..21e28d0ca7 100644 --- a/source3/printing/notify.c +++ b/source3/printing/notify.c @@ -118,7 +118,7 @@ static void send_notify_field_buffer(const char *printer_name, uint32 type, /* Send a message that the printer status has changed */ -void notify_printer_status_byname(char *printer_name, uint32 status) +void notify_printer_status_byname(const char *printer_name, uint32 status) { /* Printer status stored in value1 */ @@ -129,13 +129,13 @@ void notify_printer_status_byname(char *printer_name, uint32 status) void notify_printer_status(int snum, uint32 status) { - char *printer_name = PRINTERNAME(snum); + const char *printer_name = PRINTERNAME(snum); if (printer_name) notify_printer_status_byname(printer_name, status); } -void notify_job_status_byname(char *printer_name, uint32 jobid, uint32 status, +void notify_job_status_byname(const char *printer_name, uint32 jobid, uint32 status, uint32 flags) { /* Job id stored in id field, status in value1 */ @@ -147,14 +147,14 @@ void notify_job_status_byname(char *printer_name, uint32 jobid, uint32 status, void notify_job_status(int snum, uint32 jobid, uint32 status) { - char *printer_name = PRINTERNAME(snum); + const char *printer_name = PRINTERNAME(snum); notify_job_status_byname(printer_name, jobid, status, 0); } void notify_job_total_bytes(int snum, uint32 jobid, uint32 size) { - char *printer_name = PRINTERNAME(snum); + const char *printer_name = PRINTERNAME(snum); /* Job id stored in id field, status in value1 */ @@ -165,7 +165,7 @@ void notify_job_total_bytes(int snum, uint32 jobid, uint32 size) void notify_job_total_pages(int snum, uint32 jobid, uint32 pages) { - char *printer_name = PRINTERNAME(snum); + const char *printer_name = PRINTERNAME(snum); /* Job id stored in id field, status in value1 */ @@ -176,7 +176,7 @@ void notify_job_total_pages(int snum, uint32 jobid, uint32 pages) void notify_job_username(int snum, uint32 jobid, char *name) { - char *printer_name = PRINTERNAME(snum); + const char *printer_name = PRINTERNAME(snum); send_notify_field_buffer( printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, @@ -185,7 +185,7 @@ void notify_job_username(int snum, uint32 jobid, char *name) void notify_job_name(int snum, uint32 jobid, char *name) { - char *printer_name = PRINTERNAME(snum); + const char *printer_name = PRINTERNAME(snum); send_notify_field_buffer( printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, @@ -194,7 +194,7 @@ void notify_job_name(int snum, uint32 jobid, char *name) void notify_job_submitted(int snum, uint32 jobid, time_t submitted) { - char *printer_name = PRINTERNAME(snum); + const char *printer_name = PRINTERNAME(snum); send_notify_field_buffer( printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 0ec960b3f0..2abe27b95d 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -3593,7 +3593,7 @@ BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level, Store a security desc for a printer. ****************************************************************************/ -WERROR nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr) +WERROR nt_printing_setsec(const char *printername, SEC_DESC_BUF *secdesc_ctr) { SEC_DESC_BUF *new_secdesc_ctr = NULL; SEC_DESC_BUF *old_secdesc_ctr = NULL; @@ -3754,7 +3754,7 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx) Get a security desc for a printer. ****************************************************************************/ -BOOL nt_printing_getsec(TALLOC_CTX *ctx, char *printername, SEC_DESC_BUF **secdesc_ctr) +BOOL nt_printing_getsec(TALLOC_CTX *ctx, const char *printername, SEC_DESC_BUF **secdesc_ctr) { prs_struct ps; fstring key; @@ -3782,7 +3782,7 @@ BOOL nt_printing_getsec(TALLOC_CTX *ctx, char *printername, SEC_DESC_BUF **secde prs_init(&ps, (uint32)sec_desc_size((*secdesc_ctr)->sec) + sizeof(SEC_DESC_BUF), ctx, MARSHALL); - if (sec_io_desc_buf("nt_printing_setsec", secdesc_ctr, &ps, 1)) + if (sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) tdb_prs_store(tdb_printers, key, &ps); prs_mem_free(&ps); @@ -3923,7 +3923,7 @@ BOOL print_access_check(struct current_user *user, int snum, int access_type) uint32 access_granted; NTSTATUS status; BOOL result; - char *pname; + const char *pname; TALLOC_CTX *mem_ctx = NULL; extern struct current_user current_user; diff --git a/source3/printing/print_generic.c b/source3/printing/print_generic.c index a32521c721..4d77b827bf 100644 --- a/source3/printing/print_generic.c +++ b/source3/printing/print_generic.c @@ -55,7 +55,7 @@ static int print_run_command(int snum,char *command, int *outfd, ...) { pstring syscmd; - char *p, *arg; + char *arg; int ret; va_list ap; va_start(ap, outfd); @@ -75,9 +75,7 @@ static int print_run_command(int snum,char *command, int *outfd, ...) } va_end(ap); - p = PRINTERNAME(snum); - - pstring_sub(syscmd, "%p", p); + pstring_sub(syscmd, "%p", PRINTERNAME(snum)); standard_sub_snum(snum,syscmd,sizeof(syscmd)); ret = smbrun(syscmd,outfd); diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 654d79365b..7bfce43af6 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -3,6 +3,7 @@ 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 @@ -38,12 +39,175 @@ static 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 @@ -51,25 +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()) + if (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; - } + + 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 @@ -87,9 +255,15 @@ BOOL print_backend_init(void) void printing_end(void) { - if (tdb) { - tdb_close(tdb); - tdb = NULL; + 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; } } @@ -97,9 +271,9 @@ void printing_end(void) 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; @@ -112,12 +286,16 @@ static TDB_DATA print_key(int jobid) 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)); + ret = tdb_fetch(pdb->tdb, print_key(jobid)); if (!ret.dptr || ret.dsize != sizeof(pjob)) return NULL; @@ -128,7 +306,7 @@ static struct printjob *print_job_find(int jobid) /* Convert a unix jobid to a smb jobid */ -static int sysjob_to_jobid_value; +static uint32 sysjob_to_jobid_value; static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA data, void *state) @@ -136,11 +314,11 @@ static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, struct printjob *pjob = (struct printjob *)data.dptr; int *sysjob = (int *)state; - if (key.dsize != sizeof(int)) + if (key.dsize != sizeof(uint32)) return 0; if (*sysjob == pjob->sysjob) { - int *jobid = (int *)key.dptr; + uint32 *jobid = (uint32 *)key.dptr; sysjob_to_jobid_value = *jobid; return 1; @@ -149,16 +327,28 @@ static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, return 0; } -int sysjob_to_jobid(int unix_jobid) -{ - sysjob_to_jobid_value = -1; - tdb_traverse(tdb, unixjob_traverse_fn, &unix_jobid); +/**************************************************************************** + This is a *horribly expensive call as we have to iterate through all the + current printer tdb's. Don't do this often ! JRA. +****************************************************************************/ - return sysjob_to_jobid_value; +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 + Send notifications based on what has changed after a pjob_store. ****************************************************************************/ static struct { @@ -195,7 +385,7 @@ static uint32 map_to_spoolss_status(uint32 lpq_status) return 0; } -static void pjob_store_notify(int jobid, struct printjob *old_data, +static void pjob_store_notify(uint32 jobid, struct printjob *old_data, struct printjob *new_data) { BOOL new_job = False; @@ -237,20 +427,24 @@ static void pjob_store_notify(int jobid, struct printjob *old_data, Store a job structure back to the database. ****************************************************************************/ -static BOOL pjob_store(int jobid, struct printjob *pjob) +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(tdb, print_key(jobid)); + 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(tdb, print_key(jobid), new_data, TDB_REPLACE) == 0); + ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0); /* Send notify updates for what has changed */ @@ -268,14 +462,19 @@ static BOOL pjob_store(int jobid, struct printjob *pjob) Remove a job structure from the database. ****************************************************************************/ -static void pjob_delete(int jobid) +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 %d\n", jobid)); + DEBUG(5, ("pjob_delete(): we were asked to delete nonexistent job %u\n", + (unsigned int)jobid)); return; } @@ -296,26 +495,26 @@ static void pjob_delete(int jobid) /* Remove from printing.tdb */ - tdb_delete(tdb, print_key(jobid)); + 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; + return (uint32)-1; fname += strlen(PRINT_SPOOL_PREFIX); jobid = atoi(fname); if (jobid <= 0) - return -1; + return (uint32)-1; - return jobid; + return (uint32)jobid; } /**************************************************************************** @@ -324,7 +523,8 @@ static int print_parse_jobid(char *fname) 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 */ @@ -344,7 +544,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); - fstrcpy(pj.queuename, lp_servicename(snum)); + fstrcpy(pj.queuename, lp_const_servicename(snum)); pjob_store(jobid, &pj); } @@ -361,26 +561,30 @@ 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; - int i, jobid; + uint32 jobid; + int i; - if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) + 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) + uint32 u_jobid = ((ts->queue[i].job + UNIX_JOB_START) | QUEUEID_TO_JOBID(queueid)); + if (jobid == u_jobid) break; } if (i == ts->qcount) @@ -403,8 +607,8 @@ 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].fs_file); - if (jobid == qid) + uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file) | QUEUEID_TO_JOBID(queueid); + if (jobid == curr_jobid) break; } @@ -440,8 +644,13 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void 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); } /**************************************************************************** @@ -453,12 +662,15 @@ 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; @@ -473,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) @@ -482,20 +694,24 @@ 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); + tdb_store(pdb->tdb, key, data, TDB_REPLACE); } /**************************************************************************** @@ -512,11 +728,13 @@ static void print_queue_update(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; - /* Convert printer name (i.e. share name) to unix-codepage for all of the - * following tdb key generation */ - fstrcpy(printer_name, lp_servicename(snum)); - /* * Check to see if someone else is doing this update. * This is essentially a mutex on the update. @@ -528,7 +746,7 @@ static void print_queue_update(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. @@ -540,7 +758,7 @@ static void print_queue_update(int snum) /* * Someone else is doing the update, exit. */ - tdb_unlock_bystring(tdb, keystr); + tdb_unlock_bystring(pdb->tdb, keystr); return; } @@ -556,7 +774,7 @@ static void print_queue_update(int snum) * the update. */ - tdb_unlock_bystring(tdb, keystr); + tdb_unlock_bystring(pdb->tdb, keystr); /* * Update the cache time FIRST ! Stops others even @@ -565,7 +783,7 @@ static void print_queue_update(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); @@ -586,9 +804,9 @@ static void print_queue_update(int snum) fill in any system job numbers as we go */ for (i=0; itdb, traverse_fn_delete, (void *)&tstruct); SAFE_FREE(tstruct.queue); - tdb_store_int32(tdb, "INFO/total_jobs", tstruct.total_jobs); + tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs); 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 )); + DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n", + old_status.qcount, qcount, printer_name )); /* store the new queue status structure */ slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name); @@ -634,7 +853,7 @@ static void print_queue_update(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 @@ -642,7 +861,7 @@ static void print_queue_update(int snum) */ slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name); - tdb_store_int32(tdb, keystr, (int32)time(NULL)); + tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL)); /* Delete our pid from the db. */ set_updating_pid(printer_name, True); @@ -652,9 +871,12 @@ 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(int jobid) +BOOL print_job_exists(uint32 jobid) { - return tdb_exists(tdb, print_key(jobid)); + struct tdb_print_db *pdb = get_print_db_byjobid(jobid); + if (!pdb) + return False; + return tdb_exists(pdb->tdb, print_key(jobid)); } /**************************************************************************** @@ -663,7 +885,7 @@ BOOL print_job_exists(int jobid) 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) @@ -676,7 +898,7 @@ int print_job_snum(int 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) @@ -693,7 +915,7 @@ int print_job_fd(int jobid) 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) @@ -705,7 +927,7 @@ char *print_job_fname(int jobid) 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; @@ -715,7 +937,7 @@ BOOL print_job_set_place(int jobid, int place) 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) @@ -729,7 +951,7 @@ BOOL print_job_set_name(int jobid, char *name) 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; @@ -746,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; } @@ -754,7 +976,7 @@ 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. */ @@ -778,7 +1000,7 @@ static BOOL print_job_delete1(int jobid) 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; @@ -797,7 +1019,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, WERROR *errcode) +BOOL print_job_delete(struct current_user *user, uint32 jobid, WERROR *errcode) { int snum = print_job_snum(jobid); BOOL owner; @@ -834,7 +1056,7 @@ BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode) 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; @@ -847,7 +1069,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode) snum = print_job_snum(jobid); if (snum == -1) { - DEBUG(5,("print_job_pause: 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; } @@ -882,7 +1104,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode) 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); int snum, ret; @@ -895,7 +1117,7 @@ BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode) snum = print_job_snum(jobid); if (snum == -1) { - DEBUG(5,("print_job_resume: unknown service number for jobid %d\n", jobid)); + DEBUG(5,("print_job_resume: unknown service number for jobid %u\n", (unsigned int)jobid)); return False; } @@ -927,7 +1149,7 @@ BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode) 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); @@ -954,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. @@ -971,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; } @@ -986,12 +1213,16 @@ 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)); @@ -1023,47 +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. ***************************************************************************/ -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); @@ -1075,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 */ @@ -1091,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 */ @@ -1121,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 || !pjob_store(jobid, &pjob)) { + 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) { @@ -1163,7 +1415,7 @@ to open spool file %s.\n", pjob.filename)); 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 @@ -1182,7 +1434,7 @@ to open spool file %s.\n", pjob.filename)); 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; @@ -1192,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) @@ -1211,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; @@ -1225,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; } @@ -1245,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) { @@ -1291,7 +1543,8 @@ static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void * { 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; @@ -1333,14 +1586,14 @@ static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, { 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; 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; @@ -1383,22 +1636,27 @@ 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); + + *queue = NULL; + + if (!pdb) + return 0; /* make sure the database is up to date */ if (print_cache_expired(snum)) print_queue_update(snum); - *queue = NULL; - /* * 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)); @@ -1413,7 +1671,7 @@ 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; @@ -1432,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. */ @@ -1448,7 +1706,7 @@ int print_queue_status(int 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)) -- cgit From 496e85dd812b932caf5e6169e03df6b31a378966 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 11 Jul 2002 01:54:26 +0000 Subject: intermediate work on DeletePrinterDriverEx(). This call will actually delete driver files ( not yet though I don't think). Just wanted to get it in since Jeremy and I are both working on nt_printing.c (This used to be commit 3fa6c3132950c9ff1c6a532d8264ee34a6b2b0ff) --- source3/printing/nt_printing.c | 217 +++++++++++++++++++++++++++-------------- 1 file changed, 146 insertions(+), 71 deletions(-) (limited to 'source3/printing') diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 2abe27b95d..fe90625e78 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -1683,13 +1683,13 @@ static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver) /**************************************************************************** ****************************************************************************/ -static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch) +static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring driver, fstring arch) { NT_PRINTER_DRIVER_INFO_LEVEL_3 info; ZERO_STRUCT(info); - fstrcpy(info.name, in_prt); + fstrcpy(info.name, driver); fstrcpy(info.defaultdatatype, "RAW"); fstrcpy(info.driverpath, ""); @@ -1710,7 +1710,7 @@ static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **in /**************************************************************************** ****************************************************************************/ -static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version) +static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring drivername, fstring arch, uint32 version) { NT_PRINTER_DRIVER_INFO_LEVEL_3 driver; TDB_DATA kbuf, dbuf; @@ -1721,21 +1721,19 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, ZERO_STRUCT(driver); - get_short_archi(architecture, in_arch); + get_short_archi(architecture, arch); - DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt)); + DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, drivername)); - slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt); + slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, drivername); kbuf.dptr = key; kbuf.dsize = strlen(key)+1; dbuf = tdb_fetch(tdb_drivers, kbuf); -#if 0 - if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch); -#else - if (!dbuf.dptr) return WERR_ACCESS_DENIED; -#endif + if (!dbuf.dptr) + return WERR_ACCESS_DENIED; + len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff", &driver.cversion, driver.name, @@ -1771,7 +1769,7 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, if (len != dbuf.dsize) { SAFE_FREE(driver.dependentfiles); - return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch); + return get_a_printer_driver_3_default(info_ptr, drivername, arch); } *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver)); @@ -3335,17 +3333,31 @@ uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level) /**************************************************************************** ****************************************************************************/ WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, - fstring printername, fstring architecture, uint32 version) + fstring drivername, fstring architecture, uint32 version) { WERROR result; switch (level) { case 3: - { - result=get_a_printer_driver_3(&driver->info_3, printername, architecture, version); + /* Sometime we just want any version of the driver */ + + if ( version == DRIVER_ANY_VERSION ) { + /* look for Win2k first and then for NT4 */ + result = get_a_printer_driver_3(&driver->info_3, drivername, + architecture, 3); + + if ( !W_ERROR_IS_OK(result) ) { + result = get_a_printer_driver_3( &driver->info_3, + drivername, architecture, 2 ); + } + } + else { + result = get_a_printer_driver_3(&driver->info_3, drivername, + architecture, version); + } break; - } + default: result=W_ERROR(1); break; @@ -3353,6 +3365,7 @@ WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, if (W_ERROR_IS_OK(result)) dump_a_printer_driver(*driver, level); + return result; } @@ -3411,91 +3424,144 @@ uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level) Determine whether or not a particular driver is currently assigned to a printer ****************************************************************************/ -BOOL printer_driver_in_use (char *arch, char *driver) + +BOOL printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i ) { - TDB_DATA kbuf, newkey, dbuf; - NT_PRINTER_INFO_LEVEL_2 info; - int ret; + int snum; + int n_services = lp_numservices(); + NT_PRINTER_INFO_LEVEL *printer = NULL; - if (!tdb_printers) - if (!nt_printing_init()) - return False; + if ( !i ) + return False; - DEBUG(5,("printer_driver_in_use: Beginning search through printers.tdb...\n")); + DEBUG(5,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n")); /* loop through the printers.tdb and check for the drivername */ - for (kbuf = tdb_firstkey(tdb_printers); kbuf.dptr; - newkey = tdb_nextkey(tdb_printers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) + + for (snum=0; snumname, printer->info_2->drivername) ) { + free_a_printer( &printer, 2 ); + return True; + } + + free_a_printer( &printer, 2 ); + } + + DEBUG(5,("printer_driver_in_use: Completed search through ntprinters.tdb...\n")); + + /* report that the driver is not in use by default */ + + return False; +} - ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddddddfffffPfffff", - &info.attributes, - &info.priority, - &info.default_priority, - &info.starttime, - &info.untiltime, - &info.status, - &info.cjobs, - &info.averageppm, - &info.changeid, - &info.c_setprinter, - &info.setuptime, - info.servername, - info.printername, - info.sharename, - info.portname, - info.drivername, - info.comment, - info.location, - info.sepfile, - info.printprocessor, - info.datatype, - info.parameters); +/********************************************************************** + Check if any of the files used by src are also used by drv + *********************************************************************/ - SAFE_FREE(dbuf.dptr); +static BOOL check_driver_file_overlap( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src, + NT_PRINTER_DRIVER_INFO_LEVEL_3 *drv ) +{ + - if (ret == -1) { - DEBUG (0,("printer_driver_in_use: tdb_unpack failed for printer %s\n", - info.printername)); - continue; - } + return False; +} + +/**************************************************************************** + Determine whether or not a particular driver files are currently being + used by any other driver. Requires using the full path from [print$] +****************************************************************************/ + +BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) +{ + int i; + int ndrivers; + uint32 version; + fstring *list = NULL; + NT_PRINTER_DRIVER_INFO_LEVEL driver; + + /* loop over all driver versions */ + + DEBUG(5,("printer_driver_files_in_use: Beginning search through ntdrivers.tdb...\n")); + + for ( version=0; versionenvironment, version); + + DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", + ndrivers, info->environment, version)); + + if(ndrivers == -1) + continue; - if (strcmp(info.drivername, driver) == 0) + /* check each driver for overlap in files */ + + for (i=0; ienvironment, version)) ) + { + SAFE_FREE(list); + return True; + } + + /* check if d2 uses any files from d1 */ + + if ( check_driver_file_overlap(info, driver.info_3) ) { + free_a_printer_driver(driver, 3); + SAFE_FREE( list ); + return True; + } + + free_a_printer_driver(driver, 3); } + + SAFE_FREE(list); } - DEBUG(5,("printer_driver_in_use: Completed search through printers.tdb...\n")); - + DEBUG(5,("printer_driver_files_in_use: Completed search through ntdrivers.tdb...\n")); - /* report that the driver is in use by default */ return False; } +/**************************************************************************** + Actually delete the driver files. Make sure that + printer_driver_files_in_use() return False before calling + this. +****************************************************************************/ + +static NTSTATUS delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i ) +{ + + + return NT_STATUS_OK; +} + /**************************************************************************** Remove a printer driver from the TDB. This assumes that the the driver was previously looked up. ***************************************************************************/ -WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i) +WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, BOOL delete_files) { pstring key; fstring arch; TDB_DATA kbuf; - + /* delete the tdb data first */ + get_short_archi(arch, i->environment); slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, arch, i->cversion, i->name); @@ -3512,6 +3578,15 @@ WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i) DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n", i->name)); + /* + * now delete any associated files if delete_files == True + * even if this part failes, we return succes because the + * driver doesn not exist any more + */ + + if ( delete_files ) + delete_driver_files( i ); + return WERR_OK; } /**************************************************************************** -- cgit From 0aadcff8ec1caa7e8a8cc9c5738bc8d57be7b24f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 11 Jul 2002 03:27:12 +0000 Subject: all that is left to do is to actually perform the file deletion now. I have the file list. One more commit should do it. (This used to be commit 7207662504f585352b0ceeb99f8998ef58db7f15) --- source3/printing/nt_printing.c | 170 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 155 insertions(+), 15 deletions(-) (limited to 'source3/printing') diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index fe90625e78..17a16b84bc 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -3461,21 +3461,130 @@ BOOL printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i ) return False; } + +/********************************************************************** + Check to see if a ogiven file is in use by *info + *********************************************************************/ + +static BOOL drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) +{ + char *s; + + if ( !info ) + return False; + + if ( strequal(file, info->driverpath) ) + return True; + + if ( strequal(file, info->datafile) ) + return True; + + if ( strequal(file, info->configfile) ) + return True; + + if ( strequal(file, info->helpfile) ) + return True; + + s = (char*) info->dependentfiles; + + if ( s ) { + while ( *s ) + { + if ( strequal(file, s) ) + return True; + s += strlen(s) + 1; + } + } + + return False; + +} + +/********************************************************************** + Utility function to remove the dependent file pointed to by the + input parameter from the list + *********************************************************************/ + +static void trim_dependent_file( char* s ) +{ + char *p; + + /* set p to the next character string in the list */ + + p = s + strlen( s ) + 1; + + /* check to see that we have another string to copy back */ + + if ( *p == '\0' ) + { + /* loop over s copying characters from p to s */ + while ( *p!='\0' && *(p+1)!='\0' ) + *s++ = *p++; + } + + /* add the two trailing NULL's */ + + *s = '\0'; + *(s+1) = '\0'; +} + /********************************************************************** Check if any of the files used by src are also used by drv *********************************************************************/ -static BOOL check_driver_file_overlap( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src, +static BOOL trim_overlap_drv_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src, NT_PRINTER_DRIVER_INFO_LEVEL_3 *drv ) { + BOOL in_use = False; + char *s; - - return False; + if ( !src || !drv ) + return False; + + /* check each file. Remove it from the src structure if it overlaps */ + + if ( drv_file_in_use(src->driverpath, drv) ) { + in_use = True; + fstrcpy( src->driverpath, "" ); + } + + if ( drv_file_in_use(src->datafile, drv) ) { + in_use = True; + fstrcpy( src->datafile, "" ); + } + + if ( drv_file_in_use(src->configfile, drv) ) { + in_use = True; + fstrcpy( src->configfile, "" ); + } + + s = (char*)src->dependentfiles; + + if ( s ) { + while ( *s ) + { + if ( drv_file_in_use(s, drv) ) { + in_use = True; + trim_dependent_file( s ); + } + else + s += strlen(s) + 1; + } + } + + + return in_use; } /**************************************************************************** Determine whether or not a particular driver files are currently being - used by any other driver. Requires using the full path from [print$] + used by any other driver. + + Return value is True if any files were in use by other drivers + and False otherwise. + + Upon return, *info has been modified to only contain the driver files + which are not in use ****************************************************************************/ BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) @@ -3500,7 +3609,7 @@ BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, info->environment, version)); - if(ndrivers == -1) + if (ndrivers == -1) continue; /* check each driver for overlap in files */ @@ -3512,18 +3621,23 @@ BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) ZERO_STRUCT(driver); if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, list[i], - info->environment, version)) ) + info->environment, version)) ) { SAFE_FREE(list); return True; } /* check if d2 uses any files from d1 */ + /* only if this is a different driver than the one being deleted */ - if ( check_driver_file_overlap(info, driver.info_3) ) { - free_a_printer_driver(driver, 3); - SAFE_FREE( list ); - return True; + if ( !strequal(info->name, driver.info_3->name) + || (info->cversion != driver.info_3->cversion) ) + { + if ( trim_overlap_drv_files(info, driver.info_3) ) { + free_a_printer_driver(driver, 3); + SAFE_FREE( list ); + return True; + } } free_a_printer_driver(driver, 3); @@ -3545,7 +3659,31 @@ BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) static NTSTATUS delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i ) { - + char *s; + + if ( !i ) + return NT_STATUS_ACCESS_DENIED; + + DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n", i->name, i->cversion)); + + + if ( *i->driverpath ) + DEBUG(10,("deleting [%s]\n", i->driverpath)); + if ( *i->configfile ) + DEBUG(10,("deleting [%s]\n", i->configfile)); + if ( *i->datafile ) + DEBUG(10,("deleting [%s]\n", i->datafile)); + if ( *i->helpfile ) + DEBUG(10,("deleting [%s]\n", i->helpfile)); + + s = (char*)i->dependentfiles; + + if ( s ) { + while ( *s ) { + DEBUG(10,("deleting dependent file [%s]\n", s)); + s += strlen( s ) + 1; + } + } return NT_STATUS_OK; } @@ -3565,7 +3703,9 @@ WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, BOOL delete_fil get_short_archi(arch, i->environment); slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, arch, i->cversion, i->name); - DEBUG(5,("delete_printer_driver: key = [%s]\n", key)); + + DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n", + key, delete_files ? "TRUE" : "FALSE" )); kbuf.dptr=key; kbuf.dsize=strlen(key)+1; @@ -3575,9 +3715,6 @@ WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, BOOL delete_fil return WERR_ACCESS_DENIED; } - DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n", - i->name)); - /* * now delete any associated files if delete_files == True * even if this part failes, we return succes because the @@ -3587,6 +3724,9 @@ WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, BOOL delete_fil if ( delete_files ) delete_driver_files( i ); + DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n", + i->name)); + return WERR_OK; } /**************************************************************************** -- cgit From 137570cb037f75131241c3ae13a372803d21fbe1 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 11 Jul 2002 04:53:39 +0000 Subject: last check in for tonight. * DeletePrinterDriverEx() now has the ability to delete driver files. I need to do some more testing tro veriofy that we are in fact not deleting a file out from under another driver, but it looks ok so far. * DeletePrinterDriver() noiw deletes all versions of the specified driver (cversion == 0, 1, 2, 3) (This used to be commit 17bb780e1327663fa2fcd6a3cb25dd461a29c537) --- source3/printing/nt_printing.c | 168 +++++++++++++++++++++++++++++++---------- 1 file changed, 128 insertions(+), 40 deletions(-) (limited to 'source3/printing') diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 17a16b84bc..8e65f1d76a 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -1859,19 +1859,19 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 else { info3=driver.info_3; - DEBUGADD(106,("version:[%d]\n", info3->cversion)); - DEBUGADD(106,("name:[%s]\n", info3->name)); - DEBUGADD(106,("environment:[%s]\n", info3->environment)); - DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath)); - DEBUGADD(106,("datafile:[%s]\n", info3->datafile)); - DEBUGADD(106,("configfile:[%s]\n", info3->configfile)); - DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile)); - DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname)); - DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype)); + DEBUGADD(20,("version:[%d]\n", info3->cversion)); + DEBUGADD(20,("name:[%s]\n", info3->name)); + DEBUGADD(20,("environment:[%s]\n", info3->environment)); + DEBUGADD(20,("driverpath:[%s]\n", info3->driverpath)); + DEBUGADD(20,("datafile:[%s]\n", info3->datafile)); + DEBUGADD(20,("configfile:[%s]\n", info3->configfile)); + DEBUGADD(20,("helpfile:[%s]\n", info3->helpfile)); + DEBUGADD(20,("monitorname:[%s]\n", info3->monitorname)); + DEBUGADD(20,("defaultdatatype:[%s]\n", info3->defaultdatatype)); for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) { - DEBUGADD(106,("dependentfile:[%s]\n", + DEBUGADD(20,("dependentfile:[%s]\n", info3->dependentfiles[i])); } result=0; @@ -1879,7 +1879,7 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 break; } default: - DEBUGADD(106,("dump_a_printer_driver: Level %u not implemented\n", (unsigned int)level)); + DEBUGADD(20,("dump_a_printer_driver: Level %u not implemented\n", (unsigned int)level)); result=1; break; } @@ -3657,56 +3657,115 @@ BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) this. ****************************************************************************/ -static NTSTATUS delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i ) +static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, struct current_user *user ) { char *s; + connection_struct *conn; + DATA_BLOB null_pw; + NTSTATUS nt_status; if ( !i ) - return NT_STATUS_ACCESS_DENIED; + return False; DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n", i->name, i->cversion)); + /* + * Connect to the print$ share under the same account as the + * user connected to the rpc pipe. Note we must be root to + * do this. + */ + + become_root(); + null_pw = data_blob( NULL, 0 ); + conn = make_connection_with_chdir( "print$", null_pw, "A:", user->vuid, &nt_status ); + unbecome_root(); - if ( *i->driverpath ) - DEBUG(10,("deleting [%s]\n", i->driverpath)); - if ( *i->configfile ) - DEBUG(10,("deleting [%s]\n", i->configfile)); - if ( *i->datafile ) - DEBUG(10,("deleting [%s]\n", i->datafile)); - if ( *i->helpfile ) - DEBUG(10,("deleting [%s]\n", i->helpfile)); + if ( !conn ) { + DEBUG(0,("delete_driver_files: Unable to connect\n")); + return False; + } + + /* Save who we are - we are temporarily becoming the connection user. */ + + if ( !become_user(conn, conn->vuid) ) { + DEBUG(0,("delete_driver_files: Can't become user!\n")); + return False; + } + + /* now delete the files; must strip the '\print$' string from + fron of path */ + + if ( *i->driverpath ) { + if ( (s = strchr( &i->driverpath[1], '\\' )) != NULL ) { + DEBUG(10,("deleting driverfile [%s]\n", s)); + unlink_internals(conn, 0, s); + } + } + + if ( *i->configfile ) { + if ( (s = strchr( &i->configfile[1], '\\' )) != NULL ) { + DEBUG(10,("deleting configfile [%s]\n", s)); + unlink_internals(conn, 0, s); + } + } + + if ( *i->datafile ) { + if ( (s = strchr( &i->datafile[1], '\\' )) != NULL ) { + DEBUG(10,("deleting datafile [%s]\n", s)); + unlink_internals(conn, 0, s); + } + } + + if ( *i->helpfile ) { + if ( (s = strchr( &i->helpfile[1], '\\' )) != NULL ) { + DEBUG(10,("deleting helpfile [%s]\n", s)); + unlink_internals(conn, 0, s); + } + } s = (char*)i->dependentfiles; - if ( s ) { - while ( *s ) { - DEBUG(10,("deleting dependent file [%s]\n", s)); - s += strlen( s ) + 1; + while ( s && *s ) { + char *file; + + if ( (file = strchr( s+1, '\\' )) != NULL ) + { + DEBUG(10,("deleting dependent file [%s]\n", file)); + unlink_internals(conn, 0, file ); + file += strlen( file ) + 1; } + + s = file; } - return NT_STATUS_OK; + return True; } /**************************************************************************** Remove a printer driver from the TDB. This assumes that the the driver was previously looked up. ***************************************************************************/ -WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, BOOL delete_files) + +static WERROR delete_printer_driver_internal( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, struct current_user *user, + uint32 version, BOOL delete_files ) { pstring key; fstring arch; TDB_DATA kbuf; + NT_PRINTER_DRIVER_INFO_LEVEL ctr; /* delete the tdb data first */ - + get_short_archi(arch, i->environment); slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, - arch, i->cversion, i->name); - - DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n", + arch, version, i->name); + + DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n", key, delete_files ? "TRUE" : "FALSE" )); + ctr.info_3 = i; + dump_a_printer_driver( ctr, 3 ); + kbuf.dptr=key; kbuf.dsize=strlen(key)+1; @@ -3714,27 +3773,56 @@ WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, BOOL delete_fil DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key)); return WERR_ACCESS_DENIED; } - - /* + + /* * now delete any associated files if delete_files == True - * even if this part failes, we return succes because the - * driver doesn not exist any more + * even if this part failes, we return succes because the + * driver doesn not exist any more */ - + if ( delete_files ) - delete_driver_files( i ); - + delete_driver_files( i, user ); + DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n", i->name)); - + + return WERR_OK; +} + +/**************************************************************************** + Remove a printer driver from the TDB. This assumes that the the driver was + previously looked up. + ***************************************************************************/ + +WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, struct current_user *user, + uint32 version, BOOL delete_files ) +{ + int ver; + WERROR err; + + /* see if we should delete all versions of this driver */ + + if ( version == DRIVER_ANY_VERSION ) { + for ( ver=0; ver Date: Thu, 11 Jul 2002 13:17:57 +0000 Subject: added copyright (This used to be commit dcb6d70706a0e86881588c3828ff5bd4d63d415f) --- source3/printing/nt_printing.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/printing') diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 8e65f1d76a..ff08b99eb0 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -3,6 +3,7 @@ * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-2000, * Copyright (C) Jean François Micouleau 1998-2000. + * Copyright (C) Gerald Carter 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 -- cgit