3 Unix SMB/Netbios implementation.
5 printing backend routines
6 Copyright (C) Andrew Tridgell 1992-2000
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 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 extern int DEBUGLEVEL;
28 the printing backend revolves around a tdb database that stores the
29 SMB view of the print queue
31 The key for this database is a jobid - a internally generated number that
32 uniquely identifies a print job
34 reading the print queue involves two steps:
35 - possibly running lpq and updating the internal database from that
36 - reading entries from the database
38 jobids are assigned when a job starts spooling.
42 pid_t pid; /* which process launched the job */
43 int sysjob; /* the system (lp) job number */
44 int fd; /* file descriptor of open file if open */
45 time_t starttime; /* when the job started spooling */
46 int status; /* the status of this job */
47 size_t size; /* the size of the job so far */
48 BOOL spooled; /* has it been sent to the spooler yet? */
49 BOOL smbjob; /* set if the job is a SMB job */
50 fstring filename; /* the filename used to spool the file */
51 fstring jobname; /* the job name given to us by the client */
52 fstring user; /* the user who started the job */
53 fstring qname; /* name of the print queue the job was sent to */
56 /* the open printing.tdb database */
57 static TDB_CONTEXT *tdb;
58 static pid_t local_pid;
60 #define PRINT_MAX_JOBID 10000
61 #define UNIX_JOB_START PRINT_MAX_JOBID
63 #define PRINT_SPOOL_PREFIX "smbprn."
64 #define PRINT_DATABASE_VERSION 2
66 static int get_queue_status(int, print_status_struct *);
68 /****************************************************************************
69 initialise the printing backend. Called once at startup.
70 Does not survive a fork
71 ****************************************************************************/
72 BOOL print_backend_init(void)
74 char *sversion = "INFO/version";
76 if (tdb && local_pid == sys_getpid()) return True;
77 tdb = tdb_open(lock_path("printing.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
79 DEBUG(0,("Failed to open printing backend database\n"));
81 local_pid = sys_getpid();
83 /* handle a Samba upgrade */
84 tdb_lock_bystring(tdb, sversion);
85 if (tdb_fetch_int(tdb, sversion) != PRINT_DATABASE_VERSION) {
86 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
87 tdb_store_int(tdb, sversion, PRINT_DATABASE_VERSION);
89 tdb_unlock_bystring(tdb, sversion);
91 return nt_printing_init();
94 /****************************************************************************
95 useful function to generate a tdb key
96 ****************************************************************************/
97 static TDB_DATA print_key(int jobid)
103 ret.dptr = (void *)&j;
104 ret.dsize = sizeof(j);
108 /****************************************************************************
109 useful function to find a print job in the database
110 ****************************************************************************/
111 static struct printjob *print_job_find(int jobid)
113 static struct printjob pjob;
116 ret = tdb_fetch(tdb, print_key(jobid));
117 if (!ret.dptr || ret.dsize != sizeof(pjob)) return NULL;
119 memcpy(&pjob, ret.dptr, sizeof(pjob));
124 /****************************************************************************
125 store a job structure back to the database
126 ****************************************************************************/
127 static BOOL print_job_store(int jobid, struct printjob *pjob)
130 d.dptr = (void *)pjob;
131 d.dsize = sizeof(*pjob);
133 return (tdb_store(tdb, print_key(jobid), d, TDB_REPLACE) == 0);
136 /****************************************************************************
137 run a given print command
138 a null terminated list of value/substitute pairs is provided
139 for local substitution strings
140 ****************************************************************************/
141 static int print_run_command(int snum,char *command,
150 if (!command || !*command) return -1;
152 if (!VALID_SNUM(snum)) {
153 DEBUG(0,("Invalid snum %d for command %s\n", snum, command));
157 pstrcpy(syscmd, command);
159 va_start(ap, outfile);
160 while ((arg = va_arg(ap, char *))) {
161 char *value = va_arg(ap,char *);
162 pstring_sub(syscmd, arg, value);
166 p = PRINTERNAME(snum);
168 pstring_sub(syscmd, "%p", p);
169 standard_sub_snum(snum,syscmd);
171 /* Convert script args to unix-codepage */
172 dos_to_unix(syscmd, True);
173 ret = smbrun(syscmd,outfile,False);
175 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
181 /****************************************************************************
182 parse a file name from the system spooler to generate a jobid
183 ****************************************************************************/
184 static int print_parse_jobid(char *fname)
188 if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0) return -1;
189 fname += strlen(PRINT_SPOOL_PREFIX);
192 if (jobid <= 0) return -1;
198 /****************************************************************************
199 list a unix job in the print database
200 ****************************************************************************/
201 static void print_unix_job(int snum, print_queue_struct *q)
203 int jobid = q->job + UNIX_JOB_START;
204 struct printjob pj, *old_pj;
206 /* Preserve the timestamp on an existing unix print job */
208 old_pj = print_job_find(jobid);
215 pj.starttime = old_pj ? old_pj->starttime : q->time;
216 pj.status = q->status;
220 fstrcpy(pj.filename, "");
221 fstrcpy(pj.jobname, q->file);
222 fstrcpy(pj.user, q->user);
223 fstrcpy(pj.qname, lp_servicename(snum));
225 print_job_store(jobid, &pj);
229 struct traverse_struct {
230 print_queue_struct *queue;
231 int qcount, snum, maxcount, total_jobs;
234 /* utility fn to delete any jobs that are no longer active */
235 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
237 struct traverse_struct *ts = (struct traverse_struct *)state;
238 struct printjob pjob;
241 if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
242 memcpy(&jobid, key.dptr, sizeof(jobid));
243 memcpy(&pjob, data.dptr, sizeof(pjob));
245 if (strcmp(lp_servicename(ts->snum), pjob.qname)) {
246 /* this isn't for the queue we are looking at */
252 /* remove a unix job if it isn't in the system queue any more */
254 for (i=0;i<ts->qcount;i++) {
255 if (jobid == ts->queue[i].job + UNIX_JOB_START) break;
258 tdb_delete(tdb, key);
264 /* maybe it hasn't been spooled yet */
266 /* if a job is not spooled and the process doesn't
267 exist then kill it. This cleans up after smbd
269 if (!process_exists(pjob.pid))
270 tdb_delete(tdb, key);
276 for (i=0;i<ts->qcount;i++) {
277 int qid = print_parse_jobid(ts->queue[i].file);
278 if (jobid == qid) break;
281 /* The job isn't in the system queue - we have to assume it has
282 completed, so delete the database entry. */
284 if (i == ts->qcount) {
285 time_t cur_t = time(NULL);
287 /* A race can occur between the time a job is spooled and
288 when it appears in the lpq output. This happens when
289 the job is added to printing.tdb when another smbd
290 running print_queue_update() has completed a lpq and
291 is currently traversing the printing tdb and deleting jobs.
292 A workaround is to not delete the job if it has been
293 submitted less than lp_lpqcachetime() seconds ago. */
295 if ((cur_t - pjob.starttime) > lp_lpqcachetime())
306 /****************************************************************************
307 check if the print queue has been updated recently enough
308 ****************************************************************************/
309 static void print_cache_flush(int snum)
312 slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum));
313 dos_to_unix(key, True); /* Convert key to unix-codepage */
314 tdb_store_int(tdb, key, -1);
317 /****************************************************************************
318 update the internal database from the system print queue for a queue
319 ****************************************************************************/
320 static void print_queue_update(int snum)
322 char *path = lp_pathname(snum);
323 char *cmd = lp_lpqcommand(snum);
326 int numlines, i, qcount;
327 print_queue_struct *queue = NULL;
328 print_status_struct status;
329 print_status_struct old_status;
330 struct printjob *pjob;
331 struct traverse_struct tstruct;
332 fstring keystr, printer_name;
335 /* Convert printer name (i.e. share name) to unix-codepage for all of the
336 * following tdb key generation */
337 fstrcpy(printer_name, lp_servicename(snum));
338 dos_to_unix(printer_name, True);
341 * Update the cache time FIRST ! Stops others doing this
342 * if the lpq takes a long time.
345 slprintf(keystr, sizeof(keystr), "CACHE/%s", printer_name);
346 tdb_store_int(tdb, keystr, (int)time(NULL));
348 slprintf(tmp_file, sizeof(tmp_file), "%s/smblpq.%d", path, local_pid);
351 print_run_command(snum, cmd, tmp_file, NULL);
354 qlines = file_lines_load(tmp_file, &numlines, True);
357 /* turn the lpq output into a series of job structures */
361 queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(numlines+1));
364 for (i=0; i<numlines; i++) {
366 if (parse_lpq_entry(snum,qlines[i],
367 &queue[qcount],&status,qcount==0)) {
372 file_lines_free(qlines);
374 DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
375 "s" : "", printer_name));
377 /* Lock the queue for the database update */
379 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
380 tdb_lock_bystring(tdb, keystr);
383 any job in the internal database that is marked as spooled
384 and doesn't exist in the system queue is considered finished
385 and removed from the database
387 any job in the system database but not in the internal database
388 is added as a unix job
390 fill in any system job numbers as we go
392 for (i=0; i<qcount; i++) {
393 int jobid = print_parse_jobid(queue[i].file);
396 /* assume its a unix print job */
397 print_unix_job(snum, &queue[i]);
401 /* we have an active SMB print job - update its status */
402 pjob = print_job_find(jobid);
404 /* err, somethings wrong. Probably smbd was restarted
405 with jobs in the queue. All we can do is treat them
406 like unix jobs. Pity. */
407 print_unix_job(snum, &queue[i]);
411 pjob->sysjob = queue[i].job;
412 pjob->status = queue[i].status;
414 print_job_store(jobid, pjob);
417 /* now delete any queued entries that don't appear in the
419 tstruct.queue = queue;
420 tstruct.qcount = qcount;
422 tstruct.total_jobs = 0;
424 tdb_traverse(tdb, traverse_fn_delete, (void *)&tstruct);
426 safe_free(tstruct.queue);
428 tdb_store_int(tdb, "INFO/total_jobs", tstruct.total_jobs);
431 * Get the old print status. We will use this to compare the
432 * number of jobs. If they have changed we need to send a
433 * "changed" message to the smbds.
436 if( qcount != get_queue_status(snum, &old_status)) {
437 DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
438 old_status.qcount, qcount, printer_name ));
439 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
442 /* store the new queue status structure */
443 slprintf(keystr, sizeof(keystr), "STATUS/%s", printer_name);
445 key.dsize = strlen(keystr);
447 status.qcount = qcount;
448 data.dptr = (void *)&status;
449 data.dsize = sizeof(status);
450 tdb_store(tdb, key, data, TDB_REPLACE);
452 /* Unlock for database update */
454 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
455 tdb_unlock_bystring(tdb, keystr);
458 * Update the cache time again. We want to do this call
459 * as little as possible...
462 slprintf(keystr, sizeof(keystr), "CACHE/%s", printer_name);
463 tdb_store_int(tdb, keystr, (int)time(NULL));
466 /****************************************************************************
467 check if a jobid is valid. It is valid if it exists in the database
468 ****************************************************************************/
469 BOOL print_job_exists(int jobid)
471 return tdb_exists(tdb, print_key(jobid));
475 /****************************************************************************
476 work out which service a jobid is for
477 note that we have to look up by queue name to ensure that it works for
478 other than the process that started the job
479 ****************************************************************************/
480 int print_job_snum(int jobid)
482 struct printjob *pjob = print_job_find(jobid);
483 if (!pjob) return -1;
485 return lp_servicenumber(pjob->qname);
488 /****************************************************************************
489 give the fd used for a jobid
490 ****************************************************************************/
491 int print_job_fd(int jobid)
493 struct printjob *pjob = print_job_find(jobid);
494 if (!pjob) return -1;
495 /* don't allow another process to get this info - it is meaningless */
496 if (pjob->pid != local_pid) return -1;
500 /****************************************************************************
501 give the filename used for a jobid
502 only valid for the process doing the spooling and when the job
504 ****************************************************************************/
505 char *print_job_fname(int jobid)
507 struct printjob *pjob = print_job_find(jobid);
508 if (!pjob || pjob->spooled || pjob->pid != local_pid) return NULL;
509 return pjob->filename;
513 /****************************************************************************
514 set the place in the queue for a job
515 ****************************************************************************/
516 BOOL print_job_set_place(int jobid, int place)
518 DEBUG(2,("print_job_set_place not implemented yet\n"));
522 /****************************************************************************
523 set the name of a job. Only possible for owner
524 ****************************************************************************/
525 BOOL print_job_set_name(int jobid, char *name)
527 struct printjob *pjob = print_job_find(jobid);
528 if (!pjob || pjob->pid != local_pid) return False;
530 fstrcpy(pjob->jobname, name);
531 return print_job_store(jobid, pjob);
535 /****************************************************************************
536 delete a print job - don't update queue
537 ****************************************************************************/
538 static BOOL print_job_delete1(int jobid)
540 struct printjob *pjob = print_job_find(jobid);
541 int snum, result = 0;
543 if (!pjob) return False;
545 snum = print_job_snum(jobid);
547 /* Hrm - we need to be able to cope with deleting a job before it
548 has reached the spooler. */
550 if (pjob->sysjob == -1) {
551 DEBUG(5, ("attempt to delete job %d not seen by lpr\n",
555 if (pjob->spooled && pjob->sysjob != -1) {
558 /* need to delete the spooled entry */
559 slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob);
560 result = print_run_command(
562 lp_lprmcommand(snum), NULL,
564 "%T", http_timestring(pjob->starttime),
568 /* Delete the tdb entry if the delete suceeded or the job hasn't
572 tdb_delete(tdb, print_key(jobid));
575 return (result == 0);
578 /****************************************************************************
579 return true if the current user owns the print job
580 ****************************************************************************/
581 static BOOL is_owner(struct current_user *user, int jobid)
583 struct printjob *pjob = print_job_find(jobid);
586 if (!pjob || !user) return False;
588 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
589 return strequal(pjob->user, vuser->user.smb_name);
591 return strequal(pjob->user, uidtoname(user->uid));
595 /****************************************************************************
597 ****************************************************************************/
598 BOOL print_job_delete(struct current_user *user, int jobid, int *errcode)
600 int snum = print_job_snum(jobid);
604 owner = is_owner(user, jobid);
606 /* Check access against security descriptor or whether the user
610 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
611 DEBUG(3, ("delete denied by security descriptor\n"));
612 *errcode = ERROR_ACCESS_DENIED;
616 if (!print_job_delete1(jobid)) return False;
618 /* force update the database and say the delete failed if the
621 print_queue_update(snum);
623 /* Send a printer notify message */
625 printer_name = PRINTERNAME(snum);
627 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
629 return !print_job_exists(jobid);
633 /****************************************************************************
635 ****************************************************************************/
636 BOOL print_job_pause(struct current_user *user, int jobid, int *errcode)
638 struct printjob *pjob = print_job_find(jobid);
644 if (!pjob || !user) return False;
646 if (!pjob->spooled || pjob->sysjob == -1) return False;
648 snum = print_job_snum(jobid);
649 owner = is_owner(user, jobid);
652 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
653 DEBUG(3, ("pause denied by security descriptor\n"));
654 *errcode = ERROR_ACCESS_DENIED;
658 /* need to pause the spooled entry */
659 slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob);
660 ret = print_run_command(snum,
661 lp_lppausecommand(snum), NULL,
666 *errcode = ERROR_INVALID_PARAMETER;
670 /* force update the database */
671 print_cache_flush(snum);
673 /* Send a printer notify message */
675 printer_name = PRINTERNAME(snum);
677 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
679 /* how do we tell if this succeeded? */
684 /****************************************************************************
686 ****************************************************************************/
687 BOOL print_job_resume(struct current_user *user, int jobid, int *errcode)
689 struct printjob *pjob = print_job_find(jobid);
695 if (!pjob || !user) return False;
697 if (!pjob->spooled || pjob->sysjob == -1) return False;
699 snum = print_job_snum(jobid);
700 owner = is_owner(user, jobid);
702 if (!is_owner(user, jobid) &&
703 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
704 DEBUG(3, ("resume denied by security descriptor\n"));
705 *errcode = ERROR_ACCESS_DENIED;
709 slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob);
710 ret = print_run_command(snum,
711 lp_lpresumecommand(snum), NULL,
716 *errcode = ERROR_INVALID_PARAMETER;
720 /* force update the database */
721 print_cache_flush(snum);
723 /* Send a printer notify message */
725 printer_name = PRINTERNAME(snum);
727 message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
732 /****************************************************************************
733 write to a print file
734 ****************************************************************************/
735 int print_job_write(int jobid, const char *buf, int size)
739 fd = print_job_fd(jobid);
740 if (fd == -1) return -1;
742 return write(fd, buf, size);
745 /****************************************************************************
746 Check if the print queue has been updated recently enough.
747 ****************************************************************************/
749 static BOOL print_cache_expired(int snum)
752 time_t t2, t = time(NULL);
754 slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum));
755 dos_to_unix(key, True); /* Convert key to unix-codepage */
756 t2 = tdb_fetch_int(tdb, key);
757 if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) {
758 DEBUG(3, ("print cache expired\n"));
764 /****************************************************************************
765 Get the queue status - do not update if db is out of date.
766 ****************************************************************************/
767 static int get_queue_status(int snum, print_status_struct *status)
772 ZERO_STRUCTP(status);
773 slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum));
774 dos_to_unix(keystr, True); /* Convert key to unix-codepage */
776 key.dsize = strlen(keystr);
777 data = tdb_fetch(tdb, key);
779 if (data.dsize == sizeof(print_status_struct)) {
780 memcpy(status, data.dptr, sizeof(print_status_struct));
784 return status->qcount;
787 /****************************************************************************
788 Determine the number of jobs in a queue.
789 ****************************************************************************/
790 static int print_queue_length(int snum)
792 print_status_struct status;
794 /* make sure the database is up to date */
795 if (print_cache_expired(snum)) print_queue_update(snum);
797 /* also fetch the queue status */
798 return get_queue_status(snum, &status);
801 /****************************************************************************
802 Determine the number of jobs in all queues.
803 ****************************************************************************/
804 static int get_total_jobs(int snum)
808 /* make sure the database is up to date */
809 if (print_cache_expired(snum)) print_queue_update(snum);
811 total_jobs = tdb_fetch_int(tdb, "INFO/total_jobs");
818 /***************************************************************************
819 start spooling a job - return the jobid
820 ***************************************************************************/
821 int print_job_start(struct current_user *user, int snum, char *jobname)
825 struct printjob pjob;
831 if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
832 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
836 if (!print_time_access_check(snum)) {
837 DEBUG(3, ("print_job_start: job start denied by time check\n"));
841 path = lp_pathname(snum);
843 /* see if we have sufficient disk space */
844 if (lp_minprintspace(snum)) {
845 SMB_BIG_UINT dspace, dsize;
846 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
847 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
853 /* for autoloaded printers, check that the printcap entry still exists */
854 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_servicename(snum), NULL)) {
859 /* Insure the maximum queue size is not violated */
860 if (lp_maxprintjobs(snum) && print_queue_length(snum) > lp_maxprintjobs(snum)) {
865 /* Insure the maximum print jobs in the system is not violated */
866 if (lp_totalprintjobs() && get_total_jobs(snum) > lp_totalprintjobs()) {
871 /* create the database entry */
873 pjob.pid = local_pid;
876 pjob.starttime = time(NULL);
877 pjob.status = LPQ_QUEUED;
879 pjob.spooled = False;
882 fstrcpy(pjob.jobname, jobname);
884 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
885 fstrcpy(pjob.user, vuser->user.smb_name);
887 fstrcpy(pjob.user, uidtoname(user->uid));
890 fstrcpy(pjob.qname, lp_servicename(snum));
892 /* lock the database */
893 tdb_lock_bystring(tdb, "INFO/nextjob");
896 next_jobid = tdb_fetch_int(tdb, "INFO/nextjob");
897 if (next_jobid == -1) next_jobid = 1;
899 for (jobid = next_jobid+1; jobid != next_jobid; ) {
900 if (!print_job_exists(jobid)) break;
901 jobid = (jobid + 1) % PRINT_MAX_JOBID;
902 if (jobid == 0) jobid = 1;
904 if (jobid == next_jobid || !print_job_store(jobid, &pjob)) {
909 tdb_store_int(tdb, "INFO/nextjob", jobid);
911 /* we have a job entry - now create the spool file
913 we unlink first to cope with old spool files and also to beat
914 a symlink security hole - it allows us to use O_EXCL
915 There may be old spool files owned by other users lying around.
917 slprintf(pjob.filename, sizeof(pjob.filename), "%s/%s%d",
918 path, PRINT_SPOOL_PREFIX, jobid);
919 if (unlink(pjob.filename) == -1 && errno != ENOENT) {
922 pjob.fd = sys_open(pjob.filename,O_WRONLY|O_CREAT|O_EXCL,0600);
923 if (pjob.fd == -1) goto fail;
925 print_job_store(jobid, &pjob);
927 tdb_unlock_bystring(tdb, "INFO/nextjob");
930 * If the printer is marked as postscript output a leading
931 * file identifier to ensure the file is treated as a raw
933 * This has a similar effect as CtrlD=0 in WIN.INI file.
934 * tim@fsg.com 09/06/94
936 if (lp_postscript(snum)) {
937 print_job_write(jobid, "%!\n",3);
944 tdb_delete(tdb, print_key(jobid));
947 tdb_unlock_bystring(tdb, "INFO/nextjob");
951 /****************************************************************************
952 Print a file - called on closing the file. This spools the job.
953 If normal close is false then we're tearing down the jobs - treat as an
955 ****************************************************************************/
957 BOOL print_job_end(int jobid, BOOL normal_close)
959 struct printjob *pjob = print_job_find(jobid);
961 SMB_STRUCT_STAT sbuf;
962 pstring current_directory;
963 pstring print_directory;
970 if (pjob->spooled || pjob->pid != local_pid)
973 snum = print_job_snum(jobid);
975 if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
976 pjob->size = sbuf.st_size;
982 * Not a normal close or we couldn't stat the job file,
983 * so something has gone wrong. Cleanup.
986 unlink(pjob->filename);
987 tdb_delete(tdb, print_key(jobid));
991 if (pjob->size == 0) {
992 /* don't bother spooling empty files */
993 unlink(pjob->filename);
994 tdb_delete(tdb, print_key(jobid));
998 /* we print from the directory path to give the best chance of
999 parsing the lpq output */
1000 wd = sys_getwd(current_directory);
1004 pstrcpy(print_directory, pjob->filename);
1005 p = strrchr(print_directory,'/');
1010 if (chdir(print_directory) != 0)
1013 pstrcpy(jobname, pjob->jobname);
1014 pstring_sub(jobname, "'", "_");
1016 /* send it to the system spooler */
1017 ret = print_run_command(snum,
1018 lp_printcommand(snum), NULL,
1027 /* The print job has been sucessfully handed over to the back-end */
1029 pjob->spooled = True;
1030 print_job_store(jobid, pjob);
1032 /* make sure the database is up to date */
1033 if (print_cache_expired(snum)) print_queue_update(snum);
1037 /* The print job was not succesfully started. Cleanup */
1038 /* Still need to add proper error return propagation! 010122:JRR */
1039 unlink(pjob->filename);
1040 tdb_delete(tdb, print_key(jobid));
1045 /* utility fn to enumerate the print queue */
1046 static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
1048 struct traverse_struct *ts = (struct traverse_struct *)state;
1049 struct printjob pjob;
1052 if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
1053 memcpy(&jobid, key.dptr, sizeof(jobid));
1054 memcpy(&pjob, data.dptr, sizeof(pjob));
1056 /* maybe it isn't for this queue */
1057 if (ts->snum != print_queue_snum(pjob.qname)) return 0;
1059 if (ts->qcount >= ts->maxcount) return 0;
1063 ts->queue[i].job = jobid;
1064 ts->queue[i].size = pjob.size;
1065 ts->queue[i].status = pjob.status;
1066 ts->queue[i].priority = 1;
1067 ts->queue[i].time = pjob.starttime;
1068 fstrcpy(ts->queue[i].user, pjob.user);
1069 fstrcpy(ts->queue[i].file, pjob.jobname);
1076 struct traverse_count_struct {
1080 /* utility fn to count the number of entries in the print queue */
1081 static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
1083 struct traverse_count_struct *ts = (struct traverse_count_struct *)state;
1084 struct printjob pjob;
1087 if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
1088 memcpy(&jobid, key.dptr, sizeof(jobid));
1089 memcpy(&pjob, data.dptr, sizeof(pjob));
1091 /* maybe it isn't for this queue */
1092 if (ts->snum != print_queue_snum(pjob.qname)) return 0;
1099 /* Sort print jobs by submittal time */
1101 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1105 if (!j1 && !j2) return 0;
1109 /* Sort on job start time */
1111 if (j1->time == j2->time) return 0;
1112 return (j1->time > j2->time) ? 1 : -1;
1115 /****************************************************************************
1116 get a printer queue listing
1117 ****************************************************************************/
1118 int print_queue_status(int snum,
1119 print_queue_struct **queue,
1120 print_status_struct *status)
1122 struct traverse_struct tstruct;
1123 struct traverse_count_struct tsc;
1127 /* make sure the database is up to date */
1128 if (print_cache_expired(snum)) print_queue_update(snum);
1133 * Fetch the queue status. We must do this first, as there may
1134 * be no jobs in the queue.
1136 ZERO_STRUCTP(status);
1137 slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum));
1138 dos_to_unix(keystr, True); /* Convert key to unix-codepage */
1140 key.dsize = strlen(keystr);
1141 data = tdb_fetch(tdb, key);
1143 if (data.dsize == sizeof(*status)) {
1144 memcpy(status, data.dptr, sizeof(*status));
1150 * Now, fetch the print queue information. We first count the number
1151 * of entries, and then only retrieve the queue if necessary.
1156 tdb_traverse(tdb, traverse_count_fn_queue, (void *)&tsc);
1161 /* Allocate the queue size. */
1162 if ((tstruct.queue = (print_queue_struct *)
1163 malloc(sizeof(print_queue_struct)*tsc.count))
1168 * Fill in the queue.
1169 * We need maxcount as the queue size may have changed between
1170 * the two calls to tdb_traverse.
1173 tstruct.maxcount = tsc.count;
1174 tstruct.snum = snum;
1176 tdb_traverse(tdb, traverse_fn_queue, (void *)&tstruct);
1178 /* Sort the queue by submission time otherwise they are displayed
1181 qsort(tstruct.queue, tstruct.qcount, sizeof(print_queue_struct),
1182 QSORT_CAST(printjob_comp));
1184 *queue = tstruct.queue;
1185 return tstruct.qcount;
1189 /****************************************************************************
1190 turn a queue name into a snum
1191 ****************************************************************************/
1192 int print_queue_snum(char *qname)
1194 int snum = lp_servicenumber(qname);
1195 if (snum == -1 || !lp_print_ok(snum)) return -1;
1200 /****************************************************************************
1202 ****************************************************************************/
1203 BOOL print_queue_pause(struct current_user *user, int snum, int *errcode)
1208 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
1209 *errcode = ERROR_ACCESS_DENIED;
1213 ret = print_run_command(snum, lp_queuepausecommand(snum), NULL,
1217 *errcode = ERROR_INVALID_PARAMETER;
1221 /* force update the database */
1222 print_cache_flush(snum);
1224 /* Send a printer notify message */
1226 printer_name = PRINTERNAME(snum);
1228 message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
1233 /****************************************************************************
1235 ****************************************************************************/
1236 BOOL print_queue_resume(struct current_user *user, int snum, int *errcode)
1241 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
1242 *errcode = ERROR_ACCESS_DENIED;
1246 ret = print_run_command(snum, lp_queueresumecommand(snum), NULL,
1250 *errcode = ERROR_INVALID_PARAMETER;
1254 /* make sure the database is up to date */
1255 if (print_cache_expired(snum)) print_queue_update(snum);
1257 /* Send a printer notify message */
1259 printer_name = PRINTERNAME(snum);
1261 message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
1266 /****************************************************************************
1267 purge a queue - implemented by deleting all jobs that we can delete
1268 ****************************************************************************/
1269 BOOL print_queue_purge(struct current_user *user, int snum, int *errcode)
1271 print_queue_struct *queue;
1272 print_status_struct status;
1277 /* Force and update so the count is accurate (i.e. not a cached count) */
1278 print_queue_update(snum);
1280 can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
1281 njobs = print_queue_status(snum, &queue, &status);
1283 for (i=0;i<njobs;i++) {
1284 BOOL owner = is_owner(user, queue[i].job);
1286 if (owner || can_job_admin) {
1287 print_job_delete1(queue[i].job);
1293 /* Send a printer notify message */
1295 printer_name = PRINTERNAME(snum);
1297 message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);