2 Unix SMB/Netbios implementation.
4 printing backend routines
5 Copyright (C) Andrew Tridgell 1992-2000
6 Copyright (C) Jeremy Allison 2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "librpc/gen_ndr/messaging.h"
26 extern struct current_user current_user;
27 extern userdom_struct current_user_info;
29 /* Current printer interface */
30 static bool remove_from_jobs_changed(const char* sharename, uint32 jobid);
33 the printing backend revolves around a tdb database that stores the
34 SMB view of the print queue
36 The key for this database is a jobid - a internally generated number that
37 uniquely identifies a print job
39 reading the print queue involves two steps:
40 - possibly running lpq and updating the internal database from that
41 - reading entries from the database
43 jobids are assigned when a job starts spooling.
46 static TDB_CONTEXT *rap_tdb;
47 static uint16 next_rap_jobid;
48 struct rap_jobid_key {
53 /***************************************************************************
54 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
55 bit RPC jobids.... JRA.
56 ***************************************************************************/
58 uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
62 struct rap_jobid_key jinfo;
65 DEBUG(10,("pjobid_to_rap: called.\n"));
68 /* Create the in-memory tdb. */
69 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
75 fstrcpy( jinfo.sharename, sharename );
77 key.dptr = (uint8 *)&jinfo;
78 key.dsize = sizeof(jinfo);
80 data = tdb_fetch(rap_tdb, key);
81 if (data.dptr && data.dsize == sizeof(uint16)) {
82 rap_jobid = SVAL(data.dptr, 0);
84 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
85 (unsigned int)jobid, (unsigned int)rap_jobid));
89 /* Not found - create and store mapping. */
90 rap_jobid = ++next_rap_jobid;
92 rap_jobid = ++next_rap_jobid;
93 SSVAL(buf,0,rap_jobid);
95 data.dsize = sizeof(rap_jobid);
96 tdb_store(rap_tdb, key, data, TDB_REPLACE);
97 tdb_store(rap_tdb, data, key, TDB_REPLACE);
99 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
100 (unsigned int)jobid, (unsigned int)rap_jobid));
104 bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
109 DEBUG(10,("rap_to_pjobid called.\n"));
114 SSVAL(buf,0,rap_jobid);
116 key.dsize = sizeof(rap_jobid);
117 data = tdb_fetch(rap_tdb, key);
118 if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
120 struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
121 if (sharename != NULL) {
122 fstrcpy( sharename, jinfo->sharename );
124 *pjobid = jinfo->jobid;
125 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
126 (unsigned int)*pjobid, (unsigned int)rap_jobid));
127 SAFE_FREE(data.dptr);
131 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
132 (unsigned int)rap_jobid));
133 SAFE_FREE(data.dptr);
137 void rap_jobid_delete(const char* sharename, uint32 jobid)
141 struct rap_jobid_key jinfo;
144 DEBUG(10,("rap_jobid_delete: called.\n"));
149 ZERO_STRUCT( jinfo );
150 fstrcpy( jinfo.sharename, sharename );
152 key.dptr = (uint8 *)&jinfo;
153 key.dsize = sizeof(jinfo);
155 data = tdb_fetch(rap_tdb, key);
156 if (!data.dptr || (data.dsize != sizeof(uint16))) {
157 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
158 (unsigned int)jobid ));
159 SAFE_FREE(data.dptr);
163 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
164 (unsigned int)jobid ));
166 rap_jobid = SVAL(data.dptr, 0);
167 SAFE_FREE(data.dptr);
168 SSVAL(buf,0,rap_jobid);
170 data.dsize = sizeof(rap_jobid);
171 tdb_delete(rap_tdb, key);
172 tdb_delete(rap_tdb, data);
175 static int get_queue_status(const char* sharename, print_status_struct *);
177 /****************************************************************************
178 Initialise the printing backend. Called once at startup before the fork().
179 ****************************************************************************/
181 bool print_backend_init(struct messaging_context *msg_ctx)
183 const char *sversion = "INFO/version";
184 int services = lp_numservices();
187 unlink(cache_path("printing.tdb"));
188 mkdir(cache_path("printing"),0755);
190 /* handle a Samba upgrade */
192 for (snum = 0; snum < services; snum++) {
193 struct tdb_print_db *pdb;
194 if (!lp_print_ok(snum))
197 pdb = get_print_db_byname(lp_const_servicename(snum));
200 if (tdb_lock_bystring(pdb->tdb, sversion) == -1) {
201 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
202 release_print_db(pdb);
205 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
206 tdb_wipe_all(pdb->tdb);
207 tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
209 tdb_unlock_bystring(pdb->tdb, sversion);
210 release_print_db(pdb);
213 close_all_print_db(); /* Don't leave any open. */
215 /* do NT print initialization... */
216 return nt_printing_init(msg_ctx);
219 /****************************************************************************
220 Shut down printing backend. Called once at shutdown to close the tdb.
221 ****************************************************************************/
223 void printing_end(void)
225 close_all_print_db(); /* Don't leave any open. */
228 /****************************************************************************
229 Retrieve the set of printing functions for a given service. This allows
230 us to set the printer function table based on the value of the 'printing'
233 Use the generic interface as the default and only use cups interface only
234 when asked for (and only when supported)
235 ****************************************************************************/
237 static struct printif *get_printer_fns_from_type( enum printing_types type )
239 struct printif *printer_fns = &generic_printif;
242 if ( type == PRINT_CUPS ) {
243 printer_fns = &cups_printif;
245 #endif /* HAVE_CUPS */
248 if ( type == PRINT_IPRINT ) {
249 printer_fns = &iprint_printif;
251 #endif /* HAVE_IPRINT */
253 printer_fns->type = type;
258 static struct printif *get_printer_fns( int snum )
260 return get_printer_fns_from_type( (enum printing_types)lp_printing(snum) );
264 /****************************************************************************
265 Useful function to generate a tdb key.
266 ****************************************************************************/
268 static TDB_DATA print_key(uint32 jobid, uint32 *tmp)
272 SIVAL(tmp, 0, jobid);
273 ret.dptr = (uint8 *)tmp;
274 ret.dsize = sizeof(*tmp);
278 /****************************************************************************
279 Pack the devicemode to store it in a tdb.
280 ****************************************************************************/
281 static int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen)
283 enum ndr_err_code ndr_err;
288 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(),
290 (ndr_push_flags_fn_t)
291 ndr_push_spoolss_DeviceMode);
292 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
293 DEBUG(10, ("pack_devicemode: "
294 "error encoding spoolss_DeviceMode\n"));
301 len = tdb_pack(buf, buflen, "B", blob.length, blob.data);
304 DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname));
311 /****************************************************************************
312 Unpack the devicemode to store it in a tdb.
313 ****************************************************************************/
314 static int unpack_devicemode(TALLOC_CTX *mem_ctx,
315 const uint8 *buf, int buflen,
316 struct spoolss_DeviceMode **devmode)
318 struct spoolss_DeviceMode *dm;
319 enum ndr_err_code ndr_err;
327 len = tdb_unpack(buf, buflen, "B", &data_len, &data);
332 dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
337 blob = data_blob_const(data, data_len);
339 ndr_err = ndr_pull_struct_blob(&blob, dm, dm,
340 (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
341 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
342 DEBUG(10, ("unpack_devicemode: "
343 "error parsing spoolss_DeviceMode\n"));
347 DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
348 dm->devicename, dm->formname));
349 if (dm->driverextra_data.data) {
350 DEBUG(8, ("with a private section of %d bytes\n",
351 dm->__driverextra_length));
361 /***********************************************************************
362 unpack a pjob from a tdb buffer
363 ***********************************************************************/
365 int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )
369 uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
370 uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
375 len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
393 used = unpack_devicemode(NULL, buf+len, buflen-len, &pjob->devmode);
401 pjob->sysjob = pjsysjob;
403 pjob->starttime = pjstarttime;
404 pjob->status = pjstatus;
406 pjob->page_count = pjpage_count;
407 pjob->spooled = pjspooled;
408 pjob->smbjob = pjsmbjob;
414 /****************************************************************************
415 Useful function to find a print job in the database.
416 ****************************************************************************/
418 static struct printjob *print_job_find(const char *sharename, uint32 jobid)
420 static struct printjob pjob;
423 struct tdb_print_db *pdb = get_print_db_byname(sharename);
425 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
426 (unsigned int)jobid, sharename ));
432 ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
433 release_print_db(pdb);
436 DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid ));
440 talloc_free(pjob.devmode);
444 if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
445 DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid ));
452 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
453 (int)pjob.sysjob, (unsigned int)jobid ));
458 /* Convert a unix jobid to a smb jobid */
460 struct unixjob_traverse_state {
462 uint32 sysjob_to_jobid_value;
465 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
466 TDB_DATA data, void *private_data)
468 struct printjob *pjob;
469 struct unixjob_traverse_state *state =
470 (struct unixjob_traverse_state *)private_data;
472 if (!data.dptr || data.dsize == 0)
475 pjob = (struct printjob *)data.dptr;
476 if (key.dsize != sizeof(uint32))
479 if (state->sysjob == pjob->sysjob) {
480 uint32 jobid = IVAL(key.dptr,0);
482 state->sysjob_to_jobid_value = jobid;
489 /****************************************************************************
490 This is a *horribly expensive call as we have to iterate through all the
491 current printer tdb's. Don't do this often ! JRA.
492 ****************************************************************************/
494 uint32 sysjob_to_jobid(int unix_jobid)
496 int services = lp_numservices();
498 struct unixjob_traverse_state state;
500 state.sysjob = unix_jobid;
501 state.sysjob_to_jobid_value = (uint32)-1;
503 for (snum = 0; snum < services; snum++) {
504 struct tdb_print_db *pdb;
505 if (!lp_print_ok(snum))
507 pdb = get_print_db_byname(lp_const_servicename(snum));
511 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state);
512 release_print_db(pdb);
513 if (state.sysjob_to_jobid_value != (uint32)-1)
514 return state.sysjob_to_jobid_value;
519 /****************************************************************************
520 Send notifications based on what has changed after a pjob_store.
521 ****************************************************************************/
523 static const struct {
525 uint32 spoolss_status;
526 } lpq_to_spoolss_status_map[] = {
527 { LPQ_QUEUED, JOB_STATUS_QUEUED },
528 { LPQ_PAUSED, JOB_STATUS_PAUSED },
529 { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
530 { LPQ_PRINTING, JOB_STATUS_PRINTING },
531 { LPQ_DELETING, JOB_STATUS_DELETING },
532 { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
533 { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
534 { LPQ_PRINTED, JOB_STATUS_PRINTED },
535 { LPQ_DELETED, JOB_STATUS_DELETED },
536 { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ },
537 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
541 /* Convert a lpq status value stored in printing.tdb into the
542 appropriate win32 API constant. */
544 static uint32 map_to_spoolss_status(uint32 lpq_status)
548 while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
549 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
550 return lpq_to_spoolss_status_map[i].spoolss_status;
557 static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data,
558 struct printjob *new_data)
560 bool new_job = False;
565 /* Job attributes that can't be changed. We only send
566 notification for these on a new job. */
568 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
569 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
570 time first or else we'll end up with potential alignment
571 errors. I don't think the systemtime should be spooled as
572 a string, but this gets us around that error.
573 --jerry (i'll feel dirty for this) */
576 notify_job_submitted(sharename, jobid, new_data->starttime);
577 notify_job_username(sharename, jobid, new_data->user);
580 if (new_job || !strequal(old_data->jobname, new_data->jobname))
581 notify_job_name(sharename, jobid, new_data->jobname);
583 /* Job attributes of a new job or attributes that can be
586 if (new_job || !strequal(old_data->jobname, new_data->jobname))
587 notify_job_name(sharename, jobid, new_data->jobname);
589 if (new_job || old_data->status != new_data->status)
590 notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status));
592 if (new_job || old_data->size != new_data->size)
593 notify_job_total_bytes(sharename, jobid, new_data->size);
595 if (new_job || old_data->page_count != new_data->page_count)
596 notify_job_total_pages(sharename, jobid, new_data->page_count);
599 /****************************************************************************
600 Store a job structure back to the database.
601 ****************************************************************************/
603 static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob)
606 TDB_DATA old_data, new_data;
608 struct tdb_print_db *pdb = get_print_db_byname(sharename);
610 int len, newlen, buflen;
618 old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
620 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
627 len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
629 (uint32)pjob->sysjob,
631 (uint32)pjob->starttime,
632 (uint32)pjob->status,
634 (uint32)pjob->page_count,
635 (uint32)pjob->spooled,
636 (uint32)pjob->smbjob,
642 len += pack_devicemode(pjob->devmode, buf+len, buflen-len);
645 buf = (uint8 *)SMB_REALLOC(buf, len);
647 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
652 } while ( buflen != len );
658 new_data.dsize = len;
659 ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data,
662 release_print_db(pdb);
664 /* Send notify updates for what has changed */
667 struct printjob old_pjob;
669 if ( old_data.dsize )
671 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
673 pjob_store_notify( sharename, jobid, &old_pjob , pjob );
674 talloc_free(old_pjob.devmode);
679 pjob_store_notify( sharename, jobid, NULL, pjob );
684 SAFE_FREE( old_data.dptr );
690 /****************************************************************************
691 Remove a job structure from the database.
692 ****************************************************************************/
694 void pjob_delete(const char* sharename, uint32 jobid)
697 struct printjob *pjob;
698 uint32 job_status = 0;
699 struct tdb_print_db *pdb;
701 pdb = get_print_db_byname( sharename );
706 pjob = print_job_find( sharename, jobid );
709 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
710 (unsigned int)jobid));
711 release_print_db(pdb);
715 /* We must cycle through JOB_STATUS_DELETING and
716 JOB_STATUS_DELETED for the port monitor to delete the job
719 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
720 notify_job_status(sharename, jobid, job_status);
722 /* Remove from printing.tdb */
724 tdb_delete(pdb->tdb, print_key(jobid, &tmp));
725 remove_from_jobs_changed(sharename, jobid);
726 release_print_db( pdb );
727 rap_jobid_delete(sharename, jobid);
730 /****************************************************************************
731 List a unix job in the print database.
732 ****************************************************************************/
734 static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid)
736 struct printjob pj, *old_pj;
738 if (jobid == (uint32)-1)
739 jobid = q->job + UNIX_JOB_START;
741 /* Preserve the timestamp on an existing unix print job */
743 old_pj = print_job_find(sharename, jobid);
750 pj.starttime = old_pj ? old_pj->starttime : q->time;
751 pj.status = q->status;
754 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
755 if (jobid < UNIX_JOB_START) {
757 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
760 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
762 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
763 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
765 pjob_store(sharename, jobid, &pj);
769 struct traverse_struct {
770 print_queue_struct *queue;
771 int qcount, snum, maxcount, total_jobs;
772 const char *sharename;
774 const char *lprm_command;
775 struct printif *print_if;
778 /****************************************************************************
779 Utility fn to delete any jobs that are no longer active.
780 ****************************************************************************/
782 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
784 struct traverse_struct *ts = (struct traverse_struct *)state;
785 struct printjob pjob;
789 if ( key.dsize != sizeof(jobid) )
792 jobid = IVAL(key.dptr, 0);
793 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
795 talloc_free(pjob.devmode);
799 /* remove a unix job if it isn't in the system queue any more */
801 for (i=0;i<ts->qcount;i++) {
802 uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
803 if (jobid == u_jobid)
806 if (i == ts->qcount) {
807 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
808 (unsigned int)jobid ));
809 pjob_delete(ts->sharename, jobid);
813 /* need to continue the the bottom of the function to
814 save the correct attributes */
817 /* maybe it hasn't been spooled yet */
819 /* if a job is not spooled and the process doesn't
820 exist then kill it. This cleans up after smbd
822 if (!process_exists_by_pid(pjob.pid)) {
823 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
824 (unsigned int)jobid, (unsigned int)pjob.pid ));
825 pjob_delete(ts->sharename, jobid);
831 /* this check only makes sense for jobs submitted from Windows clients */
834 for (i=0;i<ts->qcount;i++) {
837 if ( pjob.status == LPQ_DELETED )
840 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
842 if (jobid == curr_jobid) {
844 /* try to clean up any jobs that need to be deleted */
846 if ( pjob.status == LPQ_DELETING ) {
849 result = (*(ts->print_if->job_delete))(
850 ts->sharename, ts->lprm_command, &pjob );
853 /* if we can't delete, then reset the job status */
854 pjob.status = LPQ_QUEUED;
855 pjob_store(ts->sharename, jobid, &pjob);
858 /* if we deleted the job, the remove the tdb record */
859 pjob_delete(ts->sharename, jobid);
860 pjob.status = LPQ_DELETED;
870 /* The job isn't in the system queue - we have to assume it has
871 completed, so delete the database entry. */
873 if (i == ts->qcount) {
875 /* A race can occur between the time a job is spooled and
876 when it appears in the lpq output. This happens when
877 the job is added to printing.tdb when another smbd
878 running print_queue_update() has completed a lpq and
879 is currently traversing the printing tdb and deleting jobs.
880 Don't delete the job if it was submitted after the lpq_time. */
882 if (pjob.starttime < ts->lpq_time) {
883 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
885 (unsigned int)pjob.starttime,
886 (unsigned int)ts->lpq_time ));
887 pjob_delete(ts->sharename, jobid);
893 /* Save the pjob attributes we will store.
894 FIXME!!! This is the only place where queue->job
895 represents the SMB jobid --jerry */
897 ts->queue[i].job = jobid;
898 ts->queue[i].size = pjob.size;
899 ts->queue[i].page_count = pjob.page_count;
900 ts->queue[i].status = pjob.status;
901 ts->queue[i].priority = 1;
902 ts->queue[i].time = pjob.starttime;
903 fstrcpy(ts->queue[i].fs_user, pjob.user);
904 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
911 /****************************************************************************
912 Check if the print queue has been updated recently enough.
913 ****************************************************************************/
915 static void print_cache_flush(const char *sharename)
918 struct tdb_print_db *pdb = get_print_db_byname(sharename);
922 slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
923 tdb_store_int32(pdb->tdb, key, -1);
924 release_print_db(pdb);
927 /****************************************************************************
928 Check if someone already thinks they are doing the update.
929 ****************************************************************************/
931 static pid_t get_updating_pid(const char *sharename)
936 struct tdb_print_db *pdb = get_print_db_byname(sharename);
940 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
941 key = string_tdb_data(keystr);
943 data = tdb_fetch(pdb->tdb, key);
944 release_print_db(pdb);
945 if (!data.dptr || data.dsize != sizeof(pid_t)) {
946 SAFE_FREE(data.dptr);
950 updating_pid = IVAL(data.dptr, 0);
951 SAFE_FREE(data.dptr);
953 if (process_exists_by_pid(updating_pid))
959 /****************************************************************************
960 Set the fact that we're doing the update, or have finished doing the update
962 ****************************************************************************/
964 static void set_updating_pid(const fstring sharename, bool updating)
969 pid_t updating_pid = sys_getpid();
972 struct tdb_print_db *pdb = get_print_db_byname(sharename);
977 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
978 key = string_tdb_data(keystr);
980 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
981 updating ? "" : "not ",
985 tdb_delete(pdb->tdb, key);
986 release_print_db(pdb);
990 SIVAL( buffer, 0, updating_pid);
992 data.dsize = 4; /* we always assume this is a 4 byte value */
994 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
995 release_print_db(pdb);
998 /****************************************************************************
999 Sort print jobs by submittal time.
1000 ****************************************************************************/
1002 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1013 /* Sort on job start time */
1015 if (j1->time == j2->time)
1017 return (j1->time > j2->time) ? 1 : -1;
1020 /****************************************************************************
1021 Store the sorted queue representation for later portmon retrieval.
1023 ****************************************************************************/
1025 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
1028 int max_reported_jobs = lp_max_reported_jobs(pts->snum);
1029 print_queue_struct *queue = pts->queue;
1032 unsigned int qcount;
1034 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
1035 pts->qcount = max_reported_jobs;
1038 /* Work out the size. */
1040 data.dsize += tdb_pack(NULL, 0, "d", qcount);
1042 for (i = 0; i < pts->qcount; i++) {
1043 if ( queue[i].status == LPQ_DELETED )
1047 data.dsize += tdb_pack(NULL, 0, "ddddddff",
1048 (uint32)queue[i].job,
1049 (uint32)queue[i].size,
1050 (uint32)queue[i].page_count,
1051 (uint32)queue[i].status,
1052 (uint32)queue[i].priority,
1053 (uint32)queue[i].time,
1058 if ((data.dptr = (uint8 *)SMB_MALLOC(data.dsize)) == NULL)
1062 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
1063 for (i = 0; i < pts->qcount; i++) {
1064 if ( queue[i].status == LPQ_DELETED )
1067 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
1068 (uint32)queue[i].job,
1069 (uint32)queue[i].size,
1070 (uint32)queue[i].page_count,
1071 (uint32)queue[i].status,
1072 (uint32)queue[i].priority,
1073 (uint32)queue[i].time,
1078 tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
1080 SAFE_FREE(data.dptr);
1084 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
1090 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
1091 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
1092 SAFE_FREE(data.dptr);
1099 static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
1102 unsigned int job_count = data.dsize / 4;
1104 for (i = 0; i < job_count; i++) {
1107 ch_jobid = IVAL(data.dptr, i*4);
1108 if (ch_jobid == jobid)
1109 remove_from_jobs_changed(sharename, jobid);
1113 /****************************************************************************
1114 Check if the print queue has been updated recently enough.
1115 ****************************************************************************/
1117 static bool print_cache_expired(const char *sharename, bool check_pending)
1120 time_t last_qscan_time, time_now = time(NULL);
1121 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1122 bool result = False;
1127 snprintf(key, sizeof(key), "CACHE/%s", sharename);
1128 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1131 * Invalidate the queue for 3 reasons.
1132 * (1). last queue scan time == -1.
1133 * (2). Current time - last queue scan time > allowed cache time.
1134 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1135 * This last test picks up machines for which the clock has been moved
1136 * forward, an lpq scan done and then the clock moved back. Otherwise
1137 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1140 if (last_qscan_time == ((time_t)-1)
1141 || (time_now - last_qscan_time) >= lp_lpqcachetime()
1142 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
1145 time_t msg_pending_time;
1147 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1148 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1149 sharename, (int)last_qscan_time, (int)time_now,
1150 (int)lp_lpqcachetime() ));
1152 /* check if another smbd has already sent a message to update the
1153 queue. Give the pending message one minute to clear and
1154 then send another message anyways. Make sure to check for
1155 clocks that have been run forward and then back again. */
1157 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1160 && tdb_fetch_uint32( pdb->tdb, key, &u )
1161 && (msg_pending_time=u) > 0
1162 && msg_pending_time <= time_now
1163 && (time_now - msg_pending_time) < 60 )
1165 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1174 release_print_db(pdb);
1178 /****************************************************************************
1179 main work for updating the lpq cahe for a printer queue
1180 ****************************************************************************/
1182 static void print_queue_update_internal( const char *sharename,
1183 struct printif *current_printif,
1184 char *lpq_command, char *lprm_command )
1187 print_queue_struct *queue = NULL;
1188 print_status_struct status;
1189 print_status_struct old_status;
1190 struct printjob *pjob;
1191 struct traverse_struct tstruct;
1194 fstring keystr, cachestr;
1195 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1201 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1202 sharename, current_printif->type, lpq_command));
1205 * Update the cache time FIRST ! Stops others even
1206 * attempting to get the lock and doing this
1207 * if the lpq takes a long time.
1210 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1211 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1213 /* get the current queue using the appropriate interface */
1214 ZERO_STRUCT(status);
1216 qcount = (*(current_printif->queue_get))(sharename,
1217 current_printif->type,
1218 lpq_command, &queue, &status);
1220 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1221 qcount, (qcount != 1) ? "s" : "", sharename));
1223 /* Sort the queue by submission time otherwise they are displayed
1226 TYPESAFE_QSORT(queue, qcount, printjob_comp);
1229 any job in the internal database that is marked as spooled
1230 and doesn't exist in the system queue is considered finished
1231 and removed from the database
1233 any job in the system database but not in the internal database
1234 is added as a unix job
1236 fill in any system job numbers as we go
1239 jcdata = get_jobs_changed_data(pdb);
1241 for (i=0; i<qcount; i++) {
1242 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1244 if (jobid == (uint32)-1) {
1245 /* assume its a unix print job */
1246 print_unix_job(sharename, &queue[i], jobid);
1250 /* we have an active SMB print job - update its status */
1251 pjob = print_job_find(sharename, jobid);
1253 /* err, somethings wrong. Probably smbd was restarted
1254 with jobs in the queue. All we can do is treat them
1255 like unix jobs. Pity. */
1256 print_unix_job(sharename, &queue[i], jobid);
1260 pjob->sysjob = queue[i].job;
1262 /* don't reset the status on jobs to be deleted */
1264 if ( pjob->status != LPQ_DELETING )
1265 pjob->status = queue[i].status;
1267 pjob_store(sharename, jobid, pjob);
1269 check_job_changed(sharename, jcdata, jobid);
1272 SAFE_FREE(jcdata.dptr);
1274 /* now delete any queued entries that don't appear in the
1276 tstruct.queue = queue;
1277 tstruct.qcount = qcount;
1279 tstruct.total_jobs = 0;
1280 tstruct.lpq_time = time(NULL);
1281 tstruct.sharename = sharename;
1282 tstruct.lprm_command = lprm_command;
1283 tstruct.print_if = current_printif;
1285 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1287 /* Store the linearised queue, max jobs only. */
1288 store_queue_struct(pdb, &tstruct);
1290 SAFE_FREE(tstruct.queue);
1292 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1293 sharename, tstruct.total_jobs ));
1295 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1297 get_queue_status(sharename, &old_status);
1298 if (old_status.qcount != qcount)
1299 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1300 old_status.qcount, qcount, sharename));
1302 /* store the new queue status structure */
1303 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1304 key = string_tdb_data(keystr);
1306 status.qcount = qcount;
1307 data.dptr = (uint8 *)&status;
1308 data.dsize = sizeof(status);
1309 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1312 * Update the cache time again. We want to do this call
1313 * as little as possible...
1316 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1317 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1319 /* clear the msg pending record for this queue */
1321 snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1323 if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1324 /* log a message but continue on */
1326 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1330 release_print_db( pdb );
1335 /****************************************************************************
1336 Update the internal database from the system print queue for a queue.
1337 obtain a lock on the print queue before proceeding (needed when mutiple
1338 smbd processes maytry to update the lpq cache concurrently).
1339 ****************************************************************************/
1341 static void print_queue_update_with_lock( const char *sharename,
1342 struct printif *current_printif,
1343 char *lpq_command, char *lprm_command )
1346 struct tdb_print_db *pdb;
1348 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1349 pdb = get_print_db_byname(sharename);
1353 if ( !print_cache_expired(sharename, False) ) {
1354 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1355 release_print_db(pdb);
1360 * Check to see if someone else is doing this update.
1361 * This is essentially a mutex on the update.
1364 if (get_updating_pid(sharename) != -1) {
1365 release_print_db(pdb);
1369 /* Lock the queue for the database update */
1371 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1372 /* Only wait 10 seconds for this. */
1373 if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
1374 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1375 release_print_db(pdb);
1380 * Ensure that no one else got in here.
1381 * If the updating pid is still -1 then we are
1385 if (get_updating_pid(sharename) != -1) {
1387 * Someone else is doing the update, exit.
1389 tdb_unlock_bystring(pdb->tdb, keystr);
1390 release_print_db(pdb);
1395 * We're going to do the update ourselves.
1398 /* Tell others we're doing the update. */
1399 set_updating_pid(sharename, True);
1402 * Allow others to enter and notice we're doing
1406 tdb_unlock_bystring(pdb->tdb, keystr);
1408 /* do the main work now */
1410 print_queue_update_internal( sharename, current_printif,
1411 lpq_command, lprm_command );
1413 /* Delete our pid from the db. */
1414 set_updating_pid(sharename, False);
1415 release_print_db(pdb);
1418 /****************************************************************************
1419 this is the receive function of the background lpq updater
1420 ****************************************************************************/
1421 static void print_queue_receive(struct messaging_context *msg,
1424 struct server_id server_id,
1428 char *lpqcommand = NULL, *lprmcommand = NULL;
1432 len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP",
1439 SAFE_FREE(lpqcommand);
1440 SAFE_FREE(lprmcommand);
1441 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1445 print_queue_update_with_lock(sharename,
1446 get_printer_fns_from_type((enum printing_types)printing_type),
1447 lpqcommand, lprmcommand );
1449 SAFE_FREE(lpqcommand);
1450 SAFE_FREE(lprmcommand);
1454 static void printing_pause_fd_handler(struct tevent_context *ev,
1455 struct tevent_fd *fde,
1460 * If pause_pipe[1] is closed it means the parent smbd
1461 * and children exited or aborted.
1463 exit_server_cleanly(NULL);
1466 extern struct child_pid *children;
1467 extern int num_children;
1469 static void add_child_pid(pid_t pid)
1471 struct child_pid *child;
1473 child = SMB_MALLOC_P(struct child_pid);
1474 if (child == NULL) {
1475 DEBUG(0, ("Could not add child struct -- malloc failed\n"));
1479 DLIST_ADD(children, child);
1483 static pid_t background_lpq_updater_pid = -1;
1485 /****************************************************************************
1486 main thread of the background lpq updater
1487 ****************************************************************************/
1488 void start_background_queue(void)
1490 /* Use local variables for this as we don't
1491 * need to save the parent side of this, just
1492 * ensure it closes when the process exits.
1496 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1498 if (pipe(pause_pipe) == -1) {
1499 DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno) ));
1503 background_lpq_updater_pid = sys_fork();
1505 if (background_lpq_updater_pid == -1) {
1506 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1510 /* Track the printing pid along with other smbd children */
1511 add_child_pid(background_lpq_updater_pid);
1513 if(background_lpq_updater_pid == 0) {
1514 struct tevent_fd *fde;
1519 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1521 close(pause_pipe[0]);
1524 status = reinit_after_fork(server_messaging_context(),
1525 server_event_context(),
1526 procid_self(), true);
1528 if (!NT_STATUS_IS_OK(status)) {
1529 DEBUG(0,("reinit_after_fork() failed\n"));
1530 smb_panic("reinit_after_fork() failed");
1533 smbd_setup_sig_term_handler();
1534 smbd_setup_sig_hup_handler();
1536 if (!serverid_register(procid_self(),
1537 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
1538 |FLAG_MSG_PRINT_GENERAL)) {
1542 if (!locking_init()) {
1546 messaging_register(server_messaging_context(), NULL,
1547 MSG_PRINTER_UPDATE, print_queue_receive);
1549 fde = tevent_add_fd(server_event_context(),
1550 server_event_context(),
1551 pause_pipe[1], TEVENT_FD_READ,
1552 printing_pause_fd_handler,
1555 DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
1556 smb_panic("tevent_add_fd() failed for pause_pipe");
1559 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1560 ret = tevent_loop_wait(server_event_context());
1561 /* should not be reached */
1562 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
1563 ret, (ret == 0) ? "out of events" : strerror(errno)));
1567 close(pause_pipe[1]);
1570 /****************************************************************************
1571 update the internal database from the system print queue for a queue
1572 ****************************************************************************/
1574 static void print_queue_update(int snum, bool force)
1578 char *lpqcommand = NULL;
1579 char *lprmcommand = NULL;
1580 uint8 *buffer = NULL;
1583 struct tdb_print_db *pdb;
1585 struct printif *current_printif;
1586 TALLOC_CTX *ctx = talloc_tos();
1588 fstrcpy( sharename, lp_const_servicename(snum));
1590 /* don't strip out characters like '$' from the printername */
1592 lpqcommand = talloc_string_sub2(ctx,
1593 lp_lpqcommand(snum),
1595 lp_printername(snum),
1596 false, false, false);
1600 lpqcommand = talloc_sub_advanced(ctx,
1601 lp_servicename(snum),
1602 current_user_info.unix_name,
1604 current_user.ut.gid,
1605 get_current_username(),
1606 current_user_info.domain,
1612 lprmcommand = talloc_string_sub2(ctx,
1613 lp_lprmcommand(snum),
1615 lp_printername(snum),
1616 false, false, false);
1620 lprmcommand = talloc_sub_advanced(ctx,
1621 lp_servicename(snum),
1622 current_user_info.unix_name,
1624 current_user.ut.gid,
1625 get_current_username(),
1626 current_user_info.domain,
1633 * Make sure that the background queue process exists.
1634 * Otherwise just do the update ourselves
1637 if ( force || background_lpq_updater_pid == -1 ) {
1638 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1639 current_printif = get_printer_fns( snum );
1640 print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand );
1645 type = lp_printing(snum);
1647 /* get the length */
1649 len = tdb_pack( NULL, 0, "fdPP",
1655 buffer = SMB_XMALLOC_ARRAY( uint8, len );
1657 /* now pack the buffer */
1658 newlen = tdb_pack( buffer, len, "fdPP",
1664 SMB_ASSERT( newlen == len );
1666 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1667 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1668 sharename, type, lpqcommand, lprmcommand ));
1670 /* here we set a msg pending record for other smbd processes
1671 to throttle the number of duplicate print_queue_update msgs
1674 pdb = get_print_db_byname(sharename);
1680 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1682 if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1683 /* log a message but continue on */
1685 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1689 release_print_db( pdb );
1691 /* finally send the message */
1693 messaging_send_buf(server_messaging_context(),
1694 pid_to_procid(background_lpq_updater_pid),
1695 MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
1697 SAFE_FREE( buffer );
1702 /****************************************************************************
1703 Create/Update an entry in the print tdb that will allow us to send notify
1704 updates only to interested smbd's.
1705 ****************************************************************************/
1707 bool print_notify_register_pid(int snum)
1710 struct tdb_print_db *pdb = NULL;
1711 TDB_CONTEXT *tdb = NULL;
1712 const char *printername;
1713 uint32 mypid = (uint32)sys_getpid();
1717 /* if (snum == -1), then the change notify request was
1718 on a print server handle and we need to register on
1723 int num_services = lp_numservices();
1726 for ( idx=0; idx<num_services; idx++ ) {
1727 if (lp_snum_ok(idx) && lp_print_ok(idx) )
1728 print_notify_register_pid(idx);
1733 else /* register for a specific printer */
1735 printername = lp_const_servicename(snum);
1736 pdb = get_print_db_byname(printername);
1742 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1743 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1746 release_print_db(pdb);
1750 data = get_printer_notify_pid_list( tdb, printername, True );
1752 /* Add ourselves and increase the refcount. */
1754 for (i = 0; i < data.dsize; i += 8) {
1755 if (IVAL(data.dptr,i) == mypid) {
1756 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1757 SIVAL(data.dptr, i+4, new_refcount);
1762 if (i == data.dsize) {
1763 /* We weren't in the list. Realloc. */
1764 data.dptr = (uint8 *)SMB_REALLOC(data.dptr, data.dsize + 8);
1766 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1771 SIVAL(data.dptr,data.dsize - 8,mypid);
1772 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1775 /* Store back the record. */
1776 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1777 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1778 list for printer %s\n", printername));
1786 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1788 release_print_db(pdb);
1789 SAFE_FREE(data.dptr);
1793 /****************************************************************************
1794 Update an entry in the print tdb that will allow us to send notify
1795 updates only to interested smbd's.
1796 ****************************************************************************/
1798 bool print_notify_deregister_pid(int snum)
1801 struct tdb_print_db *pdb = NULL;
1802 TDB_CONTEXT *tdb = NULL;
1803 const char *printername;
1804 uint32 mypid = (uint32)sys_getpid();
1808 /* if ( snum == -1 ), we are deregister a print server handle
1809 which means to deregister on all print queues */
1813 int num_services = lp_numservices();
1816 for ( idx=0; idx<num_services; idx++ ) {
1817 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1818 print_notify_deregister_pid(idx);
1823 else /* deregister a specific printer */
1825 printername = lp_const_servicename(snum);
1826 pdb = get_print_db_byname(printername);
1832 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1833 DEBUG(0,("print_notify_register_pid: Failed to lock \
1834 printer %s database\n", printername));
1836 release_print_db(pdb);
1840 data = get_printer_notify_pid_list( tdb, printername, True );
1842 /* Reduce refcount. Remove ourselves if zero. */
1844 for (i = 0; i < data.dsize; ) {
1845 if (IVAL(data.dptr,i) == mypid) {
1846 uint32 refcount = IVAL(data.dptr, i+4);
1850 if (refcount == 0) {
1851 if (data.dsize - i > 8)
1852 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1856 SIVAL(data.dptr, i+4, refcount);
1862 if (data.dsize == 0)
1863 SAFE_FREE(data.dptr);
1865 /* Store back the record. */
1866 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1867 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1868 list for printer %s\n", printername));
1876 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1878 release_print_db(pdb);
1879 SAFE_FREE(data.dptr);
1883 /****************************************************************************
1884 Check if a jobid is valid. It is valid if it exists in the database.
1885 ****************************************************************************/
1887 bool print_job_exists(const char* sharename, uint32 jobid)
1889 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1895 ret = tdb_exists(pdb->tdb, print_key(jobid, &tmp));
1896 release_print_db(pdb);
1900 /****************************************************************************
1901 Give the filename used for a jobid.
1902 Only valid for the process doing the spooling and when the job
1903 has not been spooled.
1904 ****************************************************************************/
1906 char *print_job_fname(const char* sharename, uint32 jobid)
1908 struct printjob *pjob = print_job_find(sharename, jobid);
1909 if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
1911 return pjob->filename;
1915 /****************************************************************************
1916 Give the filename used for a jobid.
1917 Only valid for the process doing the spooling and when the job
1918 has not been spooled.
1919 ****************************************************************************/
1921 struct spoolss_DeviceMode *print_job_devmode(const char* sharename, uint32 jobid)
1923 struct printjob *pjob = print_job_find(sharename, jobid);
1928 return pjob->devmode;
1931 /****************************************************************************
1932 Set the name of a job. Only possible for owner.
1933 ****************************************************************************/
1935 bool print_job_set_name(const char *sharename, uint32 jobid, const char *name)
1937 struct printjob *pjob;
1939 pjob = print_job_find(sharename, jobid);
1940 if (!pjob || pjob->pid != sys_getpid())
1943 fstrcpy(pjob->jobname, name);
1944 return pjob_store(sharename, jobid, pjob);
1947 /****************************************************************************
1948 Get the name of a job. Only possible for owner.
1949 ****************************************************************************/
1951 bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name)
1953 struct printjob *pjob;
1955 pjob = print_job_find(sharename, jobid);
1956 if (!pjob || pjob->pid != sys_getpid()) {
1960 *name = talloc_strdup(mem_ctx, pjob->jobname);
1969 /***************************************************************************
1970 Remove a jobid from the 'jobs changed' list.
1971 ***************************************************************************/
1973 static bool remove_from_jobs_changed(const char* sharename, uint32 jobid)
1975 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1977 size_t job_count, i;
1979 bool gotlock = False;
1987 key = string_tdb_data("INFO/jobs_changed");
1989 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1994 data = tdb_fetch(pdb->tdb, key);
1996 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1999 job_count = data.dsize / 4;
2000 for (i = 0; i < job_count; i++) {
2003 ch_jobid = IVAL(data.dptr, i*4);
2004 if (ch_jobid == jobid) {
2005 if (i < job_count -1 )
2006 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
2008 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
2018 tdb_chainunlock(pdb->tdb, key);
2019 SAFE_FREE(data.dptr);
2020 release_print_db(pdb);
2022 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
2024 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
2028 /****************************************************************************
2029 Delete a print job - don't update queue.
2030 ****************************************************************************/
2032 static bool print_job_delete1(int snum, uint32 jobid)
2034 const char* sharename = lp_const_servicename(snum);
2035 struct printjob *pjob = print_job_find(sharename, jobid);
2037 struct printif *current_printif = get_printer_fns( snum );
2043 * If already deleting just return.
2046 if (pjob->status == LPQ_DELETING)
2049 /* Hrm - we need to be able to cope with deleting a job before it
2050 has reached the spooler. Just mark it as LPQ_DELETING and
2051 let the print_queue_update() code rmeove the record */
2054 if (pjob->sysjob == -1) {
2055 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
2058 /* Set the tdb entry to be deleting. */
2060 pjob->status = LPQ_DELETING;
2061 pjob_store(sharename, jobid, pjob);
2063 if (pjob->spooled && pjob->sysjob != -1)
2065 result = (*(current_printif->job_delete))(
2066 lp_printername(snum),
2067 lp_lprmcommand(snum),
2070 /* Delete the tdb entry if the delete succeeded or the job hasn't
2074 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2079 pjob_delete(sharename, jobid);
2080 /* Ensure we keep a rough count of the number of total jobs... */
2081 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
2082 release_print_db(pdb);
2086 remove_from_jobs_changed( sharename, jobid );
2088 return (result == 0);
2091 /****************************************************************************
2092 Return true if the current user owns the print job.
2093 ****************************************************************************/
2095 static bool is_owner(struct auth_serversupplied_info *server_info,
2096 const char *servicename,
2099 struct printjob *pjob = print_job_find(servicename, jobid);
2101 if (!pjob || !server_info)
2104 return strequal(pjob->user, server_info->sanitized_username);
2107 /****************************************************************************
2109 ****************************************************************************/
2111 WERROR print_job_delete(struct auth_serversupplied_info *server_info,
2112 int snum, uint32_t jobid)
2114 const char* sharename = lp_const_servicename(snum);
2115 struct printjob *pjob;
2119 owner = is_owner(server_info, lp_const_servicename(snum), jobid);
2121 /* Check access against security descriptor or whether the user
2125 !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
2126 DEBUG(3, ("delete denied by security descriptor\n"));
2128 /* BEGIN_ADMIN_LOG */
2129 sys_adminlog( LOG_ERR,
2130 "Permission denied-- user not allowed to delete, \
2131 pause, or resume print job. User name: %s. Printer name: %s.",
2132 uidtoname(server_info->utok.uid),
2133 lp_printername(snum) );
2136 return WERR_ACCESS_DENIED;
2140 * get the spooled filename of the print job
2141 * if this works, then the file has not been spooled
2142 * to the underlying print system. Just delete the
2143 * spool file & return.
2146 fname = print_job_fname(sharename, jobid);
2147 if (fname != NULL) {
2148 /* remove the spool file */
2149 DEBUG(10, ("print_job_delete: "
2150 "Removing spool file [%s]\n", fname));
2151 if (unlink(fname) == -1) {
2152 return map_werror_from_unix(errno);
2156 if (!print_job_delete1(snum, jobid)) {
2157 return WERR_ACCESS_DENIED;
2160 /* force update the database and say the delete failed if the
2163 print_queue_update(snum, True);
2165 pjob = print_job_find(sharename, jobid);
2166 if (pjob && (pjob->status != LPQ_DELETING)) {
2167 return WERR_ACCESS_DENIED;
2170 return WERR_PRINTER_HAS_JOBS_QUEUED;
2173 /****************************************************************************
2175 ****************************************************************************/
2177 bool print_job_pause(struct auth_serversupplied_info *server_info, int snum,
2178 uint32 jobid, WERROR *errcode)
2180 const char* sharename = lp_const_servicename(snum);
2181 struct printjob *pjob;
2183 struct printif *current_printif = get_printer_fns( snum );
2185 pjob = print_job_find(sharename, jobid);
2187 if (!pjob || !server_info) {
2188 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2189 (unsigned int)jobid ));
2193 if (!pjob->spooled || pjob->sysjob == -1) {
2194 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2195 (int)pjob->sysjob, (unsigned int)jobid ));
2199 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2200 !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
2201 DEBUG(3, ("pause denied by security descriptor\n"));
2203 /* BEGIN_ADMIN_LOG */
2204 sys_adminlog( LOG_ERR,
2205 "Permission denied-- user not allowed to delete, \
2206 pause, or resume print job. User name: %s. Printer name: %s.",
2207 uidtoname(server_info->utok.uid),
2208 lp_printername(snum) );
2211 *errcode = WERR_ACCESS_DENIED;
2215 /* need to pause the spooled entry */
2216 ret = (*(current_printif->job_pause))(snum, pjob);
2219 *errcode = WERR_INVALID_PARAM;
2223 /* force update the database */
2224 print_cache_flush(lp_const_servicename(snum));
2226 /* Send a printer notify message */
2228 notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);
2230 /* how do we tell if this succeeded? */
2235 /****************************************************************************
2237 ****************************************************************************/
2239 bool print_job_resume(struct auth_serversupplied_info *server_info, int snum,
2240 uint32 jobid, WERROR *errcode)
2242 const char *sharename = lp_const_servicename(snum);
2243 struct printjob *pjob;
2245 struct printif *current_printif = get_printer_fns( snum );
2247 pjob = print_job_find(sharename, jobid);
2249 if (!pjob || !server_info) {
2250 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2251 (unsigned int)jobid ));
2255 if (!pjob->spooled || pjob->sysjob == -1) {
2256 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2257 (int)pjob->sysjob, (unsigned int)jobid ));
2261 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2262 !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
2263 DEBUG(3, ("resume denied by security descriptor\n"));
2264 *errcode = WERR_ACCESS_DENIED;
2266 /* BEGIN_ADMIN_LOG */
2267 sys_adminlog( LOG_ERR,
2268 "Permission denied-- user not allowed to delete, \
2269 pause, or resume print job. User name: %s. Printer name: %s.",
2270 uidtoname(server_info->utok.uid),
2271 lp_printername(snum) );
2276 ret = (*(current_printif->job_resume))(snum, pjob);
2279 *errcode = WERR_INVALID_PARAM;
2283 /* force update the database */
2284 print_cache_flush(lp_const_servicename(snum));
2286 /* Send a printer notify message */
2288 notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);
2293 /****************************************************************************
2294 Write to a print file.
2295 ****************************************************************************/
2297 ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size)
2299 const char* sharename = lp_const_servicename(snum);
2300 ssize_t return_code;
2301 struct printjob *pjob;
2303 pjob = print_job_find(sharename, jobid);
2307 /* don't allow another process to get this info - it is meaningless */
2308 if (pjob->pid != sys_getpid())
2311 /* if SMBD is spooling this can't be allowed */
2312 if (pjob->status == PJOB_SMBD_SPOOLING) {
2316 return_code = write_data_at_offset(pjob->fd, buf, size, pos);
2318 if (return_code>0) {
2320 pjob_store(sharename, jobid, pjob);
2325 /****************************************************************************
2326 Get the queue status - do not update if db is out of date.
2327 ****************************************************************************/
2329 static int get_queue_status(const char* sharename, print_status_struct *status)
2333 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2337 ZERO_STRUCTP(status);
2344 fstr_sprintf(keystr, "STATUS/%s", sharename);
2345 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2347 if (data.dsize == sizeof(print_status_struct))
2348 /* this memcpy is ok since the status struct was
2349 not packed before storing it in the tdb */
2350 memcpy(status, data.dptr, sizeof(print_status_struct));
2351 SAFE_FREE(data.dptr);
2354 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2355 release_print_db(pdb);
2356 return (len == -1 ? 0 : len);
2359 /****************************************************************************
2360 Determine the number of jobs in a queue.
2361 ****************************************************************************/
2363 int print_queue_length(int snum, print_status_struct *pstatus)
2365 const char* sharename = lp_const_servicename( snum );
2366 print_status_struct status;
2369 ZERO_STRUCT( status );
2371 /* make sure the database is up to date */
2372 if (print_cache_expired(lp_const_servicename(snum), True))
2373 print_queue_update(snum, False);
2375 /* also fetch the queue status */
2376 memset(&status, 0, sizeof(status));
2377 len = get_queue_status(sharename, &status);
2385 /***************************************************************************
2386 Allocate a jobid. Hold the lock for as short a time as possible.
2387 ***************************************************************************/
2389 static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
2390 const char *sharename, uint32 *pjobid)
2394 enum TDB_ERROR terr;
2397 *pjobid = (uint32)-1;
2399 for (i = 0; i < 3; i++) {
2400 /* Lock the database - only wait 20 seconds. */
2401 ret = tdb_lock_bystring_with_timeout(pdb->tdb,
2402 "INFO/nextjob", 20);
2404 DEBUG(0, ("allocate_print_jobid: "
2405 "Failed to lock printing database %s\n",
2407 terr = tdb_error(pdb->tdb);
2408 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2411 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2412 terr = tdb_error(pdb->tdb);
2413 if (terr != TDB_ERR_NOEXIST) {
2414 DEBUG(0, ("allocate_print_jobid: "
2415 "Failed to fetch INFO/nextjob "
2416 "for print queue %s\n", sharename));
2417 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2418 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2420 DEBUG(10, ("allocate_print_jobid: "
2421 "No existing jobid in %s\n", sharename));
2425 DEBUG(10, ("allocate_print_jobid: "
2426 "Read jobid %u from %s\n", jobid, sharename));
2428 jobid = NEXT_JOBID(jobid);
2430 ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid);
2432 terr = tdb_error(pdb->tdb);
2433 DEBUG(3, ("allocate_print_jobid: "
2434 "Failed to store INFO/nextjob.\n"));
2435 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2436 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2439 /* We've finished with the INFO/nextjob lock. */
2440 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2442 if (!print_job_exists(sharename, jobid)) {
2445 DEBUG(10, ("allocate_print_jobid: "
2446 "Found jobid %u in %s\n", jobid, sharename));
2450 DEBUG(0, ("allocate_print_jobid: "
2451 "Failed to allocate a print job for queue %s\n",
2453 /* Probably full... */
2454 return WERR_NO_SPOOL_SPACE;
2457 /* Store a dummy placeholder. */
2463 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
2464 TDB_INSERT) == -1) {
2465 DEBUG(3, ("allocate_print_jobid: "
2466 "jobid (%d) failed to store placeholder.\n",
2468 terr = tdb_error(pdb->tdb);
2469 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2477 /***************************************************************************
2478 Append a jobid to the 'jobs changed' list.
2479 ***************************************************************************/
2481 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
2486 SIVAL(&store_jobid, 0, jobid);
2487 data.dptr = (uint8 *)&store_jobid;
2490 DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2492 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
2497 /***************************************************************************
2498 Do all checks needed to determine if we can start a job.
2499 ***************************************************************************/
2501 static WERROR print_job_checks(struct auth_serversupplied_info *server_info,
2502 int snum, int *njobs)
2504 const char *sharename = lp_const_servicename(snum);
2505 uint64_t dspace, dsize;
2509 if (!print_access_check(server_info, snum, PRINTER_ACCESS_USE)) {
2510 DEBUG(3, ("print_job_checks: "
2511 "job start denied by security descriptor\n"));
2512 return WERR_ACCESS_DENIED;
2515 if (!print_time_access_check(server_info, sharename)) {
2516 DEBUG(3, ("print_job_checks: "
2517 "job start denied by time check\n"));
2518 return WERR_ACCESS_DENIED;
2521 /* see if we have sufficient disk space */
2522 if (lp_minprintspace(snum)) {
2523 minspace = lp_minprintspace(snum);
2524 ret = sys_fsusage(lp_pathname(snum), &dspace, &dsize);
2525 if (ret == 0 && dspace < 2*minspace) {
2526 DEBUG(3, ("print_job_checks: "
2527 "disk space check failed.\n"));
2528 return WERR_NO_SPOOL_SPACE;
2532 /* for autoloaded printers, check that the printcap entry still exists */
2533 if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) {
2534 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2536 return WERR_ACCESS_DENIED;
2539 /* Insure the maximum queue size is not violated */
2540 *njobs = print_queue_length(snum, NULL);
2541 if (*njobs > lp_maxprintjobs(snum)) {
2542 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2543 "larger than max printjobs per queue (%d).\n",
2544 sharename, *njobs, lp_maxprintjobs(snum)));
2545 return WERR_NO_SPOOL_SPACE;
2551 /***************************************************************************
2553 ***************************************************************************/
2555 static WERROR print_job_spool_file(int snum, uint32_t jobid,
2556 const char *output_file,
2557 struct printjob *pjob)
2564 /* if this file is within the printer path, it means that smbd
2565 * is spooling it and will pass us control when it is finished.
2566 * Verify that the file name is ok, within path, and it is
2567 * already already there */
2569 path = lp_pathname(snum);
2571 if (strncmp(output_file, path, len) == 0 &&
2572 (output_file[len - 1] == '/' || output_file[len] == '/')) {
2574 /* verify path is not too long */
2575 if (strlen(output_file) >= sizeof(pjob->filename)) {
2576 return WERR_INVALID_NAME;
2579 /* verify that the file exists */
2580 if (sys_stat(output_file, &st, false) != 0) {
2581 return WERR_INVALID_NAME;
2584 fstrcpy(pjob->filename, output_file);
2586 DEBUG(3, ("print_job_spool_file:"
2587 "External spooling activated"));
2589 /* we do not open the file until spooling is done */
2591 pjob->status = PJOB_SMBD_SPOOLING;
2597 slprintf(pjob->filename, sizeof(pjob->filename)-1,
2598 "%s/%s%.8u.XXXXXX", lp_pathname(snum),
2599 PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2600 pjob->fd = mkstemp(pjob->filename);
2602 if (pjob->fd == -1) {
2603 werr = map_werror_from_unix(errno);
2604 if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) {
2605 /* Common setup error, force a report. */
2606 DEBUG(0, ("print_job_spool_file: "
2607 "insufficient permissions to open spool "
2608 "file %s.\n", pjob->filename));
2610 /* Normal case, report at level 3 and above. */
2611 DEBUG(3, ("print_job_spool_file: "
2612 "can't open spool file %s\n",
2621 /***************************************************************************
2622 Start spooling a job - return the jobid.
2623 ***************************************************************************/
2625 WERROR print_job_start(struct auth_serversupplied_info *server_info,
2626 int snum, const char *docname, const char *filename,
2627 struct spoolss_DeviceMode *devmode, uint32_t *_jobid)
2631 struct printjob pjob;
2632 const char *sharename = lp_const_servicename(snum);
2633 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2638 return WERR_INTERNAL_DB_CORRUPTION;
2641 path = lp_pathname(snum);
2643 werr = print_job_checks(server_info, snum, &njobs);
2644 if (!W_ERROR_IS_OK(werr)) {
2645 release_print_db(pdb);
2649 DEBUG(10, ("print_job_start: "
2650 "Queue %s number of jobs (%d), max printjobs = %d\n",
2651 sharename, njobs, lp_maxprintjobs(snum)));
2653 werr = allocate_print_jobid(pdb, snum, sharename, &jobid);
2654 if (!W_ERROR_IS_OK(werr)) {
2658 /* create the database entry */
2662 pjob.pid = sys_getpid();
2665 pjob.starttime = time(NULL);
2666 pjob.status = LPQ_SPOOLING;
2668 pjob.spooled = False;
2670 pjob.devmode = devmode;
2672 fstrcpy(pjob.jobname, docname);
2674 fstrcpy(pjob.user, lp_printjob_username(snum));
2675 standard_sub_advanced(sharename, server_info->sanitized_username,
2676 path, server_info->utok.gid,
2677 server_info->sanitized_username,
2678 server_info->info3->base.domain.string,
2679 pjob.user, sizeof(pjob.user)-1);
2680 /* ensure NULL termination */
2681 pjob.user[sizeof(pjob.user)-1] = '\0';
2683 fstrcpy(pjob.queuename, lp_const_servicename(snum));
2685 /* we have a job entry - now create the spool file */
2686 werr = print_job_spool_file(snum, jobid, filename, &pjob);
2687 if (!W_ERROR_IS_OK(werr)) {
2691 pjob_store(sharename, jobid, &pjob);
2693 /* Update the 'jobs changed' entry used by print_queue_status. */
2694 add_to_jobs_changed(pdb, jobid);
2696 /* Ensure we keep a rough count of the number of total jobs... */
2697 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2699 release_print_db(pdb);
2706 pjob_delete(sharename, jobid);
2709 release_print_db(pdb);
2711 DEBUG(3, ("print_job_start: returning fail. "
2712 "Error = %s\n", win_errstr(werr)));
2716 /****************************************************************************
2717 Update the number of pages spooled to jobid
2718 ****************************************************************************/
2720 void print_job_endpage(int snum, uint32 jobid)
2722 const char* sharename = lp_const_servicename(snum);
2723 struct printjob *pjob;
2725 pjob = print_job_find(sharename, jobid);
2728 /* don't allow another process to get this info - it is meaningless */
2729 if (pjob->pid != sys_getpid())
2733 pjob_store(sharename, jobid, pjob);
2736 /****************************************************************************
2737 Print a file - called on closing the file. This spools the job.
2738 If normal close is false then we're tearing down the jobs - treat as an
2740 ****************************************************************************/
2742 NTSTATUS print_job_end(int snum, uint32 jobid, enum file_close_type close_type)
2744 const char* sharename = lp_const_servicename(snum);
2745 struct printjob *pjob;
2747 SMB_STRUCT_STAT sbuf;
2748 struct printif *current_printif = get_printer_fns( snum );
2749 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2751 pjob = print_job_find(sharename, jobid);
2754 return NT_STATUS_PRINT_CANCELLED;
2757 if (pjob->spooled || pjob->pid != sys_getpid()) {
2758 return NT_STATUS_ACCESS_DENIED;
2761 if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) {
2762 if (pjob->status == PJOB_SMBD_SPOOLING) {
2763 /* take over the file now, smbd is done */
2764 if (sys_stat(pjob->filename, &sbuf, false) != 0) {
2765 status = map_nt_error_from_unix(errno);
2766 DEBUG(3, ("print_job_end: "
2767 "stat file failed for jobid %d\n",
2772 pjob->status = LPQ_SPOOLING;
2776 if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) {
2777 status = map_nt_error_from_unix(errno);
2779 DEBUG(3, ("print_job_end: "
2780 "stat file failed for jobid %d\n",
2788 pjob->size = sbuf.st_ex_size;
2792 * Not a normal close, something has gone wrong. Cleanup.
2794 if (pjob->fd != -1) {
2800 /* Technically, this is not quite right. If the printer has a separator
2801 * page turned on, the NT spooler prints the separator page even if the
2802 * print job is 0 bytes. 010215 JRR */
2803 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2804 /* don't bother spooling empty files or something being deleted. */
2805 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2806 pjob->filename, pjob->size ? "deleted" : "zero length" ));
2807 unlink(pjob->filename);
2808 pjob_delete(sharename, jobid);
2809 return NT_STATUS_OK;
2812 ret = (*(current_printif->job_submit))(snum, pjob);
2815 status = NT_STATUS_PRINT_CANCELLED;
2819 /* The print job has been successfully handed over to the back-end */
2821 pjob->spooled = True;
2822 pjob->status = LPQ_QUEUED;
2823 pjob_store(sharename, jobid, pjob);
2825 /* make sure the database is up to date */
2826 if (print_cache_expired(lp_const_servicename(snum), True))
2827 print_queue_update(snum, False);
2829 return NT_STATUS_OK;
2833 /* The print job was not successfully started. Cleanup */
2834 /* Still need to add proper error return propagation! 010122:JRR */
2836 unlink(pjob->filename);
2837 pjob_delete(sharename, jobid);
2841 /****************************************************************************
2842 Get a snapshot of jobs in the system without traversing.
2843 ****************************************************************************/
2845 static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2847 TDB_DATA data, cgdata;
2848 print_queue_struct *queue = NULL;
2850 uint32 extra_count = 0;
2851 int total_count = 0;
2854 int max_reported_jobs = lp_max_reported_jobs(snum);
2856 const char* sharename = lp_servicename(snum);
2858 /* make sure the database is up to date */
2859 if (print_cache_expired(lp_const_servicename(snum), True))
2860 print_queue_update(snum, False);
2866 ZERO_STRUCT(cgdata);
2868 /* Get the stored queue data. */
2869 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
2871 if (data.dptr && data.dsize >= sizeof(qcount))
2872 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2874 /* Get the changed jobs list. */
2875 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
2876 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2877 extra_count = cgdata.dsize/4;
2879 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2881 /* Allocate the queue size. */
2882 if (qcount == 0 && extra_count == 0)
2885 if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
2888 /* Retrieve the linearised queue data. */
2890 for( i = 0; i < qcount; i++) {
2891 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2892 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2901 queue[i].job = qjob;
2902 queue[i].size = qsize;
2903 queue[i].page_count = qpage_count;
2904 queue[i].status = qstatus;
2905 queue[i].priority = qpriority;
2906 queue[i].time = qtime;
2909 total_count = qcount;
2911 /* Add in the changed jobids. */
2912 for( i = 0; i < extra_count; i++) {
2914 struct printjob *pjob;
2916 jobid = IVAL(cgdata.dptr, i*4);
2917 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2918 pjob = print_job_find(lp_const_servicename(snum), jobid);
2920 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2921 remove_from_jobs_changed(sharename, jobid);
2925 queue[total_count].job = jobid;
2926 queue[total_count].size = pjob->size;
2927 queue[total_count].page_count = pjob->page_count;
2928 queue[total_count].status = pjob->status;
2929 queue[total_count].priority = 1;
2930 queue[total_count].time = pjob->starttime;
2931 fstrcpy(queue[total_count].fs_user, pjob->user);
2932 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2936 /* Sort the queue by submission time otherwise they are displayed
2939 TYPESAFE_QSORT(queue, total_count, printjob_comp);
2941 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2943 if (max_reported_jobs && total_count > max_reported_jobs)
2944 total_count = max_reported_jobs;
2947 *pcount = total_count;
2953 SAFE_FREE(data.dptr);
2954 SAFE_FREE(cgdata.dptr);
2958 /****************************************************************************
2959 Get a printer queue listing.
2960 set queue = NULL and status = NULL if you just want to update the cache
2961 ****************************************************************************/
2963 int print_queue_status(int snum,
2964 print_queue_struct **ppqueue,
2965 print_status_struct *status)
2969 const char *sharename;
2970 struct tdb_print_db *pdb;
2973 /* make sure the database is up to date */
2975 if (print_cache_expired(lp_const_servicename(snum), True))
2976 print_queue_update(snum, False);
2978 /* return if we are done */
2979 if ( !ppqueue || !status )
2983 sharename = lp_const_servicename(snum);
2984 pdb = get_print_db_byname(sharename);
2990 * Fetch the queue status. We must do this first, as there may
2991 * be no jobs in the queue.
2994 ZERO_STRUCTP(status);
2995 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
2996 key = string_tdb_data(keystr);
2998 data = tdb_fetch(pdb->tdb, key);
3000 if (data.dsize == sizeof(*status)) {
3001 /* this memcpy is ok since the status struct was
3002 not packed before storing it in the tdb */
3003 memcpy(status, data.dptr, sizeof(*status));
3005 SAFE_FREE(data.dptr);
3009 * Now, fetch the print queue information. We first count the number
3010 * of entries, and then only retrieve the queue if necessary.
3013 if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
3014 release_print_db(pdb);
3018 release_print_db(pdb);
3022 /****************************************************************************
3024 ****************************************************************************/
3026 WERROR print_queue_pause(struct auth_serversupplied_info *server_info, int snum)
3029 struct printif *current_printif = get_printer_fns( snum );
3031 if (!print_access_check(server_info, snum,
3032 PRINTER_ACCESS_ADMINISTER)) {
3033 return WERR_ACCESS_DENIED;
3039 ret = (*(current_printif->queue_pause))(snum);
3044 return WERR_INVALID_PARAM;
3047 /* force update the database */
3048 print_cache_flush(lp_const_servicename(snum));
3050 /* Send a printer notify message */
3052 notify_printer_status(snum, PRINTER_STATUS_PAUSED);
3057 /****************************************************************************
3059 ****************************************************************************/
3061 WERROR print_queue_resume(struct auth_serversupplied_info *server_info, int snum)
3064 struct printif *current_printif = get_printer_fns( snum );
3066 if (!print_access_check(server_info, snum,
3067 PRINTER_ACCESS_ADMINISTER)) {
3068 return WERR_ACCESS_DENIED;
3073 ret = (*(current_printif->queue_resume))(snum);
3078 return WERR_INVALID_PARAM;
3081 /* make sure the database is up to date */
3082 if (print_cache_expired(lp_const_servicename(snum), True))
3083 print_queue_update(snum, True);
3085 /* Send a printer notify message */
3087 notify_printer_status(snum, PRINTER_STATUS_OK);
3092 /****************************************************************************
3093 Purge a queue - implemented by deleting all jobs that we can delete.
3094 ****************************************************************************/
3096 WERROR print_queue_purge(struct auth_serversupplied_info *server_info, int snum)
3098 print_queue_struct *queue;
3099 print_status_struct status;
3103 /* Force and update so the count is accurate (i.e. not a cached count) */
3104 print_queue_update(snum, True);
3106 can_job_admin = print_access_check(server_info, snum,
3107 JOB_ACCESS_ADMINISTER);
3108 njobs = print_queue_status(snum, &queue, &status);
3110 if ( can_job_admin )
3113 for (i=0;i<njobs;i++) {
3114 bool owner = is_owner(server_info, lp_const_servicename(snum),
3117 if (owner || can_job_admin) {
3118 print_job_delete1(snum, queue[i].job);
3122 if ( can_job_admin )
3125 /* update the cache */
3126 print_queue_update( snum, True );