2 Unix SMB/Netbios implementation.
4 printing backend routines
5 Copyright (C) Andrew Tridgell 1992-2000
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 extern int DEBUGLEVEL;
26 /* Current printer interface */
27 struct printif *current_printif = &generic_printif;
30 the printing backend revolves around a tdb database that stores the
31 SMB view of the print queue
33 The key for this database is a jobid - a internally generated number that
34 uniquely identifies a print job
36 reading the print queue involves two steps:
37 - possibly running lpq and updating the internal database from that
38 - reading entries from the database
40 jobids are assigned when a job starts spooling.
43 /* the open printing.tdb database */
44 static TDB_CONTEXT *tdb;
45 static pid_t local_pid;
47 static int get_queue_status(int, print_status_struct *);
49 /****************************************************************************
50 initialise the printing backend. Called once at startup.
51 Does not survive a fork
52 ****************************************************************************/
53 BOOL print_backend_init(void)
55 char *sversion = "INFO/version";
57 if (tdb && local_pid == sys_getpid()) return True;
58 tdb = tdb_open_log(lock_path("printing.tdb"), 0, USE_TDB_MMAP_FLAG, O_RDWR|O_CREAT, 0600);
60 DEBUG(0,("print_backend_init: Failed to open printing backend database. Error = [%s]\n",
64 local_pid = sys_getpid();
66 /* handle a Samba upgrade */
67 tdb_lock_bystring(tdb, sversion);
68 if (tdb_fetch_int(tdb, sversion) != PRINT_DATABASE_VERSION) {
69 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
70 tdb_store_int(tdb, sversion, PRINT_DATABASE_VERSION);
72 tdb_unlock_bystring(tdb, sversion);
74 /* select the appropriate printing interface... */
76 if (strcmp(lp_printcapname(), "cups") == 0)
77 current_printif = &cups_printif;
78 #endif /* HAVE_CUPS */
80 /* do NT print initialization... */
81 return nt_printing_init();
84 /****************************************************************************
85 useful function to generate a tdb key
86 ****************************************************************************/
87 static TDB_DATA print_key(int jobid)
93 ret.dptr = (void *)&j;
94 ret.dsize = sizeof(j);
98 /****************************************************************************
99 useful function to find a print job in the database
100 ****************************************************************************/
101 static struct printjob *print_job_find(int jobid)
103 static struct printjob pjob;
106 ret = tdb_fetch(tdb, print_key(jobid));
107 if (!ret.dptr || ret.dsize != sizeof(pjob)) return NULL;
109 memcpy(&pjob, ret.dptr, sizeof(pjob));
114 /****************************************************************************
115 store a job structure back to the database
116 ****************************************************************************/
117 static BOOL print_job_store(int jobid, struct printjob *pjob)
120 d.dptr = (void *)pjob;
121 d.dsize = sizeof(*pjob);
123 return (tdb_store(tdb, print_key(jobid), d, TDB_REPLACE) == 0);
126 /****************************************************************************
127 parse a file name from the system spooler to generate a jobid
128 ****************************************************************************/
129 static int print_parse_jobid(char *fname)
133 if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0) return -1;
134 fname += strlen(PRINT_SPOOL_PREFIX);
137 if (jobid <= 0) return -1;
143 /****************************************************************************
144 list a unix job in the print database
145 ****************************************************************************/
146 static void print_unix_job(int snum, print_queue_struct *q)
148 int jobid = q->job + UNIX_JOB_START;
149 struct printjob pj, *old_pj;
151 /* Preserve the timestamp on an existing unix print job */
153 old_pj = print_job_find(jobid);
160 pj.starttime = old_pj ? old_pj->starttime : q->time;
161 pj.status = q->status;
165 fstrcpy(pj.filename, "");
166 fstrcpy(pj.jobname, q->file);
167 fstrcpy(pj.user, q->user);
168 fstrcpy(pj.qname, lp_servicename(snum));
170 print_job_store(jobid, &pj);
174 struct traverse_struct {
175 print_queue_struct *queue;
176 int qcount, snum, maxcount, total_jobs;
179 /* utility fn to delete any jobs that are no longer active */
180 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
182 struct traverse_struct *ts = (struct traverse_struct *)state;
183 struct printjob pjob;
186 if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
187 memcpy(&jobid, key.dptr, sizeof(jobid));
188 memcpy(&pjob, data.dptr, sizeof(pjob));
190 if (strcmp(lp_servicename(ts->snum), pjob.qname)) {
191 /* this isn't for the queue we are looking at */
197 /* remove a unix job if it isn't in the system queue any more */
199 for (i=0;i<ts->qcount;i++) {
200 if (jobid == ts->queue[i].job + UNIX_JOB_START) break;
203 tdb_delete(tdb, key);
209 /* maybe it hasn't been spooled yet */
211 /* if a job is not spooled and the process doesn't
212 exist then kill it. This cleans up after smbd
214 if (!process_exists(pjob.pid))
215 tdb_delete(tdb, key);
221 for (i=0;i<ts->qcount;i++) {
222 int qid = print_parse_jobid(ts->queue[i].file);
223 if (jobid == qid) break;
226 /* The job isn't in the system queue - we have to assume it has
227 completed, so delete the database entry. */
229 if (i == ts->qcount) {
230 time_t cur_t = time(NULL);
232 /* A race can occur between the time a job is spooled and
233 when it appears in the lpq output. This happens when
234 the job is added to printing.tdb when another smbd
235 running print_queue_update() has completed a lpq and
236 is currently traversing the printing tdb and deleting jobs.
237 A workaround is to not delete the job if it has been
238 submitted less than lp_lpqcachetime() seconds ago. */
240 if ((cur_t - pjob.starttime) > lp_lpqcachetime())
251 /****************************************************************************
252 check if the print queue has been updated recently enough
253 ****************************************************************************/
254 static void print_cache_flush(int snum)
257 slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum));
258 tdb_store_int(tdb, key, -1);
261 /****************************************************************************
262 Check if someone already thinks they are doing the update.
263 ****************************************************************************/
265 static pid_t get_updating_pid(fstring printer_name)
271 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
273 key.dsize = strlen(keystr);
275 data = tdb_fetch(tdb, key);
276 if (!data.dptr || data.dsize != sizeof(pid_t))
279 memcpy(&updating_pid, data.dptr, sizeof(pid_t));
282 if (process_exists(updating_pid))
288 /****************************************************************************
289 Set the fact that we're doing the update, or have finished doing the update
291 ****************************************************************************/
293 static void set_updating_pid(fstring printer_name, BOOL delete)
298 pid_t updating_pid = getpid();
300 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
302 key.dsize = strlen(keystr);
305 tdb_delete(tdb, key);
309 data.dptr = (void *)&updating_pid;
310 data.dsize = sizeof(pid_t);
312 tdb_store(tdb, key, data, TDB_REPLACE);
315 /****************************************************************************
316 update the internal database from the system print queue for a queue
317 ****************************************************************************/
319 static void print_queue_update(int snum)
322 print_queue_struct *queue = NULL;
323 print_status_struct status;
324 print_status_struct old_status;
325 struct printjob *pjob;
326 struct traverse_struct tstruct;
327 fstring keystr, printer_name, cachestr;
330 fstrcpy(printer_name, lp_servicename(snum));
333 * Check to see if someone else is doing this update.
334 * This is essentially a mutex on the update.
337 if (get_updating_pid(printer_name) != -1)
340 /* Lock the queue for the database update */
342 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
343 tdb_lock_bystring(tdb, keystr);
346 * Ensure that no one else got in here.
347 * If the updating pid is still -1 then we are
351 if (get_updating_pid(printer_name) != -1) {
353 * Someone else is doing the update, exit.
355 tdb_unlock_bystring(tdb, keystr);
360 * We're going to do the update ourselves.
363 /* Tell others we're doing the update. */
364 set_updating_pid(printer_name, False);
367 * Allow others to enter and notice we're doing
371 tdb_unlock_bystring(tdb, keystr);
374 * Update the cache time FIRST ! Stops others even
375 * attempting to get the lock and doing this
376 * if the lpq takes a long time.
379 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name);
380 tdb_store_int(tdb, cachestr, (int)time(NULL));
382 /* get the current queue using the appropriate interface */
385 qcount = (*(current_printif->queue_get))(snum, &queue, &status);
387 DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
388 "s" : "", printer_name));
391 any job in the internal database that is marked as spooled
392 and doesn't exist in the system queue is considered finished
393 and removed from the database
395 any job in the system database but not in the internal database
396 is added as a unix job
398 fill in any system job numbers as we go
400 for (i=0; i<qcount; i++) {
401 int jobid = print_parse_jobid(queue[i].file);
404 /* assume its a unix print job */
405 print_unix_job(snum, &queue[i]);
409 /* we have an active SMB print job - update its status */
410 pjob = print_job_find(jobid);
412 /* err, somethings wrong. Probably smbd was restarted
413 with jobs in the queue. All we can do is treat them
414 like unix jobs. Pity. */
415 print_unix_job(snum, &queue[i]);
419 pjob->sysjob = queue[i].job;
420 pjob->status = queue[i].status;
422 print_job_store(jobid, pjob);
425 /* now delete any queued entries that don't appear in the
427 tstruct.queue = queue;
428 tstruct.qcount = qcount;
430 tstruct.total_jobs = 0;
432 tdb_traverse(tdb, traverse_fn_delete, (void *)&tstruct);
434 safe_free(tstruct.queue);
436 tdb_store_int(tdb, "INFO/total_jobs", tstruct.total_jobs);
439 * Get the old print status. We will use this to compare the
440 * number of jobs. If they have changed we need to send a
441 * "changed" message to the smbds.
444 if( qcount != get_queue_status(snum, &old_status)) {
445 DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
446 old_status.qcount, qcount, printer_name ));
447 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
450 /* store the new queue status structure */
451 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name);
453 key.dsize = strlen(keystr);
455 status.qcount = qcount;
456 data.dptr = (void *)&status;
457 data.dsize = sizeof(status);
458 tdb_store(tdb, key, data, TDB_REPLACE);
461 * Update the cache time again. We want to do this call
462 * as little as possible...
465 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
466 tdb_store_int(tdb, keystr, (int)time(NULL));
468 /* Delete our pid from the db. */
469 set_updating_pid(printer_name, True);
472 /****************************************************************************
473 check if a jobid is valid. It is valid if it exists in the database
474 ****************************************************************************/
475 BOOL print_job_exists(int jobid)
477 return tdb_exists(tdb, print_key(jobid));
481 /****************************************************************************
482 work out which service a jobid is for
483 note that we have to look up by queue name to ensure that it works for
484 other than the process that started the job
485 ****************************************************************************/
486 int print_job_snum(int jobid)
488 struct printjob *pjob = print_job_find(jobid);
489 if (!pjob) return -1;
491 return lp_servicenumber(pjob->qname);
494 /****************************************************************************
495 give the fd used for a jobid
496 ****************************************************************************/
497 int print_job_fd(int jobid)
499 struct printjob *pjob = print_job_find(jobid);
500 if (!pjob) return -1;
501 /* don't allow another process to get this info - it is meaningless */
502 if (pjob->pid != local_pid) return -1;
506 /****************************************************************************
507 give the filename used for a jobid
508 only valid for the process doing the spooling and when the job
510 ****************************************************************************/
511 char *print_job_fname(int jobid)
513 struct printjob *pjob = print_job_find(jobid);
514 if (!pjob || pjob->spooled || pjob->pid != local_pid) return NULL;
515 return pjob->filename;
519 /****************************************************************************
520 set the place in the queue for a job
521 ****************************************************************************/
522 BOOL print_job_set_place(int jobid, int place)
524 DEBUG(2,("print_job_set_place not implemented yet\n"));
528 /****************************************************************************
529 set the name of a job. Only possible for owner
530 ****************************************************************************/
531 BOOL print_job_set_name(int jobid, char *name)
533 struct printjob *pjob = print_job_find(jobid);
534 if (!pjob || pjob->pid != local_pid) return False;
536 fstrcpy(pjob->jobname, name);
537 return print_job_store(jobid, pjob);
541 /****************************************************************************
542 delete a print job - don't update queue
543 ****************************************************************************/
544 static BOOL print_job_delete1(int jobid)
546 struct printjob *pjob = print_job_find(jobid);
547 int snum, result = 0;
549 if (!pjob) return False;
552 * If already deleting just return.
555 if (pjob->status == LPQ_DELETING)
558 snum = print_job_snum(jobid);
560 /* Hrm - we need to be able to cope with deleting a job before it
561 has reached the spooler. */
563 if (pjob->sysjob == -1) {
564 DEBUG(5, ("attempt to delete job %d not seen by lpr\n",
568 /* Set the tdb entry to be deleting. */
570 pjob->status = LPQ_DELETING;
571 print_job_store(jobid, pjob);
573 if (pjob->spooled && pjob->sysjob != -1)
574 result = (*(current_printif->job_delete))(snum, pjob);
576 /* Delete the tdb entry if the delete suceeded or the job hasn't
580 tdb_delete(tdb, print_key(jobid));
583 return (result == 0);
586 /****************************************************************************
587 return true if the current user owns the print job
588 ****************************************************************************/
589 static BOOL is_owner(struct current_user *user, int jobid)
591 struct printjob *pjob = print_job_find(jobid);
594 if (!pjob || !user) return False;
596 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
597 return strequal(pjob->user, vuser->user.smb_name);
599 return strequal(pjob->user, uidtoname(user->uid));
603 /****************************************************************************
605 ****************************************************************************/
606 BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode)
608 int snum = print_job_snum(jobid);
612 owner = is_owner(user, jobid);
614 /* Check access against security descriptor or whether the user
618 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
619 DEBUG(3, ("delete denied by security descriptor\n"));
620 *errcode = WERR_ACCESS_DENIED;
624 if (!print_job_delete1(jobid)) return False;
626 /* force update the database and say the delete failed if the
629 print_queue_update(snum);
631 /* Send a printer notify message */
633 printer_name = PRINTERNAME(snum);
635 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
637 return !print_job_exists(jobid);
641 /****************************************************************************
643 ****************************************************************************/
644 BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode)
646 struct printjob *pjob = print_job_find(jobid);
650 if (!pjob || !user) return False;
652 if (!pjob->spooled || pjob->sysjob == -1) return False;
654 snum = print_job_snum(jobid);
656 if (!is_owner(user, jobid) &&
657 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
658 DEBUG(3, ("pause denied by security descriptor\n"));
659 *errcode = WERR_ACCESS_DENIED;
663 /* need to pause the spooled entry */
664 ret = (*(current_printif->job_pause))(snum, pjob);
667 *errcode = WERR_INVALID_PARAM;
671 /* force update the database */
672 print_cache_flush(snum);
674 /* Send a printer notify message */
676 printer_name = PRINTERNAME(snum);
678 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
680 /* how do we tell if this succeeded? */
685 /****************************************************************************
687 ****************************************************************************/
688 BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode)
690 struct printjob *pjob = print_job_find(jobid);
694 if (!pjob || !user) return False;
696 if (!pjob->spooled || pjob->sysjob == -1) return False;
698 snum = print_job_snum(jobid);
700 if (!is_owner(user, jobid) &&
701 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
702 DEBUG(3, ("resume denied by security descriptor\n"));
703 *errcode = WERR_ACCESS_DENIED;
707 ret = (*(current_printif->job_resume))(snum, pjob);
710 *errcode = WERR_INVALID_PARAM;
714 /* force update the database */
715 print_cache_flush(snum);
717 /* Send a printer notify message */
719 printer_name = PRINTERNAME(snum);
721 message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
726 /****************************************************************************
727 write to a print file
728 ****************************************************************************/
729 int print_job_write(int jobid, const char *buf, int size)
733 fd = print_job_fd(jobid);
734 if (fd == -1) return -1;
736 return write(fd, buf, size);
739 /****************************************************************************
740 Check if the print queue has been updated recently enough.
741 ****************************************************************************/
743 static BOOL print_cache_expired(int snum)
746 time_t t2, t = time(NULL);
748 slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum));
749 t2 = tdb_fetch_int(tdb, key);
750 if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) {
751 DEBUG(3, ("print cache expired\n"));
757 /****************************************************************************
758 Get the queue status - do not update if db is out of date.
759 ****************************************************************************/
760 static int get_queue_status(int snum, print_status_struct *status)
765 ZERO_STRUCTP(status);
766 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", lp_servicename(snum));
768 key.dsize = strlen(keystr);
769 data = tdb_fetch(tdb, key);
771 if (data.dsize == sizeof(print_status_struct)) {
772 memcpy(status, data.dptr, sizeof(print_status_struct));
776 return status->qcount;
779 /****************************************************************************
780 Determine the number of jobs in a queue.
781 ****************************************************************************/
782 static int print_queue_length(int snum)
784 print_status_struct status;
786 /* make sure the database is up to date */
787 if (print_cache_expired(snum)) print_queue_update(snum);
789 /* also fetch the queue status */
790 return get_queue_status(snum, &status);
793 /****************************************************************************
794 Determine the number of jobs in all queues.
795 ****************************************************************************/
796 static int get_total_jobs(int snum)
800 /* make sure the database is up to date */
801 if (print_cache_expired(snum)) print_queue_update(snum);
803 total_jobs = tdb_fetch_int(tdb, "INFO/total_jobs");
810 /***************************************************************************
811 start spooling a job - return the jobid
812 ***************************************************************************/
813 int print_job_start(struct current_user *user, int snum, char *jobname)
817 struct printjob pjob;
823 if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
824 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
828 if (!print_time_access_check(snum)) {
829 DEBUG(3, ("print_job_start: job start denied by time check\n"));
833 path = lp_pathname(snum);
835 /* see if we have sufficient disk space */
836 if (lp_minprintspace(snum)) {
837 SMB_BIG_UINT dspace, dsize;
838 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
839 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
840 DEBUG(3, ("print_job_start: disk space check failed.\n"));
846 /* for autoloaded printers, check that the printcap entry still exists */
847 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_servicename(snum), NULL)) {
848 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_servicename(snum) ));
853 /* Insure the maximum queue size is not violated */
854 if (lp_maxprintjobs(snum) && print_queue_length(snum) > lp_maxprintjobs(snum)) {
855 DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per queue (%d).\n",
856 print_queue_length(snum), lp_maxprintjobs(snum) ));
861 /* Insure the maximum print jobs in the system is not violated */
862 if (lp_totalprintjobs() && get_total_jobs(snum) > lp_totalprintjobs()) {
863 DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per system (%d).\n",
864 print_queue_length(snum), lp_totalprintjobs() ));
869 /* create the database entry */
871 pjob.pid = local_pid;
874 pjob.starttime = time(NULL);
875 pjob.status = LPQ_SPOOLING;
877 pjob.spooled = False;
880 fstrcpy(pjob.jobname, jobname);
882 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
883 fstrcpy(pjob.user, vuser->user.smb_name);
885 fstrcpy(pjob.user, uidtoname(user->uid));
888 fstrcpy(pjob.qname, lp_servicename(snum));
890 /* lock the database */
891 tdb_lock_bystring(tdb, "INFO/nextjob");
893 next_jobid = tdb_fetch_int(tdb, "INFO/nextjob");
894 if (next_jobid == -1)
897 for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) {
898 if (!print_job_exists(jobid))
901 if (jobid == next_jobid || !print_job_store(jobid, &pjob)) {
902 DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or print_job_store failed.\n",
903 jobid, next_jobid ));
908 tdb_store_int(tdb, "INFO/nextjob", jobid);
910 /* we have a job entry - now create the spool file */
911 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.6d.XXXXXX",
912 path, PRINT_SPOOL_PREFIX, jobid);
913 pjob.fd = smb_mkstemp(pjob.filename);
916 if (errno == EACCES) {
917 /* Common setup error, force a report. */
918 DEBUG(0, ("print_job_start: insufficient permissions \
919 to open spool file %s.\n", pjob.filename));
921 /* Normal case, report at level 3 and above. */
922 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
923 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
928 print_job_store(jobid, &pjob);
930 tdb_unlock_bystring(tdb, "INFO/nextjob");
933 * If the printer is marked as postscript output a leading
934 * file identifier to ensure the file is treated as a raw
936 * This has a similar effect as CtrlD=0 in WIN.INI file.
937 * tim@fsg.com 09/06/94
939 if (lp_postscript(snum)) {
940 print_job_write(jobid, "%!\n",3);
947 tdb_delete(tdb, print_key(jobid));
950 tdb_unlock_bystring(tdb, "INFO/nextjob");
952 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
956 /****************************************************************************
957 Print a file - called on closing the file. This spools the job.
958 If normal close is false then we're tearing down the jobs - treat as an
960 ****************************************************************************/
962 BOOL print_job_end(int jobid, BOOL normal_close)
964 struct printjob *pjob = print_job_find(jobid);
966 SMB_STRUCT_STAT sbuf;
971 if (pjob->spooled || pjob->pid != local_pid)
974 snum = print_job_snum(jobid);
976 if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
977 pjob->size = sbuf.st_size;
983 * Not a normal close or we couldn't stat the job file,
984 * so something has gone wrong. Cleanup.
988 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
992 /* Technically, this is not quit right. If the printer has a separator
993 * page turned on, the NT spooler prints the separator page even if the
994 * print job is 0 bytes. 010215 JRR */
995 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
996 /* don't bother spooling empty files or something being deleted. */
997 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
998 pjob->filename, pjob->size ? "deleted" : "zero length" ));
999 unlink(pjob->filename);
1000 tdb_delete(tdb, print_key(jobid));
1004 ret = (*(current_printif->job_submit))(snum, pjob);
1009 /* The print job has been sucessfully handed over to the back-end */
1011 pjob->spooled = True;
1012 pjob->status = LPQ_QUEUED;
1013 print_job_store(jobid, pjob);
1015 /* make sure the database is up to date */
1016 if (print_cache_expired(snum))
1017 print_queue_update(snum);
1023 /* The print job was not succesfully started. Cleanup */
1024 /* Still need to add proper error return propagation! 010122:JRR */
1025 unlink(pjob->filename);
1026 tdb_delete(tdb, print_key(jobid));
1030 /* utility fn to enumerate the print queue */
1031 static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
1033 struct traverse_struct *ts = (struct traverse_struct *)state;
1034 struct printjob pjob;
1037 if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
1038 memcpy(&jobid, key.dptr, sizeof(jobid));
1039 memcpy(&pjob, data.dptr, sizeof(pjob));
1041 /* maybe it isn't for this queue */
1042 if (ts->snum != print_queue_snum(pjob.qname)) return 0;
1044 if (ts->qcount >= ts->maxcount) return 0;
1048 ts->queue[i].job = jobid;
1049 ts->queue[i].size = pjob.size;
1050 ts->queue[i].status = pjob.status;
1051 ts->queue[i].priority = 1;
1052 ts->queue[i].time = pjob.starttime;
1053 fstrcpy(ts->queue[i].user, pjob.user);
1054 fstrcpy(ts->queue[i].file, pjob.jobname);
1061 struct traverse_count_struct {
1065 /* utility fn to count the number of entries in the print queue */
1066 static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
1068 struct traverse_count_struct *ts = (struct traverse_count_struct *)state;
1069 struct printjob pjob;
1072 if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
1073 memcpy(&jobid, key.dptr, sizeof(jobid));
1074 memcpy(&pjob, data.dptr, sizeof(pjob));
1076 /* maybe it isn't for this queue */
1077 if (ts->snum != print_queue_snum(pjob.qname)) return 0;
1084 /* Sort print jobs by submittal time */
1086 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1090 if (!j1 && !j2) return 0;
1094 /* Sort on job start time */
1096 if (j1->time == j2->time) return 0;
1097 return (j1->time > j2->time) ? 1 : -1;
1100 /****************************************************************************
1101 get a printer queue listing
1102 ****************************************************************************/
1103 int print_queue_status(int snum,
1104 print_queue_struct **queue,
1105 print_status_struct *status)
1107 struct traverse_struct tstruct;
1108 struct traverse_count_struct tsc;
1112 /* make sure the database is up to date */
1113 if (print_cache_expired(snum)) print_queue_update(snum);
1118 * Fetch the queue status. We must do this first, as there may
1119 * be no jobs in the queue.
1121 ZERO_STRUCTP(status);
1122 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", lp_servicename(snum));
1124 key.dsize = strlen(keystr);
1125 data = tdb_fetch(tdb, key);
1127 if (data.dsize == sizeof(*status)) {
1128 memcpy(status, data.dptr, sizeof(*status));
1134 * Now, fetch the print queue information. We first count the number
1135 * of entries, and then only retrieve the queue if necessary.
1140 tdb_traverse(tdb, traverse_count_fn_queue, (void *)&tsc);
1145 /* Allocate the queue size. */
1146 if ((tstruct.queue = (print_queue_struct *)
1147 malloc(sizeof(print_queue_struct)*tsc.count))
1152 * Fill in the queue.
1153 * We need maxcount as the queue size may have changed between
1154 * the two calls to tdb_traverse.
1157 tstruct.maxcount = tsc.count;
1158 tstruct.snum = snum;
1160 tdb_traverse(tdb, traverse_fn_queue, (void *)&tstruct);
1162 /* Sort the queue by submission time otherwise they are displayed
1165 qsort(tstruct.queue, tstruct.qcount, sizeof(print_queue_struct),
1166 QSORT_CAST(printjob_comp));
1168 *queue = tstruct.queue;
1169 return tstruct.qcount;
1173 /****************************************************************************
1174 turn a queue name into a snum
1175 ****************************************************************************/
1176 int print_queue_snum(char *qname)
1178 int snum = lp_servicenumber(qname);
1179 if (snum == -1 || !lp_print_ok(snum)) return -1;
1184 /****************************************************************************
1186 ****************************************************************************/
1187 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
1192 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
1193 *errcode = WERR_ACCESS_DENIED;
1197 ret = (*(current_printif->queue_pause))(snum);
1200 *errcode = WERR_INVALID_PARAM;
1204 /* force update the database */
1205 print_cache_flush(snum);
1207 /* Send a printer notify message */
1209 printer_name = PRINTERNAME(snum);
1211 message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
1216 /****************************************************************************
1218 ****************************************************************************/
1219 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
1224 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
1225 *errcode = WERR_ACCESS_DENIED;
1229 ret = (*(current_printif->queue_resume))(snum);
1232 *errcode = WERR_INVALID_PARAM;
1236 /* make sure the database is up to date */
1237 if (print_cache_expired(snum)) print_queue_update(snum);
1239 /* Send a printer notify message */
1241 printer_name = PRINTERNAME(snum);
1243 message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
1248 /****************************************************************************
1249 purge a queue - implemented by deleting all jobs that we can delete
1250 ****************************************************************************/
1251 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
1253 print_queue_struct *queue;
1254 print_status_struct status;
1259 /* Force and update so the count is accurate (i.e. not a cached count) */
1260 print_queue_update(snum);
1262 can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
1263 njobs = print_queue_status(snum, &queue, &status);
1265 for (i=0;i<njobs;i++) {
1266 BOOL owner = is_owner(user, queue[i].job);
1268 if (owner || can_job_admin) {
1269 print_job_delete1(queue[i].job);
1275 /* Send a printer notify message */
1277 printer_name = PRINTERNAME(snum);
1279 message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);