2 Unix SMB/CIFS implementation.
3 printing backend routines
4 Copyright (C) Andrew Tridgell 1992-2000
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 /* Current printer interface */
24 struct printif *current_printif = &generic_printif;
27 the printing backend revolves around a tdb database that stores the
28 SMB view of the print queue
30 The key for this database is a jobid - a internally generated number that
31 uniquely identifies a print job
33 reading the print queue involves two steps:
34 - possibly running lpq and updating the internal database from that
35 - reading entries from the database
37 jobids are assigned when a job starts spooling.
40 /* the open printing.tdb database */
41 static TDB_CONTEXT *tdb;
42 static pid_t local_pid;
44 static int get_queue_status(int, print_status_struct *);
46 /****************************************************************************
47 Initialise the printing backend. Called once at startup.
48 Does not survive a fork
49 ****************************************************************************/
51 BOOL print_backend_init(void)
53 char *sversion = "INFO/version";
55 if (tdb && local_pid == sys_getpid()) return True;
56 tdb = tdb_open_log(lock_path("printing.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
58 DEBUG(0,("print_backend_init: Failed to open printing backend database. Error = [%s]\n",
62 local_pid = sys_getpid();
64 /* handle a Samba upgrade */
65 tdb_lock_bystring(tdb, sversion);
66 if (tdb_fetch_int32(tdb, sversion) != PRINT_DATABASE_VERSION) {
67 tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
68 tdb_store_int32(tdb, sversion, PRINT_DATABASE_VERSION);
70 tdb_unlock_bystring(tdb, sversion);
72 /* select the appropriate printing interface... */
74 if (strcmp(lp_printcapname(), "cups") == 0)
75 current_printif = &cups_printif;
76 #endif /* HAVE_CUPS */
78 /* do NT print initialization... */
79 return nt_printing_init();
82 /****************************************************************************
83 useful function to generate a tdb key
84 ****************************************************************************/
85 static TDB_DATA print_key(int jobid)
91 ret.dptr = (void *)&j;
92 ret.dsize = sizeof(j);
96 /****************************************************************************
97 useful function to find a print job in the database
98 ****************************************************************************/
99 static struct printjob *print_job_find(int jobid)
101 static struct printjob pjob;
104 ret = tdb_fetch(tdb, print_key(jobid));
105 if (!ret.dptr || ret.dsize != sizeof(pjob)) return NULL;
107 memcpy(&pjob, ret.dptr, sizeof(pjob));
112 /****************************************************************************
113 store a job structure back to the database
114 ****************************************************************************/
115 static BOOL print_job_store(int jobid, struct printjob *pjob)
120 d.dptr = (void *)pjob;
121 d.dsize = sizeof(*pjob);
122 ret = (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->fs_file);
167 fstrcpy(pj.user, q->fs_user);
168 fstrcpy(pj.queuename, 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 (ts->snum != lp_servicenumber(pjob.queuename)) {
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].fs_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_int32(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 = sys_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 Send a message saying the queue changed.
317 ****************************************************************************/
319 static void send_queue_message(const char *printer_name, uint32 high, uint32 low)
321 char msg[8 + sizeof(fstring)];
324 fstrcpy(&msg[8], printer_name);
326 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, msg, 8 + strlen(printer_name) + 1, False, NULL);
329 /****************************************************************************
330 update the internal database from the system print queue for a queue in the background
331 ****************************************************************************/
333 static void print_queue_update_background(int snum)
336 print_queue_struct *queue = NULL;
337 print_status_struct status;
338 print_status_struct old_status;
339 struct printjob *pjob;
340 struct traverse_struct tstruct;
341 fstring keystr, printer_name, cachestr;
344 fstrcpy(printer_name, lp_servicename(snum));
347 * Check to see if someone else is doing this update.
348 * This is essentially a mutex on the update.
351 if (get_updating_pid(printer_name) != -1)
354 /* Lock the queue for the database update */
356 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
357 tdb_lock_bystring(tdb, keystr);
360 * Ensure that no one else got in here.
361 * If the updating pid is still -1 then we are
365 if (get_updating_pid(printer_name) != -1) {
367 * Someone else is doing the update, exit.
369 tdb_unlock_bystring(tdb, keystr);
374 * We're going to do the update ourselves.
377 /* Tell others we're doing the update. */
378 set_updating_pid(printer_name, False);
381 * Allow others to enter and notice we're doing
385 tdb_unlock_bystring(tdb, keystr);
388 * Update the cache time FIRST ! Stops others even
389 * attempting to get the lock and doing this
390 * if the lpq takes a long time.
393 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name);
394 tdb_store_int32(tdb, cachestr, (int)time(NULL));
396 /* get the current queue using the appropriate interface */
399 qcount = (*(current_printif->queue_get))(snum, &queue, &status);
401 DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
402 "s" : "", printer_name));
405 any job in the internal database that is marked as spooled
406 and doesn't exist in the system queue is considered finished
407 and removed from the database
409 any job in the system database but not in the internal database
410 is added as a unix job
412 fill in any system job numbers as we go
414 for (i=0; i<qcount; i++) {
415 int jobid = print_parse_jobid(queue[i].fs_file);
418 /* assume its a unix print job */
419 print_unix_job(snum, &queue[i]);
423 /* we have an active SMB print job - update its status */
424 pjob = print_job_find(jobid);
426 /* err, somethings wrong. Probably smbd was restarted
427 with jobs in the queue. All we can do is treat them
428 like unix jobs. Pity. */
429 print_unix_job(snum, &queue[i]);
433 pjob->sysjob = queue[i].job;
434 pjob->status = queue[i].status;
436 print_job_store(jobid, pjob);
439 /* now delete any queued entries that don't appear in the
441 tstruct.queue = queue;
442 tstruct.qcount = qcount;
444 tstruct.total_jobs = 0;
446 tdb_traverse(tdb, traverse_fn_delete, (void *)&tstruct);
448 safe_free(tstruct.queue);
450 tdb_store_int32(tdb, "INFO/total_jobs", tstruct.total_jobs);
453 * Get the old print status. We will use this to compare the
454 * number of jobs. If they have changed we need to send a
455 * "changed" message to the smbds.
458 if( qcount != get_queue_status(snum, &old_status)) {
459 DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
460 old_status.qcount, qcount, printer_name ));
461 send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB);
464 /* store the new queue status structure */
465 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name);
467 key.dsize = strlen(keystr);
469 status.qcount = qcount;
470 data.dptr = (void *)&status;
471 data.dsize = sizeof(status);
472 tdb_store(tdb, key, data, TDB_REPLACE);
475 * Update the cache time again. We want to do this call
476 * as little as possible...
479 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
480 tdb_store_int32(tdb, keystr, (int)time(NULL));
482 /* Delete our pid from the db. */
483 set_updating_pid(printer_name, True);
486 /****************************************************************************
487 this is the receive function of the background lpq updater
488 ****************************************************************************/
489 static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len)
493 print_queue_update_background(snum);
496 static pid_t background_lpq_updater_pid;
498 /****************************************************************************
499 main thread of the background lpq updater
500 ****************************************************************************/
501 void start_background_queue(void)
503 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
504 background_lpq_updater_pid = sys_fork();
506 if (background_lpq_updater_pid == -1) {
507 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
511 if(background_lpq_updater_pid == 0) {
513 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
515 claim_connection(NULL,"smbd lpq backend",0,False);
517 if (!locking_init(0))
520 if (!print_backend_init())
523 message_register(MSG_PRINTER_UPDATE, print_queue_receive);
525 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
528 DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
534 /****************************************************************************
535 update the internal database from the system print queue for a queue
536 ****************************************************************************/
537 static void print_queue_update(int snum)
539 message_send_pid(background_lpq_updater_pid, MSG_PRINTER_UPDATE, &snum, sizeof(snum), False);
542 /****************************************************************************
543 check if a jobid is valid. It is valid if it exists in the database
544 ****************************************************************************/
545 BOOL print_job_exists(int jobid)
547 return tdb_exists(tdb, print_key(jobid));
551 /****************************************************************************
552 work out which service a jobid is for
553 note that we have to look up by queue name to ensure that it works for
554 other than the process that started the job
555 ****************************************************************************/
556 int print_job_snum(int jobid)
558 struct printjob *pjob = print_job_find(jobid);
559 if (!pjob) return -1;
561 return find_service(pjob->queuename);
564 /****************************************************************************
565 give the fd used for a jobid
566 ****************************************************************************/
567 int print_job_fd(int jobid)
569 struct printjob *pjob = print_job_find(jobid);
570 if (!pjob) return -1;
571 /* don't allow another process to get this info - it is meaningless */
572 if (pjob->pid != local_pid) return -1;
576 /****************************************************************************
577 give the filename used for a jobid
578 only valid for the process doing the spooling and when the job
580 ****************************************************************************/
581 char *print_job_fname(int jobid)
583 struct printjob *pjob = print_job_find(jobid);
584 if (!pjob || pjob->spooled || pjob->pid != local_pid) return NULL;
585 return pjob->filename;
589 /****************************************************************************
590 set the place in the queue for a job
591 ****************************************************************************/
592 BOOL print_job_set_place(int jobid, int place)
594 DEBUG(2,("print_job_set_place not implemented yet\n"));
598 /****************************************************************************
599 set the name of a job. Only possible for owner
600 ****************************************************************************/
601 BOOL print_job_set_name(int jobid, char *name)
603 struct printjob *pjob = print_job_find(jobid);
604 if (!pjob || pjob->pid != local_pid) return False;
606 fstrcpy(pjob->jobname, name);
607 return print_job_store(jobid, pjob);
611 /****************************************************************************
612 delete a print job - don't update queue
613 ****************************************************************************/
614 static BOOL print_job_delete1(int jobid)
616 struct printjob *pjob = print_job_find(jobid);
617 int snum, result = 0;
619 if (!pjob) return False;
622 * If already deleting just return.
625 if (pjob->status == LPQ_DELETING)
628 snum = print_job_snum(jobid);
630 DEBUG(5,("print_job_delete1: unknown service number for jobid %d\n", jobid));
634 /* Hrm - we need to be able to cope with deleting a job before it
635 has reached the spooler. */
637 if (pjob->sysjob == -1) {
638 DEBUG(5, ("attempt to delete job %d not seen by lpr\n",
642 /* Set the tdb entry to be deleting. */
644 pjob->status = LPQ_DELETING;
645 print_job_store(jobid, pjob);
647 if (pjob->spooled && pjob->sysjob != -1)
648 result = (*(current_printif->job_delete))(snum, pjob);
650 /* Delete the tdb entry if the delete suceeded or the job hasn't
654 tdb_delete(tdb, print_key(jobid));
657 return (result == 0);
660 /****************************************************************************
661 return true if the current user owns the print job
662 ****************************************************************************/
663 static BOOL is_owner(struct current_user *user, int jobid)
665 struct printjob *pjob = print_job_find(jobid);
668 if (!pjob || !user) return False;
670 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
671 return strequal(pjob->user, vuser->user.smb_name);
673 return strequal(pjob->user, uidtoname(user->uid));
677 /****************************************************************************
679 ****************************************************************************/
680 BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode)
682 int snum = print_job_snum(jobid);
687 DEBUG(5,("print_job_delete: unknown service number for jobid %d\n", jobid));
691 owner = is_owner(user, jobid);
693 /* Check access against security descriptor or whether the user
697 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
698 DEBUG(3, ("delete denied by security descriptor\n"));
699 *errcode = WERR_ACCESS_DENIED;
703 if (!print_job_delete1(jobid)) return False;
705 /* force update the database and say the delete failed if the
708 print_queue_update(snum);
710 /* Send a printer notify message */
712 printer_name = PRINTERNAME(snum);
714 send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB);
716 return !print_job_exists(jobid);
720 /****************************************************************************
722 ****************************************************************************/
723 BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode)
725 struct printjob *pjob = print_job_find(jobid);
729 if (!pjob || !user) return False;
731 if (!pjob->spooled || pjob->sysjob == -1) return False;
733 snum = print_job_snum(jobid);
735 DEBUG(5,("print_job_pause: unknown service number for jobid %d\n", jobid));
739 DEBUG(5,("print_job_resume: unknown service number for jobid %d\n", jobid));
743 if (!is_owner(user, jobid) &&
744 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
745 DEBUG(3, ("pause denied by security descriptor\n"));
746 *errcode = WERR_ACCESS_DENIED;
750 /* need to pause the spooled entry */
751 ret = (*(current_printif->job_pause))(snum, pjob);
754 *errcode = WERR_INVALID_PARAM;
758 /* force update the database */
759 print_cache_flush(snum);
761 /* Send a printer notify message */
763 printer_name = PRINTERNAME(snum);
765 send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB);
767 /* how do we tell if this succeeded? */
772 /****************************************************************************
774 ****************************************************************************/
775 BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode)
777 struct printjob *pjob = print_job_find(jobid);
781 if (!pjob || !user) return False;
783 if (!pjob->spooled || pjob->sysjob == -1) return False;
785 snum = print_job_snum(jobid);
787 if (!is_owner(user, jobid) &&
788 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
789 DEBUG(3, ("resume denied by security descriptor\n"));
790 *errcode = WERR_ACCESS_DENIED;
794 ret = (*(current_printif->job_resume))(snum, pjob);
797 *errcode = WERR_INVALID_PARAM;
801 /* force update the database */
802 print_cache_flush(snum);
804 /* Send a printer notify message */
806 printer_name = PRINTERNAME(snum);
808 send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB);
813 /****************************************************************************
814 write to a print file
815 ****************************************************************************/
816 int print_job_write(int jobid, const char *buf, int size)
819 struct printjob *pjob = print_job_find(jobid);
823 /* don't allow another process to get this info - it is meaningless */
824 if (pjob->pid != local_pid)
827 return_code = write(pjob->fd, buf, size);
830 print_job_store(jobid, pjob);
835 /****************************************************************************
836 Check if the print queue has been updated recently enough.
837 ****************************************************************************/
839 static BOOL print_cache_expired(int snum)
842 time_t last_qscan_time, time_now = time(NULL);
844 slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum));
845 last_qscan_time = (time_t)tdb_fetch_int32(tdb, key);
848 * Invalidate the queue for 3 reasons.
849 * (1). last queue scan time == -1.
850 * (2). Current time - last queue scan time > allowed cache time.
851 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
852 * This last test picks up machines for which the clock has been moved
853 * forward, an lpq scan done and then the clock moved back. Otherwise
854 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
857 if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
858 last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
859 DEBUG(3, ("print cache expired for queue %s \
860 (last_qscan_time = %d, time now = %d, qcachetime = %d)\n", lp_servicename(snum),
861 (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
867 /****************************************************************************
868 Get the queue status - do not update if db is out of date.
869 ****************************************************************************/
870 static int get_queue_status(int snum, print_status_struct *status)
875 ZERO_STRUCTP(status);
876 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", lp_servicename(snum));
878 key.dsize = strlen(keystr);
879 data = tdb_fetch(tdb, key);
881 if (data.dsize == sizeof(print_status_struct)) {
882 memcpy(status, data.dptr, sizeof(print_status_struct));
886 return status->qcount;
889 /****************************************************************************
890 Determine the number of jobs in a queue.
891 ****************************************************************************/
893 int print_queue_length(int snum, print_status_struct *pstatus)
895 print_status_struct status;
898 /* make sure the database is up to date */
899 if (print_cache_expired(snum))
900 print_queue_update(snum);
902 /* also fetch the queue status */
903 memset(&status, 0, sizeof(status));
904 len = get_queue_status(snum, &status);
910 /****************************************************************************
911 Determine the number of jobs in all queues.
912 ****************************************************************************/
913 static int get_total_jobs(int snum)
917 /* make sure the database is up to date */
918 if (print_cache_expired(snum)) print_queue_update(snum);
920 total_jobs = tdb_fetch_int32(tdb, "INFO/total_jobs");
927 /***************************************************************************
928 start spooling a job - return the jobid
929 ***************************************************************************/
930 int print_job_start(struct current_user *user, int snum, char *jobname)
934 struct printjob pjob;
941 if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
942 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
946 if (!print_time_access_check(snum)) {
947 DEBUG(3, ("print_job_start: job start denied by time check\n"));
951 path = lp_pathname(snum);
953 /* see if we have sufficient disk space */
954 if (lp_minprintspace(snum)) {
955 SMB_BIG_UINT dspace, dsize;
956 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
957 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
958 DEBUG(3, ("print_job_start: disk space check failed.\n"));
964 /* for autoloaded printers, check that the printcap entry still exists */
965 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_servicename(snum), NULL)) {
966 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_servicename(snum) ));
971 /* Insure the maximum queue size is not violated */
972 if (lp_maxprintjobs(snum) && (njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
973 DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per queue (%d).\n",
974 njobs, lp_maxprintjobs(snum) ));
979 /* Insure the maximum print jobs in the system is not violated */
980 if (lp_totalprintjobs() && get_total_jobs(snum) > lp_totalprintjobs()) {
981 DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per system (%d).\n",
982 njobs, lp_totalprintjobs() ));
987 /* create the database entry */
989 pjob.pid = local_pid;
992 pjob.starttime = time(NULL);
993 pjob.status = LPQ_SPOOLING;
995 pjob.spooled = False;
998 fstrcpy(pjob.jobname, jobname);
1000 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1001 fstrcpy(pjob.user, vuser->user.smb_name);
1003 fstrcpy(pjob.user, uidtoname(user->uid));
1006 fstrcpy(pjob.queuename, lp_servicename(snum));
1008 /* lock the database */
1009 tdb_lock_bystring(tdb, "INFO/nextjob");
1011 next_jobid = tdb_fetch_int32(tdb, "INFO/nextjob");
1012 if (next_jobid == -1)
1015 for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) {
1016 if (!print_job_exists(jobid))
1019 if (jobid == next_jobid || !print_job_store(jobid, &pjob)) {
1020 DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or print_job_store failed.\n",
1021 jobid, next_jobid ));
1026 tdb_store_int32(tdb, "INFO/nextjob", jobid);
1028 /* we have a job entry - now create the spool file */
1029 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.6d.XXXXXX",
1030 path, PRINT_SPOOL_PREFIX, jobid);
1031 pjob.fd = smb_mkstemp(pjob.filename);
1033 if (pjob.fd == -1) {
1034 if (errno == EACCES) {
1035 /* Common setup error, force a report. */
1036 DEBUG(0, ("print_job_start: insufficient permissions \
1037 to open spool file %s.\n", pjob.filename));
1039 /* Normal case, report at level 3 and above. */
1040 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
1041 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
1046 print_job_store(jobid, &pjob);
1048 tdb_unlock_bystring(tdb, "INFO/nextjob");
1051 * If the printer is marked as postscript output a leading
1052 * file identifier to ensure the file is treated as a raw
1054 * This has a similar effect as CtrlD=0 in WIN.INI file.
1055 * tim@fsg.com 09/06/94
1057 if (lp_postscript(snum)) {
1058 print_job_write(jobid, "%!\n",3);
1065 tdb_delete(tdb, print_key(jobid));
1068 tdb_unlock_bystring(tdb, "INFO/nextjob");
1070 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
1074 /****************************************************************************
1075 Update the number of pages spooled to jobid
1076 ****************************************************************************/
1078 void print_job_endpage(int jobid)
1080 struct printjob *pjob = print_job_find(jobid);
1083 /* don't allow another process to get this info - it is meaningless */
1084 if (pjob->pid != local_pid)
1088 print_job_store(jobid, pjob);
1091 /****************************************************************************
1092 Print a file - called on closing the file. This spools the job.
1093 If normal close is false then we're tearing down the jobs - treat as an
1095 ****************************************************************************/
1097 BOOL print_job_end(int jobid, BOOL normal_close)
1099 struct printjob *pjob = print_job_find(jobid);
1101 SMB_STRUCT_STAT sbuf;
1106 if (pjob->spooled || pjob->pid != local_pid)
1109 snum = print_job_snum(jobid);
1111 DEBUG(5,("print_job_end: unknown service number for jobid %d\n", jobid));
1115 if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
1116 pjob->size = sbuf.st_size;
1122 * Not a normal close or we couldn't stat the job file,
1123 * so something has gone wrong. Cleanup.
1127 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
1131 /* Technically, this is not quit right. If the printer has a separator
1132 * page turned on, the NT spooler prints the separator page even if the
1133 * print job is 0 bytes. 010215 JRR */
1134 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
1135 /* don't bother spooling empty files or something being deleted. */
1136 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
1137 pjob->filename, pjob->size ? "deleted" : "zero length" ));
1138 unlink(pjob->filename);
1139 tdb_delete(tdb, print_key(jobid));
1143 ret = (*(current_printif->job_submit))(snum, pjob);
1148 /* The print job has been sucessfully handed over to the back-end */
1150 pjob->spooled = True;
1151 pjob->status = LPQ_QUEUED;
1152 print_job_store(jobid, pjob);
1154 /* make sure the database is up to date */
1155 if (print_cache_expired(snum))
1156 print_queue_update(snum);
1162 /* The print job was not succesfully started. Cleanup */
1163 /* Still need to add proper error return propagation! 010122:JRR */
1164 unlink(pjob->filename);
1165 tdb_delete(tdb, print_key(jobid));
1169 /* utility fn to enumerate the print queue */
1170 static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
1172 struct traverse_struct *ts = (struct traverse_struct *)state;
1173 struct printjob pjob;
1176 if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
1177 memcpy(&jobid, key.dptr, sizeof(jobid));
1178 memcpy(&pjob, data.dptr, sizeof(pjob));
1180 /* maybe it isn't for this queue */
1181 if (ts->snum != lp_servicenumber(pjob.queuename))
1184 if (ts->qcount >= ts->maxcount) return 0;
1188 ts->queue[i].job = jobid;
1189 ts->queue[i].size = pjob.size;
1190 ts->queue[i].page_count = pjob.page_count;
1191 ts->queue[i].status = pjob.status;
1192 ts->queue[i].priority = 1;
1193 ts->queue[i].time = pjob.starttime;
1194 fstrcpy(ts->queue[i].fs_user, pjob.user);
1195 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
1202 struct traverse_count_struct {
1206 /* utility fn to count the number of entries in the print queue */
1207 static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
1209 struct traverse_count_struct *ts = (struct traverse_count_struct *)state;
1210 struct printjob pjob;
1213 if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
1214 memcpy(&jobid, key.dptr, sizeof(jobid));
1215 memcpy(&pjob, data.dptr, sizeof(pjob));
1217 /* maybe it isn't for this queue */
1218 if (ts->snum != lp_servicenumber(pjob.queuename))
1226 /* Sort print jobs by submittal time */
1228 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1232 if (!j1 && !j2) return 0;
1236 /* Sort on job start time */
1238 if (j1->time == j2->time) return 0;
1239 return (j1->time > j2->time) ? 1 : -1;
1242 /****************************************************************************
1243 get a printer queue listing
1244 ****************************************************************************/
1245 int print_queue_status(int snum,
1246 print_queue_struct **queue,
1247 print_status_struct *status)
1249 struct traverse_struct tstruct;
1250 struct traverse_count_struct tsc;
1254 /* make sure the database is up to date */
1255 if (print_cache_expired(snum)) print_queue_update(snum);
1260 * Fetch the queue status. We must do this first, as there may
1261 * be no jobs in the queue.
1263 ZERO_STRUCTP(status);
1264 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", lp_servicename(snum));
1266 key.dsize = strlen(keystr);
1267 data = tdb_fetch(tdb, key);
1269 if (data.dsize == sizeof(*status)) {
1270 memcpy(status, data.dptr, sizeof(*status));
1276 * Now, fetch the print queue information. We first count the number
1277 * of entries, and then only retrieve the queue if necessary.
1282 tdb_traverse(tdb, traverse_count_fn_queue, (void *)&tsc);
1287 /* Allocate the queue size. */
1288 if ((tstruct.queue = (print_queue_struct *)
1289 malloc(sizeof(print_queue_struct)*tsc.count))
1294 * Fill in the queue.
1295 * We need maxcount as the queue size may have changed between
1296 * the two calls to tdb_traverse.
1299 tstruct.maxcount = tsc.count;
1300 tstruct.snum = snum;
1302 tdb_traverse(tdb, traverse_fn_queue, (void *)&tstruct);
1304 /* Sort the queue by submission time otherwise they are displayed
1307 qsort(tstruct.queue, tstruct.qcount, sizeof(print_queue_struct),
1308 QSORT_CAST(printjob_comp));
1310 *queue = tstruct.queue;
1311 return tstruct.qcount;
1315 /****************************************************************************
1316 turn a queue name into a snum
1317 ****************************************************************************/
1318 int print_queue_snum(char *qname)
1320 int snum = lp_servicenumber(qname);
1321 if (snum == -1 || !lp_print_ok(snum)) return -1;
1326 /****************************************************************************
1328 ****************************************************************************/
1329 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
1334 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
1335 *errcode = WERR_ACCESS_DENIED;
1339 ret = (*(current_printif->queue_pause))(snum);
1342 *errcode = WERR_INVALID_PARAM;
1346 /* force update the database */
1347 print_cache_flush(snum);
1349 /* Send a printer notify message */
1351 printer_name = PRINTERNAME(snum);
1353 send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB);
1358 /****************************************************************************
1360 ****************************************************************************/
1361 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
1366 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
1367 *errcode = WERR_ACCESS_DENIED;
1371 ret = (*(current_printif->queue_resume))(snum);
1374 *errcode = WERR_INVALID_PARAM;
1378 /* make sure the database is up to date */
1379 if (print_cache_expired(snum)) print_queue_update(snum);
1381 /* Send a printer notify message */
1383 printer_name = PRINTERNAME(snum);
1385 send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB);
1390 /****************************************************************************
1391 purge a queue - implemented by deleting all jobs that we can delete
1392 ****************************************************************************/
1393 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
1395 print_queue_struct *queue;
1396 print_status_struct status;
1401 /* Force and update so the count is accurate (i.e. not a cached count) */
1402 print_queue_update(snum);
1404 can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
1405 njobs = print_queue_status(snum, &queue, &status);
1407 for (i=0;i<njobs;i++) {
1408 BOOL owner = is_owner(user, queue[i].job);
1410 if (owner || can_job_admin) {
1411 print_job_delete1(queue[i].job);
1417 /* Send a printer notify message */
1419 printer_name = PRINTERNAME(snum);
1421 send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB);