2 Unix SMB/Netbios implementation.
4 printing backend routines
5 Copyright (C) Andrew Tridgell 1992-2000
6 Copyright (C) Jeremy Allison 2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 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 /* Current printer interface */
26 static struct printif
*current_printif
= &generic_printif
;
27 static BOOL
remove_from_jobs_changed(int snum
, uint32 jobid
);
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 /***************************************************************************
44 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
45 bit RPC jobids.... JRA.
46 ***************************************************************************/
48 static TDB_CONTEXT
*rap_tdb
;
49 static uint16 next_rap_jobid
;
51 uint16
pjobid_to_rap(int snum
, uint32 jobid
)
57 DEBUG(10,("pjobid_to_rap: called.\n"));
60 /* Create the in-memory tdb. */
61 rap_tdb
= tdb_open_log(NULL
, 0, TDB_INTERNAL
, (O_RDWR
|O_CREAT
), 0644);
66 SIVAL(&jinfo
,0,(int32
)snum
);
67 SIVAL(&jinfo
,4,jobid
);
69 key
.dptr
= (char *)&jinfo
;
70 key
.dsize
= sizeof(jinfo
);
71 data
= tdb_fetch(rap_tdb
, key
);
72 if (data
.dptr
&& data
.dsize
== sizeof(uint16
)) {
73 memcpy(&rap_jobid
, data
.dptr
, sizeof(uint16
));
75 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
77 (unsigned int)rap_jobid
));
81 /* Not found - create and store mapping. */
82 rap_jobid
= ++next_rap_jobid
;
84 rap_jobid
= ++next_rap_jobid
;
85 data
.dptr
= (char *)&rap_jobid
;
86 data
.dsize
= sizeof(rap_jobid
);
87 tdb_store(rap_tdb
, key
, data
, TDB_REPLACE
);
88 tdb_store(rap_tdb
, data
, key
, TDB_REPLACE
);
90 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
92 (unsigned int)rap_jobid
));
96 BOOL
rap_to_pjobid(uint16 rap_jobid
, int *psnum
, uint32
*pjobid
)
100 DEBUG(10,("rap_to_pjobid called.\n"));
105 key
.dptr
= (char *)&rap_jobid
;
106 key
.dsize
= sizeof(rap_jobid
);
107 data
= tdb_fetch(rap_tdb
, key
);
108 if (data
.dptr
&& data
.dsize
== 8) {
109 *psnum
= IVAL(data
.dptr
,0);
110 *pjobid
= IVAL(data
.dptr
,4);
111 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
112 (unsigned int)*pjobid
,
113 (unsigned int)rap_jobid
));
114 SAFE_FREE(data
.dptr
);
118 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
119 (unsigned int)rap_jobid
));
120 SAFE_FREE(data
.dptr
);
124 static void rap_jobid_delete(int snum
, uint32 jobid
)
130 DEBUG(10,("rap_jobid_delete: called.\n"));
135 SIVAL(&jinfo
,0,(int32
)snum
);
136 SIVAL(&jinfo
,4,jobid
);
138 key
.dptr
= (char *)&jinfo
;
139 key
.dsize
= sizeof(jinfo
);
140 data
= tdb_fetch(rap_tdb
, key
);
141 if (!data
.dptr
|| (data
.dsize
!= sizeof(uint16
))) {
142 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
143 (unsigned int)jobid
));
144 SAFE_FREE(data
.dptr
);
148 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
149 (unsigned int)jobid
));
151 memcpy(&rap_jobid
, data
.dptr
, sizeof(uint16
));
152 SAFE_FREE(data
.dptr
);
153 data
.dptr
= (char *)&rap_jobid
;
154 data
.dsize
= sizeof(rap_jobid
);
155 tdb_delete(rap_tdb
, key
);
156 tdb_delete(rap_tdb
, data
);
159 static pid_t local_pid
;
161 static int get_queue_status(int, print_status_struct
*);
163 /****************************************************************************
164 Initialise the printing backend. Called once at startup before the fork().
165 ****************************************************************************/
167 BOOL
print_backend_init(void)
169 const char *sversion
= "INFO/version";
170 pstring printing_path
;
171 int services
= lp_numservices();
174 if (local_pid
== sys_getpid())
177 unlink(lock_path("printing.tdb"));
178 pstrcpy(printing_path
,lock_path("printing"));
179 mkdir(printing_path
,0755);
181 local_pid
= sys_getpid();
183 /* handle a Samba upgrade */
185 for (snum
= 0; snum
< services
; snum
++) {
186 struct tdb_print_db
*pdb
;
187 if (!lp_print_ok(snum
))
190 pdb
= get_print_db_byname(lp_const_servicename(snum
));
193 if (tdb_lock_bystring(pdb
->tdb
, sversion
, 0) == -1) {
194 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum
) ));
195 release_print_db(pdb
);
198 if (tdb_fetch_int32(pdb
->tdb
, sversion
) != PRINT_DATABASE_VERSION
) {
199 tdb_traverse(pdb
->tdb
, tdb_traverse_delete_fn
, NULL
);
200 tdb_store_int32(pdb
->tdb
, sversion
, PRINT_DATABASE_VERSION
);
202 tdb_unlock_bystring(pdb
->tdb
, sversion
);
203 release_print_db(pdb
);
206 close_all_print_db(); /* Don't leave any open. */
208 /* select the appropriate printing interface... */
210 if (strcmp(lp_printcapname(), "cups") == 0)
211 current_printif
= &cups_printif
;
212 #endif /* HAVE_CUPS */
214 /* do NT print initialization... */
215 return nt_printing_init();
218 /****************************************************************************
219 Shut down printing backend. Called once at shutdown to close the tdb.
220 ****************************************************************************/
222 void printing_end(void)
224 close_all_print_db(); /* Don't leave any open. */
227 /****************************************************************************
228 Useful function to generate a tdb key.
229 ****************************************************************************/
231 static TDB_DATA
print_key(uint32 jobid
)
237 ret
.dptr
= (void *)&j
;
238 ret
.dsize
= sizeof(j
);
242 /***********************************************************************
243 unpack a pjob from a tdb buffer
244 ***********************************************************************/
246 int unpack_pjob( char* buf
, int buflen
, struct printjob
*pjob
)
250 uint32 pjpid
, pjsysjob
, pjfd
, pjstarttime
, pjstatus
;
251 uint32 pjsize
, pjpage_count
, pjspooled
, pjsmbjob
;
256 len
+= tdb_unpack(buf
+len
, buflen
-len
, "dddddddddffff",
274 if ( (used
= unpack_devicemode(&pjob
->nt_devmode
, buf
+len
, buflen
-len
)) == -1 )
280 pjob
->sysjob
= pjsysjob
;
282 pjob
->starttime
= pjstarttime
;
283 pjob
->status
= pjstatus
;
285 pjob
->page_count
= pjpage_count
;
286 pjob
->spooled
= pjspooled
;
287 pjob
->smbjob
= pjsmbjob
;
293 /****************************************************************************
294 Useful function to find a print job in the database.
295 ****************************************************************************/
297 static struct printjob
*print_job_find(int snum
, uint32 jobid
)
299 static struct printjob pjob
;
301 struct tdb_print_db
*pdb
= get_print_db_byname(lp_const_servicename(snum
));
307 ret
= tdb_fetch(pdb
->tdb
, print_key(jobid
));
308 release_print_db(pdb
);
313 if ( pjob
.nt_devmode
)
314 free_nt_devicemode( &pjob
.nt_devmode
);
318 if ( unpack_pjob( ret
.dptr
, ret
.dsize
, &pjob
) == -1 ) {
327 /* Convert a unix jobid to a smb jobid */
329 static uint32 sysjob_to_jobid_value
;
331 static int unixjob_traverse_fn(TDB_CONTEXT
*the_tdb
, TDB_DATA key
,
332 TDB_DATA data
, void *state
)
334 struct printjob
*pjob
;
335 int *sysjob
= (int *)state
;
337 if (!data
.dptr
|| data
.dsize
== 0)
340 pjob
= (struct printjob
*)data
.dptr
;
341 if (key
.dsize
!= sizeof(uint32
))
344 if (*sysjob
== pjob
->sysjob
) {
345 uint32
*jobid
= (uint32
*)key
.dptr
;
347 sysjob_to_jobid_value
= *jobid
;
354 /****************************************************************************
355 This is a *horribly expensive call as we have to iterate through all the
356 current printer tdb's. Don't do this often ! JRA.
357 ****************************************************************************/
359 uint32
sysjob_to_jobid(int unix_jobid
)
361 int services
= lp_numservices();
364 sysjob_to_jobid_value
= (uint32
)-1;
366 for (snum
= 0; snum
< services
; snum
++) {
367 struct tdb_print_db
*pdb
;
368 if (!lp_print_ok(snum
))
370 pdb
= get_print_db_byname(lp_const_servicename(snum
));
372 tdb_traverse(pdb
->tdb
, unixjob_traverse_fn
, &unix_jobid
);
373 release_print_db(pdb
);
374 if (sysjob_to_jobid_value
!= (uint32
)-1)
375 return sysjob_to_jobid_value
;
380 /****************************************************************************
381 Send notifications based on what has changed after a pjob_store.
382 ****************************************************************************/
386 uint32 spoolss_status
;
387 } lpq_to_spoolss_status_map
[] = {
388 { LPQ_QUEUED
, JOB_STATUS_QUEUED
},
389 { LPQ_PAUSED
, JOB_STATUS_PAUSED
},
390 { LPQ_SPOOLING
, JOB_STATUS_SPOOLING
},
391 { LPQ_PRINTING
, JOB_STATUS_PRINTING
},
392 { LPQ_DELETING
, JOB_STATUS_DELETING
},
393 { LPQ_OFFLINE
, JOB_STATUS_OFFLINE
},
394 { LPQ_PAPEROUT
, JOB_STATUS_PAPEROUT
},
395 { LPQ_PRINTED
, JOB_STATUS_PRINTED
},
396 { LPQ_DELETED
, JOB_STATUS_DELETED
},
397 { LPQ_BLOCKED
, JOB_STATUS_BLOCKED
},
398 { LPQ_USER_INTERVENTION
, JOB_STATUS_USER_INTERVENTION
},
402 /* Convert a lpq status value stored in printing.tdb into the
403 appropriate win32 API constant. */
405 static uint32
map_to_spoolss_status(uint32 lpq_status
)
409 while (lpq_to_spoolss_status_map
[i
].lpq_status
!= -1) {
410 if (lpq_to_spoolss_status_map
[i
].lpq_status
== lpq_status
)
411 return lpq_to_spoolss_status_map
[i
].spoolss_status
;
418 static void pjob_store_notify(int snum
, uint32 jobid
, struct printjob
*old_data
,
419 struct printjob
*new_data
)
421 BOOL new_job
= False
;
426 /* Notify the job name first */
428 if (new_job
|| !strequal(old_data
->jobname
, new_data
->jobname
))
429 notify_job_name(snum
, jobid
, new_data
->jobname
);
431 /* Job attributes that can't be changed. We only send
432 notification for these on a new job. */
435 notify_job_submitted(snum
, jobid
, new_data
->starttime
);
436 notify_job_username(snum
, jobid
, new_data
->user
);
439 /* Job attributes of a new job or attributes that can be
442 if (new_job
|| old_data
->status
!= new_data
->status
)
443 notify_job_status(snum
, jobid
, map_to_spoolss_status(new_data
->status
));
445 if (new_job
|| old_data
->size
!= new_data
->size
)
446 notify_job_total_bytes(snum
, jobid
, new_data
->size
);
448 if (new_job
|| old_data
->page_count
!= new_data
->page_count
)
449 notify_job_total_pages(snum
, jobid
, new_data
->page_count
);
452 /****************************************************************************
453 Store a job structure back to the database.
454 ****************************************************************************/
456 static BOOL
pjob_store(int snum
, uint32 jobid
, struct printjob
*pjob
)
458 TDB_DATA old_data
, new_data
;
460 struct tdb_print_db
*pdb
= get_print_db_byname(lp_const_servicename(snum
));
462 int len
, newlen
, buflen
;
470 old_data
= tdb_fetch(pdb
->tdb
, print_key(jobid
));
472 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
479 len
+= tdb_pack(buf
+len
, buflen
-len
, "dddddddddffff",
481 (uint32
)pjob
->sysjob
,
483 (uint32
)pjob
->starttime
,
484 (uint32
)pjob
->status
,
486 (uint32
)pjob
->page_count
,
487 (uint32
)pjob
->spooled
,
488 (uint32
)pjob
->smbjob
,
494 len
+= pack_devicemode(pjob
->nt_devmode
, buf
+len
, buflen
-len
);
499 tb
= (char *)Realloc(buf
, len
);
501 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
508 } while ( buflen
!= len
);
514 new_data
.dsize
= len
;
515 ret
= (tdb_store(pdb
->tdb
, print_key(jobid
), new_data
, TDB_REPLACE
) == 0);
517 release_print_db(pdb
);
519 /* Send notify updates for what has changed */
521 if ( ret
&& (old_data
.dsize
== 0 || old_data
.dsize
== sizeof(*pjob
)) )
522 pjob_store_notify( snum
, jobid
, (struct printjob
*)old_data
.dptr
, pjob
);
525 SAFE_FREE( old_data
.dptr
);
531 /****************************************************************************
532 Remove a job structure from the database.
533 ****************************************************************************/
535 void pjob_delete(int snum
, uint32 jobid
)
537 struct printjob
*pjob
= print_job_find(snum
, jobid
);
538 uint32 job_status
= 0;
539 struct tdb_print_db
*pdb
= get_print_db_byname(lp_const_servicename(snum
));
545 DEBUG(5, ("pjob_delete(): we were asked to delete nonexistent job %u\n",
546 (unsigned int)jobid
));
547 release_print_db(pdb
);
551 /* Send a notification that a job has been deleted */
553 job_status
= map_to_spoolss_status(pjob
->status
);
555 /* We must cycle through JOB_STATUS_DELETING and
556 JOB_STATUS_DELETED for the port monitor to delete the job
559 job_status
|= JOB_STATUS_DELETING
;
560 notify_job_status(snum
, jobid
, job_status
);
562 job_status
|= JOB_STATUS_DELETED
;
563 notify_job_status(snum
, jobid
, job_status
);
565 /* Remove from printing.tdb */
567 tdb_delete(pdb
->tdb
, print_key(jobid
));
568 release_print_db(pdb
);
569 rap_jobid_delete(snum
, jobid
);
572 /****************************************************************************
573 Parse a file name from the system spooler to generate a jobid.
574 ****************************************************************************/
576 static uint32
print_parse_jobid(char *fname
)
580 if (strncmp(fname
,PRINT_SPOOL_PREFIX
,strlen(PRINT_SPOOL_PREFIX
)) != 0)
582 fname
+= strlen(PRINT_SPOOL_PREFIX
);
588 return (uint32
)jobid
;
591 /****************************************************************************
592 List a unix job in the print database.
593 ****************************************************************************/
595 static void print_unix_job(int snum
, print_queue_struct
*q
, uint32 jobid
)
597 struct printjob pj
, *old_pj
;
599 if (jobid
== (uint32
)-1)
600 jobid
= q
->job
+ UNIX_JOB_START
;
602 /* Preserve the timestamp on an existing unix print job */
604 old_pj
= print_job_find(snum
, jobid
);
611 pj
.starttime
= old_pj
? old_pj
->starttime
: q
->time
;
612 pj
.status
= q
->status
;
615 pj
.smbjob
= (old_pj
!= NULL
? True
: False
);
616 fstrcpy(pj
.filename
, old_pj
? old_pj
->filename
: "");
617 if (jobid
< UNIX_JOB_START
)
618 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: "Remote Downlevel Document");
620 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: q
->fs_file
);
621 fstrcpy(pj
.user
, old_pj
? old_pj
->user
: q
->fs_user
);
622 fstrcpy(pj
.queuename
, old_pj
? old_pj
->queuename
: lp_const_servicename(snum
));
624 pjob_store(snum
, jobid
, &pj
);
628 struct traverse_struct
{
629 print_queue_struct
*queue
;
630 int qcount
, snum
, maxcount
, total_jobs
;
634 /****************************************************************************
635 Utility fn to delete any jobs that are no longer active.
636 ****************************************************************************/
638 static int traverse_fn_delete(TDB_CONTEXT
*t
, TDB_DATA key
, TDB_DATA data
, void *state
)
640 struct traverse_struct
*ts
= (struct traverse_struct
*)state
;
641 struct printjob pjob
;
645 if ( key
.dsize
!= sizeof(jobid
) )
648 memcpy(&jobid
, key
.dptr
, sizeof(jobid
));
649 if ( unpack_pjob( data
.dptr
, data
.dsize
, &pjob
) == -1 )
651 free_nt_devicemode( &pjob
.nt_devmode
);
654 if (ts
->snum
!= lp_servicenumber(pjob
.queuename
)) {
655 /* this isn't for the queue we are looking at - this cannot happen with the split tdb's. JRA */
660 /* remove a unix job if it isn't in the system queue any more */
662 for (i
=0;i
<ts
->qcount
;i
++) {
663 uint32 u_jobid
= (ts
->queue
[i
].job
+ UNIX_JOB_START
);
664 if (jobid
== u_jobid
)
667 if (i
== ts
->qcount
) {
668 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
669 (unsigned int)jobid
));
670 pjob_delete(ts
->snum
, jobid
);
676 /* maybe it hasn't been spooled yet */
678 /* if a job is not spooled and the process doesn't
679 exist then kill it. This cleans up after smbd
681 if (!process_exists(pjob
.pid
)) {
682 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
683 (unsigned int)jobid
, (unsigned int)pjob
.pid
));
684 pjob_delete(ts
->snum
, jobid
);
690 for (i
=0;i
<ts
->qcount
;i
++) {
691 uint32 curr_jobid
= print_parse_jobid(ts
->queue
[i
].fs_file
);
692 if (jobid
== curr_jobid
)
696 /* The job isn't in the system queue - we have to assume it has
697 completed, so delete the database entry. */
699 if (i
== ts
->qcount
) {
701 /* A race can occur between the time a job is spooled and
702 when it appears in the lpq output. This happens when
703 the job is added to printing.tdb when another smbd
704 running print_queue_update() has completed a lpq and
705 is currently traversing the printing tdb and deleting jobs.
706 Don't delete the job if it was submitted after the lpq_time. */
708 if (pjob
.starttime
< ts
->lpq_time
) {
709 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
711 (unsigned int)pjob
.starttime
,
712 (unsigned int)ts
->lpq_time
));
713 pjob_delete(ts
->snum
, jobid
);
719 /* Save the pjob attributes we will store. */
720 ts
->queue
[i
].job
= jobid
;
721 ts
->queue
[i
].size
= pjob
.size
;
722 ts
->queue
[i
].page_count
= pjob
.page_count
;
723 ts
->queue
[i
].status
= pjob
.status
;
724 ts
->queue
[i
].priority
= 1;
725 ts
->queue
[i
].time
= pjob
.starttime
;
726 fstrcpy(ts
->queue
[i
].fs_user
, pjob
.user
);
727 fstrcpy(ts
->queue
[i
].fs_file
, pjob
.jobname
);
734 /****************************************************************************
735 Check if the print queue has been updated recently enough.
736 ****************************************************************************/
738 static void print_cache_flush(int snum
)
741 const char *printername
= lp_const_servicename(snum
);
742 struct tdb_print_db
*pdb
= get_print_db_byname(printername
);
746 slprintf(key
, sizeof(key
)-1, "CACHE/%s", printername
);
747 tdb_store_int32(pdb
->tdb
, key
, -1);
748 release_print_db(pdb
);
751 /****************************************************************************
752 Check if someone already thinks they are doing the update.
753 ****************************************************************************/
755 static pid_t
get_updating_pid(fstring printer_name
)
760 struct tdb_print_db
*pdb
= get_print_db_byname(printer_name
);
764 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", printer_name
);
766 key
.dsize
= strlen(keystr
);
768 data
= tdb_fetch(pdb
->tdb
, key
);
769 release_print_db(pdb
);
770 if (!data
.dptr
|| data
.dsize
!= sizeof(pid_t
)) {
771 SAFE_FREE(data
.dptr
);
775 memcpy(&updating_pid
, data
.dptr
, sizeof(pid_t
));
776 SAFE_FREE(data
.dptr
);
778 if (process_exists(updating_pid
))
784 /****************************************************************************
785 Set the fact that we're doing the update, or have finished doing the update
787 ****************************************************************************/
789 static void set_updating_pid(const fstring printer_name
, BOOL
delete)
794 pid_t updating_pid
= sys_getpid();
795 struct tdb_print_db
*pdb
= get_print_db_byname(printer_name
);
800 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", printer_name
);
802 key
.dsize
= strlen(keystr
);
805 tdb_delete(pdb
->tdb
, key
);
806 release_print_db(pdb
);
810 data
.dptr
= (void *)&updating_pid
;
811 data
.dsize
= sizeof(pid_t
);
813 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
814 release_print_db(pdb
);
817 /****************************************************************************
818 Sort print jobs by submittal time.
819 ****************************************************************************/
821 static int printjob_comp(print_queue_struct
*j1
, print_queue_struct
*j2
)
832 /* Sort on job start time */
834 if (j1
->time
== j2
->time
)
836 return (j1
->time
> j2
->time
) ? 1 : -1;
839 /****************************************************************************
840 Store the sorted queue representation for later portmon retrieval.
841 ****************************************************************************/
843 static void store_queue_struct(struct tdb_print_db
*pdb
, struct traverse_struct
*pts
)
846 int max_reported_jobs
= lp_max_reported_jobs(pts
->snum
);
847 print_queue_struct
*queue
= pts
->queue
;
852 if (max_reported_jobs
< pts
->qcount
)
853 pts
->qcount
= max_reported_jobs
;
854 qcount
= pts
->qcount
;
856 /* Work out the size. */
858 data
.dsize
+= tdb_pack(NULL
, 0, "d", qcount
);
860 for (i
= 0; i
< pts
->qcount
; i
++) {
861 data
.dsize
+= tdb_pack(NULL
, 0, "ddddddff",
862 (uint32
)queue
[i
].job
,
863 (uint32
)queue
[i
].size
,
864 (uint32
)queue
[i
].page_count
,
865 (uint32
)queue
[i
].status
,
866 (uint32
)queue
[i
].priority
,
867 (uint32
)queue
[i
].time
,
872 if ((data
.dptr
= malloc(data
.dsize
)) == NULL
)
876 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "d", qcount
);
877 for (i
= 0; i
< pts
->qcount
; i
++) {
878 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "ddddddff",
879 (uint32
)queue
[i
].job
,
880 (uint32
)queue
[i
].size
,
881 (uint32
)queue
[i
].page_count
,
882 (uint32
)queue
[i
].status
,
883 (uint32
)queue
[i
].priority
,
884 (uint32
)queue
[i
].time
,
889 key
.dptr
= "INFO/linear_queue_array";
890 key
.dsize
= strlen(key
.dptr
);
891 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
892 SAFE_FREE(data
.dptr
);
896 static TDB_DATA
get_jobs_changed_data(struct tdb_print_db
*pdb
)
900 key
.dptr
= "INFO/jobs_changed";
901 key
.dsize
= strlen(key
.dptr
);
904 data
= tdb_fetch(pdb
->tdb
, key
);
905 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0)) {
906 SAFE_FREE(data
.dptr
);
913 static void check_job_changed(int snum
, TDB_DATA data
, uint32 jobid
)
916 unsigned int job_count
= data
.dsize
/ 4;
918 for (i
= 0; i
< job_count
; i
++) {
921 memcpy(&ch_jobid
, data
.dptr
+ (i
*4), 4);
922 if (ch_jobid
== jobid
)
923 remove_from_jobs_changed(snum
, jobid
);
927 /****************************************************************************
928 Update the internal database from the system print queue for a queue.
929 ****************************************************************************/
931 static void print_queue_update(int snum
)
934 print_queue_struct
*queue
= NULL
;
935 print_status_struct status
;
936 print_status_struct old_status
;
937 struct printjob
*pjob
;
938 struct traverse_struct tstruct
;
939 fstring keystr
, printer_name
, cachestr
;
942 struct tdb_print_db
*pdb
;
944 fstrcpy(printer_name
, lp_const_servicename(snum
));
945 pdb
= get_print_db_byname(printer_name
);
950 * Check to see if someone else is doing this update.
951 * This is essentially a mutex on the update.
954 if (get_updating_pid(printer_name
) != -1) {
955 release_print_db(pdb
);
959 /* Lock the queue for the database update */
961 slprintf(keystr
, sizeof(keystr
) - 1, "LOCK/%s", printer_name
);
962 /* Only wait 10 seconds for this. */
963 if (tdb_lock_bystring(pdb
->tdb
, keystr
, 10) == -1) {
964 DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name
));
965 release_print_db(pdb
);
970 * Ensure that no one else got in here.
971 * If the updating pid is still -1 then we are
975 if (get_updating_pid(printer_name
) != -1) {
977 * Someone else is doing the update, exit.
979 tdb_unlock_bystring(pdb
->tdb
, keystr
);
980 release_print_db(pdb
);
985 * We're going to do the update ourselves.
988 /* Tell others we're doing the update. */
989 set_updating_pid(printer_name
, False
);
992 * Allow others to enter and notice we're doing
996 tdb_unlock_bystring(pdb
->tdb
, keystr
);
999 * Update the cache time FIRST ! Stops others even
1000 * attempting to get the lock and doing this
1001 * if the lpq takes a long time.
1004 slprintf(cachestr
, sizeof(cachestr
)-1, "CACHE/%s", printer_name
);
1005 tdb_store_int32(pdb
->tdb
, cachestr
, (int)time(NULL
));
1007 /* get the current queue using the appropriate interface */
1008 ZERO_STRUCT(status
);
1010 qcount
= (*(current_printif
->queue_get
))(snum
, &queue
, &status
);
1012 DEBUG(3, ("%d job%s in queue for %s\n", qcount
, (qcount
!= 1) ?
1013 "s" : "", printer_name
));
1015 /* Sort the queue by submission time otherwise they are displayed
1018 qsort(queue
, qcount
, sizeof(print_queue_struct
),
1019 QSORT_CAST(printjob_comp
));
1022 any job in the internal database that is marked as spooled
1023 and doesn't exist in the system queue is considered finished
1024 and removed from the database
1026 any job in the system database but not in the internal database
1027 is added as a unix job
1029 fill in any system job numbers as we go
1032 jcdata
= get_jobs_changed_data(pdb
);
1034 for (i
=0; i
<qcount
; i
++) {
1035 uint32 jobid
= print_parse_jobid(queue
[i
].fs_file
);
1037 if (jobid
== (uint32
)-1) {
1038 /* assume its a unix print job */
1039 print_unix_job(snum
, &queue
[i
], jobid
);
1043 /* we have an active SMB print job - update its status */
1044 pjob
= print_job_find(snum
, jobid
);
1046 /* err, somethings wrong. Probably smbd was restarted
1047 with jobs in the queue. All we can do is treat them
1048 like unix jobs. Pity. */
1049 print_unix_job(snum
, &queue
[i
], jobid
);
1053 pjob
->sysjob
= queue
[i
].job
;
1054 pjob
->status
= queue
[i
].status
;
1055 pjob_store(snum
, jobid
, pjob
);
1056 check_job_changed(snum
, jcdata
, jobid
);
1059 SAFE_FREE(jcdata
.dptr
);
1061 /* now delete any queued entries that don't appear in the
1063 tstruct
.queue
= queue
;
1064 tstruct
.qcount
= qcount
;
1065 tstruct
.snum
= snum
;
1066 tstruct
.total_jobs
= 0;
1067 tstruct
.lpq_time
= time(NULL
);
1069 tdb_traverse(pdb
->tdb
, traverse_fn_delete
, (void *)&tstruct
);
1071 /* Store the linearised queue, max jobs only. */
1072 store_queue_struct(pdb
, &tstruct
);
1074 SAFE_FREE(tstruct
.queue
);
1076 DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n",
1077 printer_name
, tstruct
.total_jobs
));
1079 tdb_store_int32(pdb
->tdb
, "INFO/total_jobs", tstruct
.total_jobs
);
1081 get_queue_status(snum
, &old_status
);
1082 if (old_status
.qcount
!= qcount
)
1083 DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
1084 old_status
.qcount
, qcount
, printer_name
));
1086 /* store the new queue status structure */
1087 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", printer_name
);
1089 key
.dsize
= strlen(keystr
);
1091 status
.qcount
= qcount
;
1092 data
.dptr
= (void *)&status
;
1093 data
.dsize
= sizeof(status
);
1094 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
1097 * Update the cache time again. We want to do this call
1098 * as little as possible...
1101 slprintf(keystr
, sizeof(keystr
)-1, "CACHE/%s", printer_name
);
1102 tdb_store_int32(pdb
->tdb
, keystr
, (int32
)time(NULL
));
1104 /* Delete our pid from the db. */
1105 set_updating_pid(printer_name
, True
);
1106 release_print_db(pdb
);
1109 /****************************************************************************
1110 Create/Update an entry in the print tdb that will allow us to send notify
1111 updates only to interested smbd's.
1112 ****************************************************************************/
1114 BOOL
print_notify_register_pid(int snum
)
1117 struct tdb_print_db
*pdb
= NULL
;
1118 TDB_CONTEXT
*tdb
= NULL
;
1119 const char *printername
;
1120 uint32 mypid
= (uint32
)sys_getpid();
1124 /* if (snum == -1), then the change notify request was
1125 on a print server handle and we need to register on
1130 int num_services
= lp_numservices();
1133 for ( idx
=0; idx
<num_services
; idx
++ ) {
1134 if (lp_snum_ok(idx
) && lp_print_ok(idx
) )
1135 print_notify_register_pid(idx
);
1140 else /* register for a specific printer */
1142 printername
= lp_const_servicename(snum
);
1143 pdb
= get_print_db_byname(printername
);
1149 if (tdb_lock_bystring(tdb
, NOTIFY_PID_LIST_KEY
, 10) == -1) {
1150 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1153 release_print_db(pdb
);
1157 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1159 /* Add ourselves and increase the refcount. */
1161 for (i
= 0; i
< data
.dsize
; i
+= 8) {
1162 if (IVAL(data
.dptr
,i
) == mypid
) {
1163 uint32 new_refcount
= IVAL(data
.dptr
, i
+4) + 1;
1164 SIVAL(data
.dptr
, i
+4, new_refcount
);
1169 if (i
== data
.dsize
) {
1170 /* We weren't in the list. Realloc. */
1171 data
.dptr
= Realloc(data
.dptr
, data
.dsize
+ 8);
1173 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1178 SIVAL(data
.dptr
,data
.dsize
- 8,mypid
);
1179 SIVAL(data
.dptr
,data
.dsize
- 4,1); /* Refcount. */
1182 /* Store back the record. */
1183 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) == -1) {
1184 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1185 list for printer %s\n", printername
));
1193 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
1195 release_print_db(pdb
);
1196 SAFE_FREE(data
.dptr
);
1200 /****************************************************************************
1201 Update an entry in the print tdb that will allow us to send notify
1202 updates only to interested smbd's.
1203 ****************************************************************************/
1205 BOOL
print_notify_deregister_pid(int snum
)
1208 struct tdb_print_db
*pdb
= NULL
;
1209 TDB_CONTEXT
*tdb
= NULL
;
1210 const char *printername
;
1211 uint32 mypid
= (uint32
)sys_getpid();
1215 /* if ( snum == -1 ), we are deregister a print server handle
1216 which means to deregister on all print queues */
1220 int num_services
= lp_numservices();
1223 for ( idx
=0; idx
<num_services
; idx
++ ) {
1224 if ( lp_snum_ok(idx
) && lp_print_ok(idx
) )
1225 print_notify_deregister_pid(idx
);
1230 else /* deregister a specific printer */
1232 printername
= lp_const_servicename(snum
);
1233 pdb
= get_print_db_byname(printername
);
1239 if (tdb_lock_bystring(tdb
, NOTIFY_PID_LIST_KEY
, 10) == -1) {
1240 DEBUG(0,("print_notify_register_pid: Failed to lock \
1241 printer %s database\n", printername
));
1243 release_print_db(pdb
);
1247 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1249 /* Reduce refcount. Remove ourselves if zero. */
1251 for (i
= 0; i
< data
.dsize
; ) {
1252 if (IVAL(data
.dptr
,i
) == mypid
) {
1253 uint32 refcount
= IVAL(data
.dptr
, i
+4);
1257 if (refcount
== 0) {
1258 if (data
.dsize
- i
> 8)
1259 memmove( &data
.dptr
[i
], &data
.dptr
[i
+8], data
.dsize
- i
- 8);
1263 SIVAL(data
.dptr
, i
+4, refcount
);
1269 if (data
.dsize
== 0)
1270 SAFE_FREE(data
.dptr
);
1272 /* Store back the record. */
1273 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) == -1) {
1274 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1275 list for printer %s\n", printername
));
1283 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
1285 release_print_db(pdb
);
1286 SAFE_FREE(data
.dptr
);
1290 /****************************************************************************
1291 Check if a jobid is valid. It is valid if it exists in the database.
1292 ****************************************************************************/
1294 BOOL
print_job_exists(int snum
, uint32 jobid
)
1296 struct tdb_print_db
*pdb
= get_print_db_byname(lp_const_servicename(snum
));
1301 ret
= tdb_exists(pdb
->tdb
, print_key(jobid
));
1302 release_print_db(pdb
);
1306 /****************************************************************************
1307 Give the fd used for a jobid.
1308 ****************************************************************************/
1310 int print_job_fd(int snum
, uint32 jobid
)
1312 struct printjob
*pjob
= print_job_find(snum
, jobid
);
1315 /* don't allow another process to get this info - it is meaningless */
1316 if (pjob
->pid
!= local_pid
)
1321 /****************************************************************************
1322 Give the filename used for a jobid.
1323 Only valid for the process doing the spooling and when the job
1324 has not been spooled.
1325 ****************************************************************************/
1327 char *print_job_fname(int snum
, uint32 jobid
)
1329 struct printjob
*pjob
= print_job_find(snum
, jobid
);
1330 if (!pjob
|| pjob
->spooled
|| pjob
->pid
!= local_pid
)
1332 return pjob
->filename
;
1336 /****************************************************************************
1337 Give the filename used for a jobid.
1338 Only valid for the process doing the spooling and when the job
1339 has not been spooled.
1340 ****************************************************************************/
1342 NT_DEVICEMODE
*print_job_devmode(int snum
, uint32 jobid
)
1344 struct printjob
*pjob
= print_job_find(snum
, jobid
);
1349 return pjob
->nt_devmode
;
1352 /****************************************************************************
1353 Set the place in the queue for a job.
1354 ****************************************************************************/
1356 BOOL
print_job_set_place(int snum
, uint32 jobid
, int place
)
1358 DEBUG(2,("print_job_set_place not implemented yet\n"));
1362 /****************************************************************************
1363 Set the name of a job. Only possible for owner.
1364 ****************************************************************************/
1366 BOOL
print_job_set_name(int snum
, uint32 jobid
, char *name
)
1368 struct printjob
*pjob
= print_job_find(snum
, jobid
);
1369 if (!pjob
|| pjob
->pid
!= local_pid
)
1372 fstrcpy(pjob
->jobname
, name
);
1373 return pjob_store(snum
, jobid
, pjob
);
1376 /***************************************************************************
1377 Remove a jobid from the 'jobs changed' list.
1378 ***************************************************************************/
1380 static BOOL
remove_from_jobs_changed(int snum
, uint32 jobid
)
1382 const char *printername
= lp_const_servicename(snum
);
1383 struct tdb_print_db
*pdb
= get_print_db_byname(printername
);
1385 size_t job_count
, i
;
1387 BOOL gotlock
= False
;
1389 key
.dptr
= "INFO/jobs_changed";
1390 key
.dsize
= strlen(key
.dptr
);
1393 if (tdb_chainlock_with_timeout(pdb
->tdb
, key
, 5) == -1)
1398 data
= tdb_fetch(pdb
->tdb
, key
);
1400 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0))
1403 job_count
= data
.dsize
/ 4;
1404 for (i
= 0; i
< job_count
; i
++) {
1407 memcpy(&ch_jobid
, data
.dptr
+ (i
*4), 4);
1408 if (ch_jobid
== jobid
) {
1409 if (i
< job_count
-1 )
1410 memmove(data
.dptr
+ (i
*4), data
.dptr
+ (i
*4) + 4, (job_count
- i
- 1)*4 );
1412 if (tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
) == -1)
1422 tdb_chainunlock(pdb
->tdb
, key
);
1423 SAFE_FREE(data
.dptr
);
1424 release_print_db(pdb
);
1426 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid
));
1428 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid
));
1432 /****************************************************************************
1433 Delete a print job - don't update queue.
1434 ****************************************************************************/
1436 static BOOL
print_job_delete1(int snum
, uint32 jobid
)
1438 struct printjob
*pjob
= print_job_find(snum
, jobid
);
1445 * If already deleting just return.
1448 if (pjob
->status
== LPQ_DELETING
)
1451 /* Hrm - we need to be able to cope with deleting a job before it
1452 has reached the spooler. */
1454 if (pjob
->sysjob
== -1) {
1455 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid
));
1458 /* Set the tdb entry to be deleting. */
1460 pjob
->status
= LPQ_DELETING
;
1461 pjob_store(snum
, jobid
, pjob
);
1463 if (pjob
->spooled
&& pjob
->sysjob
!= -1)
1464 result
= (*(current_printif
->job_delete
))(snum
, pjob
);
1466 remove_from_jobs_changed(snum
, jobid
);
1468 /* Delete the tdb entry if the delete succeeded or the job hasn't
1472 const char *printername
= lp_const_servicename(snum
);
1473 struct tdb_print_db
*pdb
= get_print_db_byname(printername
);
1478 pjob_delete(snum
, jobid
);
1479 /* Ensure we keep a rough count of the number of total jobs... */
1480 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, -1);
1481 release_print_db(pdb
);
1484 return (result
== 0);
1487 /****************************************************************************
1488 Return true if the current user owns the print job.
1489 ****************************************************************************/
1491 static BOOL
is_owner(struct current_user
*user
, int snum
, uint32 jobid
)
1493 struct printjob
*pjob
= print_job_find(snum
, jobid
);
1499 if ((vuser
= get_valid_user_struct(user
->vuid
)) != NULL
) {
1500 return strequal(pjob
->user
, vuser
->user
.smb_name
);
1502 return strequal(pjob
->user
, uidtoname(user
->uid
));
1506 /****************************************************************************
1508 ****************************************************************************/
1510 BOOL
print_job_delete(struct current_user
*user
, int snum
, uint32 jobid
, WERROR
*errcode
)
1512 BOOL owner
, deleted
;
1517 owner
= is_owner(user
, snum
, jobid
);
1519 /* Check access against security descriptor or whether the user
1523 !print_access_check(user
, snum
, JOB_ACCESS_ADMINISTER
)) {
1524 DEBUG(3, ("delete denied by security descriptor\n"));
1525 *errcode
= WERR_ACCESS_DENIED
;
1527 /* BEGIN_ADMIN_LOG */
1528 sys_adminlog( LOG_ERR
,
1529 "Permission denied-- user not allowed to delete, \
1530 pause, or resume print job. User name: %s. Printer name: %s.",
1531 uidtoname(user
->uid
), PRINTERNAME(snum
) );
1538 * get the spooled filename of the print job
1539 * if this works, then the file has not been spooled
1540 * to the underlying print system. Just delete the
1541 * spool file & return.
1544 if ( (fname
= print_job_fname( snum
, jobid
)) != NULL
)
1546 /* remove the spool file */
1547 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname
));
1548 if ( unlink( fname
) == -1 ) {
1549 *errcode
= map_werror_from_unix(errno
);
1556 if (!print_job_delete1(snum
, jobid
)) {
1557 *errcode
= WERR_ACCESS_DENIED
;
1561 /* force update the database and say the delete failed if the
1564 print_queue_update(snum
);
1566 deleted
= !print_job_exists(snum
, jobid
);
1568 *errcode
= WERR_ACCESS_DENIED
;
1573 /****************************************************************************
1575 ****************************************************************************/
1577 BOOL
print_job_pause(struct current_user
*user
, int snum
, uint32 jobid
, WERROR
*errcode
)
1579 struct printjob
*pjob
= print_job_find(snum
, jobid
);
1585 if (!pjob
->spooled
|| pjob
->sysjob
== -1)
1588 if (!is_owner(user
, snum
, jobid
) &&
1589 !print_access_check(user
, snum
, JOB_ACCESS_ADMINISTER
)) {
1590 DEBUG(3, ("pause denied by security descriptor\n"));
1592 /* BEGIN_ADMIN_LOG */
1593 sys_adminlog( LOG_ERR
,
1594 "Permission denied-- user not allowed to delete, \
1595 pause, or resume print job. User name: %s. Printer name: %s.",
1596 uidtoname(user
->uid
), PRINTERNAME(snum
) );
1599 *errcode
= WERR_ACCESS_DENIED
;
1603 /* need to pause the spooled entry */
1604 ret
= (*(current_printif
->job_pause
))(snum
, pjob
);
1607 *errcode
= WERR_INVALID_PARAM
;
1611 /* force update the database */
1612 print_cache_flush(snum
);
1614 /* Send a printer notify message */
1616 notify_job_status(snum
, jobid
, JOB_STATUS_PAUSED
);
1618 /* how do we tell if this succeeded? */
1623 /****************************************************************************
1625 ****************************************************************************/
1627 BOOL
print_job_resume(struct current_user
*user
, int snum
, uint32 jobid
, WERROR
*errcode
)
1629 struct printjob
*pjob
= print_job_find(snum
, jobid
);
1635 if (!pjob
->spooled
|| pjob
->sysjob
== -1)
1638 if (!is_owner(user
, snum
, jobid
) &&
1639 !print_access_check(user
, snum
, JOB_ACCESS_ADMINISTER
)) {
1640 DEBUG(3, ("resume denied by security descriptor\n"));
1641 *errcode
= WERR_ACCESS_DENIED
;
1643 /* BEGIN_ADMIN_LOG */
1644 sys_adminlog( LOG_ERR
,
1645 "Permission denied-- user not allowed to delete, \
1646 pause, or resume print job. User name: %s. Printer name: %s.",
1647 uidtoname(user
->uid
), PRINTERNAME(snum
) );
1652 ret
= (*(current_printif
->job_resume
))(snum
, pjob
);
1655 *errcode
= WERR_INVALID_PARAM
;
1659 /* force update the database */
1660 print_cache_flush(snum
);
1662 /* Send a printer notify message */
1664 notify_job_status(snum
, jobid
, JOB_STATUS_QUEUED
);
1669 /****************************************************************************
1670 Write to a print file.
1671 ****************************************************************************/
1673 int print_job_write(int snum
, uint32 jobid
, const char *buf
, int size
)
1676 struct printjob
*pjob
= print_job_find(snum
, jobid
);
1680 /* don't allow another process to get this info - it is meaningless */
1681 if (pjob
->pid
!= local_pid
)
1684 return_code
= write(pjob
->fd
, buf
, size
);
1685 if (return_code
>0) {
1687 pjob_store(snum
, jobid
, pjob
);
1692 /****************************************************************************
1693 Check if the print queue has been updated recently enough.
1694 ****************************************************************************/
1696 static BOOL
print_cache_expired(int snum
)
1699 time_t last_qscan_time
, time_now
= time(NULL
);
1700 const char *printername
= lp_const_servicename(snum
);
1701 struct tdb_print_db
*pdb
= get_print_db_byname(printername
);
1706 slprintf(key
, sizeof(key
), "CACHE/%s", printername
);
1707 last_qscan_time
= (time_t)tdb_fetch_int32(pdb
->tdb
, key
);
1710 * Invalidate the queue for 3 reasons.
1711 * (1). last queue scan time == -1.
1712 * (2). Current time - last queue scan time > allowed cache time.
1713 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1714 * This last test picks up machines for which the clock has been moved
1715 * forward, an lpq scan done and then the clock moved back. Otherwise
1716 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1719 if (last_qscan_time
== ((time_t)-1) || (time_now
- last_qscan_time
) >= lp_lpqcachetime() ||
1720 last_qscan_time
> (time_now
+ MAX_CACHE_VALID_TIME
)) {
1721 DEBUG(3, ("print cache expired for queue %s \
1722 (last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername
,
1723 (int)last_qscan_time
, (int)time_now
, (int)lp_lpqcachetime() ));
1724 release_print_db(pdb
);
1727 release_print_db(pdb
);
1731 /****************************************************************************
1732 Get the queue status - do not update if db is out of date.
1733 ****************************************************************************/
1735 static int get_queue_status(int snum
, print_status_struct
*status
)
1739 const char *printername
= lp_const_servicename(snum
);
1740 struct tdb_print_db
*pdb
= get_print_db_byname(printername
);
1747 ZERO_STRUCTP(status
);
1748 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", printername
);
1750 key
.dsize
= strlen(keystr
);
1751 data
= tdb_fetch(pdb
->tdb
, key
);
1753 if (data
.dsize
== sizeof(print_status_struct
))
1754 memcpy(status
, data
.dptr
, sizeof(print_status_struct
));
1755 SAFE_FREE(data
.dptr
);
1758 len
= tdb_fetch_int32(pdb
->tdb
, "INFO/total_jobs");
1759 release_print_db(pdb
);
1760 return (len
== -1 ? 0 : len
);
1763 /****************************************************************************
1764 Determine the number of jobs in a queue.
1765 ****************************************************************************/
1767 int print_queue_length(int snum
, print_status_struct
*pstatus
)
1769 print_status_struct status
;
1772 /* make sure the database is up to date */
1773 if (print_cache_expired(snum
))
1774 print_queue_update(snum
);
1776 /* also fetch the queue status */
1777 memset(&status
, 0, sizeof(status
));
1778 len
= get_queue_status(snum
, &status
);
1786 /***************************************************************************
1787 Allocate a jobid. Hold the lock for as short a time as possible.
1788 ***************************************************************************/
1790 static BOOL
allocate_print_jobid(struct tdb_print_db
*pdb
, int snum
, const char *printername
, uint32
*pjobid
)
1795 *pjobid
= (uint32
)-1;
1797 for (i
= 0; i
< 3; i
++) {
1798 /* Lock the database - only wait 20 seconds. */
1799 if (tdb_lock_bystring(pdb
->tdb
, "INFO/nextjob", 20) == -1) {
1800 DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", printername
));
1804 if (!tdb_fetch_uint32(pdb
->tdb
, "INFO/nextjob", &jobid
)) {
1805 if (tdb_error(pdb
->tdb
) != TDB_ERR_NOEXIST
) {
1806 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
1813 jobid
= NEXT_JOBID(jobid
);
1815 if (tdb_store_int32(pdb
->tdb
, "INFO/nextjob", jobid
)==-1) {
1816 DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
1817 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
1821 /* We've finished with the INFO/nextjob lock. */
1822 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
1824 if (!print_job_exists(snum
, jobid
))
1829 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
1831 /* Probably full... */
1836 /* Store a dummy placeholder. */
1841 if (tdb_store(pdb
->tdb
, print_key(jobid
), dum
, TDB_INSERT
) == -1) {
1842 DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
1852 /***************************************************************************
1853 Append a jobid to the 'jobs changed' list.
1854 ***************************************************************************/
1856 static BOOL
add_to_jobs_changed(struct tdb_print_db
*pdb
, uint32 jobid
)
1860 key
.dptr
= "INFO/jobs_changed";
1861 key
.dsize
= strlen(key
.dptr
);
1862 data
.dptr
= (char *)&jobid
;
1865 DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid
));
1867 return (tdb_append(pdb
->tdb
, key
, data
) == 0);
1870 /***************************************************************************
1871 Start spooling a job - return the jobid.
1872 ***************************************************************************/
1874 uint32
print_job_start(struct current_user
*user
, int snum
, char *jobname
, NT_DEVICEMODE
*nt_devmode
)
1878 struct printjob pjob
;
1880 const char *printername
= lp_const_servicename(snum
);
1881 struct tdb_print_db
*pdb
= get_print_db_byname(printername
);
1889 if (!print_access_check(user
, snum
, PRINTER_ACCESS_USE
)) {
1890 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
1891 release_print_db(pdb
);
1895 if (!print_time_access_check(snum
)) {
1896 DEBUG(3, ("print_job_start: job start denied by time check\n"));
1897 release_print_db(pdb
);
1901 path
= lp_pathname(snum
);
1903 /* see if we have sufficient disk space */
1904 if (lp_minprintspace(snum
)) {
1905 SMB_BIG_UINT dspace
, dsize
;
1906 if (sys_fsusage(path
, &dspace
, &dsize
) == 0 &&
1907 dspace
< 2*(SMB_BIG_UINT
)lp_minprintspace(snum
)) {
1908 DEBUG(3, ("print_job_start: disk space check failed.\n"));
1909 release_print_db(pdb
);
1915 /* for autoloaded printers, check that the printcap entry still exists */
1916 if (lp_autoloaded(snum
) && !pcap_printername_ok(lp_const_servicename(snum
), NULL
)) {
1917 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum
) ));
1918 release_print_db(pdb
);
1923 /* Insure the maximum queue size is not violated */
1924 if ((njobs
= print_queue_length(snum
,NULL
)) > lp_maxprintjobs(snum
)) {
1925 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
1926 printername
, njobs
, lp_maxprintjobs(snum
) ));
1927 release_print_db(pdb
);
1932 DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
1933 printername
, njobs
, lp_maxprintjobs(snum
) ));
1935 if (!allocate_print_jobid(pdb
, snum
, printername
, &jobid
))
1938 /* create the database entry */
1942 pjob
.pid
= local_pid
;
1945 pjob
.starttime
= time(NULL
);
1946 pjob
.status
= LPQ_SPOOLING
;
1948 pjob
.spooled
= False
;
1950 pjob
.nt_devmode
= nt_devmode
;
1952 fstrcpy(pjob
.jobname
, jobname
);
1954 if ((vuser
= get_valid_user_struct(user
->vuid
)) != NULL
) {
1955 fstrcpy(pjob
.user
, vuser
->user
.smb_name
);
1957 fstrcpy(pjob
.user
, uidtoname(user
->uid
));
1960 fstrcpy(pjob
.queuename
, lp_const_servicename(snum
));
1962 /* we have a job entry - now create the spool file */
1963 slprintf(pjob
.filename
, sizeof(pjob
.filename
)-1, "%s/%s%.8u.XXXXXX",
1964 path
, PRINT_SPOOL_PREFIX
, (unsigned int)jobid
);
1965 pjob
.fd
= smb_mkstemp(pjob
.filename
);
1967 if (pjob
.fd
== -1) {
1968 if (errno
== EACCES
) {
1969 /* Common setup error, force a report. */
1970 DEBUG(0, ("print_job_start: insufficient permissions \
1971 to open spool file %s.\n", pjob
.filename
));
1973 /* Normal case, report at level 3 and above. */
1974 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob
.filename
));
1975 DEBUGADD(3, ("errno = %d (%s).\n", errno
, strerror(errno
)));
1980 pjob_store(snum
, jobid
, &pjob
);
1982 /* Update the 'jobs changed' entry used by print_queue_status. */
1983 add_to_jobs_changed(pdb
, jobid
);
1985 /* Ensure we keep a rough count of the number of total jobs... */
1986 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, 1);
1988 release_print_db(pdb
);
1994 pjob_delete(snum
, jobid
);
1996 release_print_db(pdb
);
1998 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno
) ));
2002 /****************************************************************************
2003 Update the number of pages spooled to jobid
2004 ****************************************************************************/
2006 void print_job_endpage(int snum
, uint32 jobid
)
2008 struct printjob
*pjob
= print_job_find(snum
, jobid
);
2011 /* don't allow another process to get this info - it is meaningless */
2012 if (pjob
->pid
!= local_pid
)
2016 pjob_store(snum
, jobid
, pjob
);
2019 /****************************************************************************
2020 Print a file - called on closing the file. This spools the job.
2021 If normal close is false then we're tearing down the jobs - treat as an
2023 ****************************************************************************/
2025 BOOL
print_job_end(int snum
, uint32 jobid
, BOOL normal_close
)
2027 struct printjob
*pjob
= print_job_find(snum
, jobid
);
2029 SMB_STRUCT_STAT sbuf
;
2034 if (pjob
->spooled
|| pjob
->pid
!= local_pid
)
2037 if (normal_close
&& (sys_fstat(pjob
->fd
, &sbuf
) == 0)) {
2038 pjob
->size
= sbuf
.st_size
;
2044 * Not a normal close or we couldn't stat the job file,
2045 * so something has gone wrong. Cleanup.
2049 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid
));
2053 /* Technically, this is not quite right. If the printer has a separator
2054 * page turned on, the NT spooler prints the separator page even if the
2055 * print job is 0 bytes. 010215 JRR */
2056 if (pjob
->size
== 0 || pjob
->status
== LPQ_DELETING
) {
2057 /* don't bother spooling empty files or something being deleted. */
2058 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2059 pjob
->filename
, pjob
->size
? "deleted" : "zero length" ));
2060 unlink(pjob
->filename
);
2061 pjob_delete(snum
, jobid
);
2065 ret
= (*(current_printif
->job_submit
))(snum
, pjob
);
2070 /* The print job has been sucessfully handed over to the back-end */
2072 pjob
->spooled
= True
;
2073 pjob
->status
= LPQ_QUEUED
;
2074 pjob_store(snum
, jobid
, pjob
);
2076 /* make sure the database is up to date */
2077 if (print_cache_expired(snum
))
2078 print_queue_update(snum
);
2084 /* The print job was not succesfully started. Cleanup */
2085 /* Still need to add proper error return propagation! 010122:JRR */
2086 unlink(pjob
->filename
);
2087 pjob_delete(snum
, jobid
);
2088 remove_from_jobs_changed(snum
, jobid
);
2092 /****************************************************************************
2093 Get a snapshot of jobs in the system without traversing.
2094 ****************************************************************************/
2096 static BOOL
get_stored_queue_info(struct tdb_print_db
*pdb
, int snum
, int *pcount
, print_queue_struct
**ppqueue
)
2098 TDB_DATA data
, key
, cgdata
;
2099 print_queue_struct
*queue
= NULL
;
2101 uint32 extra_count
= 0;
2102 int total_count
= 0;
2105 int max_reported_jobs
= lp_max_reported_jobs(snum
);
2108 /* make sure the database is up to date */
2109 if (print_cache_expired(snum
))
2110 print_queue_update(snum
);
2116 ZERO_STRUCT(cgdata
);
2117 key
.dptr
= "INFO/linear_queue_array";
2118 key
.dsize
= strlen(key
.dptr
);
2120 /* Get the stored queue data. */
2121 data
= tdb_fetch(pdb
->tdb
, key
);
2123 if (data
.dptr
== NULL
|| data
.dsize
< 4)
2126 memcpy(&qcount
, data
.dptr
, 4);
2128 /* Get the changed jobs list. */
2129 key
.dptr
= "INFO/jobs_changed";
2130 key
.dsize
= strlen(key
.dptr
);
2132 cgdata
= tdb_fetch(pdb
->tdb
, key
);
2133 if (cgdata
.dptr
!= NULL
&& (cgdata
.dsize
% 4 == 0))
2134 extra_count
= cgdata
.dsize
/4;
2136 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount
, (unsigned int)extra_count
));
2138 /* Allocate the queue size. */
2139 if (qcount
== 0 && extra_count
== 0)
2142 if ((queue
= (print_queue_struct
*)malloc(sizeof(print_queue_struct
)*(qcount
+ extra_count
))) == NULL
)
2145 /* Retrieve the linearised queue data. */
2147 for( i
= 0; i
< qcount
; i
++) {
2148 uint32 qjob
, qsize
, qpage_count
, qstatus
, qpriority
, qtime
;
2149 len
+= tdb_unpack(data
.dptr
+ 4 + len
, data
.dsize
- len
, NULL
, "ddddddff",
2158 queue
[i
].job
= qjob
;
2159 queue
[i
].size
= qsize
;
2160 queue
[i
].page_count
= qpage_count
;
2161 queue
[i
].status
= qstatus
;
2162 queue
[i
].priority
= qpriority
;
2163 queue
[i
].time
= qtime
;
2166 total_count
= qcount
;
2168 /* Add in the changed jobids. */
2169 for( i
= 0; i
< extra_count
; i
++) {
2171 struct printjob
*pjob
;
2173 memcpy(&jobid
, &cgdata
.dptr
[i
*4], 4);
2174 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid
));
2175 pjob
= print_job_find(snum
, jobid
);
2177 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid
));
2178 remove_from_jobs_changed(snum
, jobid
);
2182 queue
[total_count
].job
= jobid
;
2183 queue
[total_count
].size
= pjob
->size
;
2184 queue
[total_count
].page_count
= pjob
->page_count
;
2185 queue
[total_count
].status
= pjob
->status
;
2186 queue
[total_count
].priority
= 1;
2187 fstrcpy(queue
[total_count
].fs_user
, pjob
->user
);
2188 fstrcpy(queue
[total_count
].fs_file
, pjob
->jobname
);
2192 /* Sort the queue by submission time otherwise they are displayed
2195 qsort(queue
, total_count
, sizeof(print_queue_struct
), QSORT_CAST(printjob_comp
));
2197 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count
));
2199 if (max_reported_jobs
&& total_count
> max_reported_jobs
)
2200 total_count
= max_reported_jobs
;
2203 *pcount
= total_count
;
2209 SAFE_FREE(data
.dptr
);
2210 SAFE_FREE(cgdata
.dptr
);
2214 /****************************************************************************
2215 Get a printer queue listing.
2216 set queue = NULL and status = NULL if you just want to update the cache
2217 ****************************************************************************/
2219 int print_queue_status(int snum
,
2220 print_queue_struct
**ppqueue
,
2221 print_status_struct
*status
)
2225 const char *printername
;
2226 struct tdb_print_db
*pdb
;
2229 /* make sure the database is up to date */
2231 if (print_cache_expired(snum
))
2232 print_queue_update(snum
);
2234 /* return if we are done */
2235 if ( !ppqueue
|| !status
)
2239 printername
= lp_const_servicename(snum
);
2240 pdb
= get_print_db_byname(printername
);
2246 * Fetch the queue status. We must do this first, as there may
2247 * be no jobs in the queue.
2250 ZERO_STRUCTP(status
);
2251 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", printername
);
2253 key
.dsize
= strlen(keystr
);
2254 data
= tdb_fetch(pdb
->tdb
, key
);
2256 if (data
.dsize
== sizeof(*status
)) {
2257 memcpy(status
, data
.dptr
, sizeof(*status
));
2259 SAFE_FREE(data
.dptr
);
2263 * Now, fetch the print queue information. We first count the number
2264 * of entries, and then only retrieve the queue if necessary.
2267 if (!get_stored_queue_info(pdb
, snum
, &count
, ppqueue
)) {
2268 release_print_db(pdb
);
2272 release_print_db(pdb
);
2276 /****************************************************************************
2278 ****************************************************************************/
2280 BOOL
print_queue_pause(struct current_user
*user
, int snum
, WERROR
*errcode
)
2284 if (!print_access_check(user
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
2285 *errcode
= WERR_ACCESS_DENIED
;
2289 ret
= (*(current_printif
->queue_pause
))(snum
);
2292 *errcode
= WERR_INVALID_PARAM
;
2296 /* force update the database */
2297 print_cache_flush(snum
);
2299 /* Send a printer notify message */
2301 notify_printer_status(snum
, PRINTER_STATUS_PAUSED
);
2306 /****************************************************************************
2308 ****************************************************************************/
2310 BOOL
print_queue_resume(struct current_user
*user
, int snum
, WERROR
*errcode
)
2314 if (!print_access_check(user
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
2315 *errcode
= WERR_ACCESS_DENIED
;
2319 ret
= (*(current_printif
->queue_resume
))(snum
);
2322 *errcode
= WERR_INVALID_PARAM
;
2326 /* make sure the database is up to date */
2327 if (print_cache_expired(snum
))
2328 print_queue_update(snum
);
2330 /* Send a printer notify message */
2332 notify_printer_status(snum
, PRINTER_STATUS_OK
);
2337 /****************************************************************************
2338 Purge a queue - implemented by deleting all jobs that we can delete.
2339 ****************************************************************************/
2341 BOOL
print_queue_purge(struct current_user
*user
, int snum
, WERROR
*errcode
)
2343 print_queue_struct
*queue
;
2344 print_status_struct status
;
2348 /* Force and update so the count is accurate (i.e. not a cached count) */
2349 print_queue_update(snum
);
2351 can_job_admin
= print_access_check(user
, snum
, JOB_ACCESS_ADMINISTER
);
2352 njobs
= print_queue_status(snum
, &queue
, &status
);
2354 for (i
=0;i
<njobs
;i
++) {
2355 BOOL owner
= is_owner(user
, snum
, queue
[i
].job
);
2357 if (owner
|| can_job_admin
) {
2358 print_job_delete1(snum
, queue
[i
].job
);