2002-06-28 04:17:15 +04:00
/*
Unix SMB / Netbios implementation .
2003-10-15 02:32:27 +04:00
Version 3.0
2002-06-28 04:17:15 +04:00
printing backend routines
Copyright ( C ) Tim Potter , 2002
2002-08-17 20:31:24 +04:00
Copyright ( C ) Gerald Carter , 2002
2002-06-28 04:17:15 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2002-06-28 04:17:15 +04:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2002-06-28 04:17:15 +04:00
*/
2003-11-12 04:51:10 +03:00
# include "includes.h"
2002-06-28 04:17:15 +04:00
# include "printing.h"
2002-09-25 19:19:00 +04:00
static TALLOC_CTX * send_ctx ;
2003-04-10 22:43:13 +04:00
static unsigned int num_messages ;
2002-09-25 19:19:00 +04:00
static struct notify_queue {
struct notify_queue * next , * prev ;
2003-02-06 02:03:58 +03:00
struct spoolss_notify_msg * msg ;
2003-04-02 06:31:51 +04:00
struct timeval tv ;
2007-03-29 13:35:51 +04:00
uint8 * buf ;
2002-09-25 19:19:00 +04:00
size_t buflen ;
} * notify_queue_head = NULL ;
2009-01-21 09:39:28 +03:00
static struct tevent_timer * notify_event ;
static bool print_notify_pid_list ( const char * printername , TALLOC_CTX * mem_ctx ,
size_t * p_num_pids , pid_t * * pp_pid_list ) ;
2003-02-06 02:03:58 +03:00
2007-10-19 04:40:25 +04:00
static bool create_send_ctx ( void )
2003-02-06 02:03:58 +03:00
{
if ( ! send_ctx )
send_ctx = talloc_init ( " print notify queue " ) ;
if ( ! send_ctx )
return False ;
return True ;
}
2002-11-26 03:46:31 +03:00
/****************************************************************************
Turn a queue name into a snum .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int print_queue_snum ( const char * qname )
{
int snum = lp_servicenumber ( qname ) ;
if ( snum = = - 1 | | ! lp_print_ok ( snum ) )
return - 1 ;
return snum ;
}
2002-09-25 19:19:00 +04:00
/*******************************************************************
Used to decide if we need a short select timeout .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-01-21 09:39:28 +03:00
static bool print_notify_messages_pending ( void )
2002-09-25 19:19:00 +04:00
{
return ( notify_queue_head ! = NULL ) ;
}
2003-02-06 02:03:58 +03:00
/*******************************************************************
Flatten data into a message .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static bool flatten_message ( struct notify_queue * q )
2003-02-06 02:03:58 +03:00
{
struct spoolss_notify_msg * msg = q - > msg ;
2007-03-29 13:35:51 +04:00
uint8 * buf = NULL ;
2003-02-06 02:03:58 +03:00
size_t buflen = 0 , len ;
again :
len = 0 ;
/* Pack header */
2003-02-12 13:57:39 +03:00
len + = tdb_pack ( buf + len , buflen - len , " f " , msg - > printer ) ;
2003-02-06 02:03:58 +03:00
2003-04-02 06:31:51 +04:00
len + = tdb_pack ( buf + len , buflen - len , " ddddddd " ,
( uint32 ) q - > tv . tv_sec , ( uint32 ) q - > tv . tv_usec ,
2003-02-06 02:03:58 +03:00
msg - > type , msg - > field , msg - > id , msg - > len , msg - > flags ) ;
/* Pack data */
if ( msg - > len = = 0 )
2003-02-12 13:57:39 +03:00
len + = tdb_pack ( buf + len , buflen - len , " dd " ,
2003-02-06 02:03:58 +03:00
msg - > notify . value [ 0 ] , msg - > notify . value [ 1 ] ) ;
else
2003-02-12 13:57:39 +03:00
len + = tdb_pack ( buf + len , buflen - len , " B " ,
2003-02-06 02:03:58 +03:00
msg - > len , msg - > notify . data ) ;
if ( buflen ! = len ) {
2007-03-29 13:35:51 +04:00
buf = ( uint8 * ) TALLOC_REALLOC ( send_ctx , buf , len ) ;
2003-02-06 02:03:58 +03:00
if ( ! buf )
return False ;
buflen = len ;
goto again ;
}
q - > buf = buf ;
q - > buflen = buflen ;
return True ;
}
2002-09-25 19:19:00 +04:00
/*******************************************************************
2002-11-07 05:15:35 +03:00
Send the batched messages - on a per - printer basis .
2002-09-25 19:19:00 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-05-15 00:31:28 +04:00
static void print_notify_send_messages_to_printer ( struct messaging_context * msg_ctx ,
const char * printer ,
unsigned int timeout )
2002-09-25 19:19:00 +04:00
{
char * buf ;
2002-11-07 05:15:35 +03:00
struct notify_queue * pq , * pq_next ;
2002-09-25 19:19:00 +04:00
size_t msg_count = 0 , offset = 0 ;
2002-11-07 05:15:35 +03:00
size_t num_pids = 0 ;
size_t i ;
pid_t * pid_list = NULL ;
2007-05-20 23:43:49 +04:00
struct timeval end_time = timeval_zero ( ) ;
2002-09-25 19:19:00 +04:00
/* Count the space needed to send the messages. */
2002-11-07 05:15:35 +03:00
for ( pq = notify_queue_head ; pq ; pq = pq - > next ) {
2003-02-06 02:03:58 +03:00
if ( strequal ( printer , pq - > msg - > printer ) ) {
if ( ! flatten_message ( pq ) ) {
DEBUG ( 0 , ( " print_notify_send_messages: Out of memory \n " ) ) ;
2005-05-03 11:33:49 +04:00
talloc_free_children ( send_ctx ) ;
2003-04-10 22:43:13 +04:00
num_messages = 0 ;
2003-02-06 02:03:58 +03:00
return ;
}
2002-11-07 05:15:35 +03:00
offset + = ( pq - > buflen + 4 ) ;
msg_count + + ;
}
}
2002-09-25 19:19:00 +04:00
offset + = 4 ; /* For count. */
2006-08-17 18:28:03 +04:00
buf = ( char * ) TALLOC ( send_ctx , offset ) ;
2002-09-25 19:19:00 +04:00
if ( ! buf ) {
DEBUG ( 0 , ( " print_notify_send_messages: Out of memory \n " ) ) ;
2005-05-03 11:33:49 +04:00
talloc_free_children ( send_ctx ) ;
2003-04-10 22:43:13 +04:00
num_messages = 0 ;
2002-09-25 19:19:00 +04:00
return ;
}
offset = 0 ;
SIVAL ( buf , offset , msg_count ) ;
offset + = 4 ;
2002-11-07 05:15:35 +03:00
for ( pq = notify_queue_head ; pq ; pq = pq_next ) {
pq_next = pq - > next ;
2003-02-06 02:03:58 +03:00
if ( strequal ( printer , pq - > msg - > printer ) ) {
2002-11-07 05:15:35 +03:00
SIVAL ( buf , offset , pq - > buflen ) ;
offset + = 4 ;
memcpy ( buf + offset , pq - > buf , pq - > buflen ) ;
offset + = pq - > buflen ;
/* Remove from list. */
DLIST_REMOVE ( notify_queue_head , pq ) ;
}
2002-09-25 19:19:00 +04:00
}
2003-07-25 08:24:40 +04:00
DEBUG ( 5 , ( " print_notify_send_messages_to_printer: sending %lu print notify message%s to printer %s \n " ,
( unsigned long ) msg_count , msg_count ! = 1 ? " s " : " " , printer ) ) ;
2002-11-07 05:15:35 +03:00
/*
* Get the list of PID ' s to send to .
*/
if ( ! print_notify_pid_list ( printer , send_ctx , & num_pids , & pid_list ) )
return ;
2007-05-20 23:43:49 +04:00
if ( timeout ! = 0 ) {
end_time = timeval_current_ofs ( timeout , 0 ) ;
}
2003-04-23 04:19:30 +04:00
for ( i = 0 ; i < num_pids ; i + + ) {
2007-05-20 23:43:49 +04:00
messaging_send_buf ( msg_ctx ,
pid_to_procid ( pid_list [ i ] ) ,
2007-05-24 15:09:37 +04:00
MSG_PRINTER_NOTIFY2 | MSG_FLAG_LOWPRIORITY ,
2007-05-20 23:43:49 +04:00
( uint8 * ) buf , offset ) ;
if ( ( timeout ! = 0 ) & & timeval_expired ( & end_time ) ) {
break ;
}
2003-04-23 04:19:30 +04:00
}
2002-11-07 05:15:35 +03:00
}
/*******************************************************************
Actually send the batched messages .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-05-15 00:31:28 +04:00
void print_notify_send_messages ( struct messaging_context * msg_ctx ,
unsigned int timeout )
2002-11-07 05:15:35 +03:00
{
if ( ! print_notify_messages_pending ( ) )
return ;
2003-02-06 02:03:58 +03:00
if ( ! create_send_ctx ( ) )
2002-11-07 05:15:35 +03:00
return ;
while ( print_notify_messages_pending ( ) )
2007-05-15 00:31:28 +04:00
print_notify_send_messages_to_printer (
msg_ctx , notify_queue_head - > msg - > printer , timeout ) ;
2002-09-25 19:19:00 +04:00
2005-05-03 11:33:49 +04:00
talloc_free_children ( send_ctx ) ;
2003-04-10 22:43:13 +04:00
num_messages = 0 ;
2002-09-25 19:19:00 +04:00
}
2008-10-04 01:18:35 +04:00
/*******************************************************************
Event handler to send the messages .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-01-21 09:39:28 +03:00
static void print_notify_event_send_messages ( struct tevent_context * event_ctx ,
struct tevent_timer * te ,
struct timeval now ,
void * private_data )
2008-10-04 01:18:35 +04:00
{
/* Remove this timed event handler. */
TALLOC_FREE ( notify_event ) ;
change_to_root_user ( ) ;
print_notify_send_messages ( smbd_messaging_context ( ) , 0 ) ;
}
2003-02-16 02:33:30 +03:00
/**********************************************************************
deep copy a SPOOLSS_NOTIFY_MSG structure using a TALLOC_CTX
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static bool copy_notify2_msg ( SPOOLSS_NOTIFY_MSG * to , SPOOLSS_NOTIFY_MSG * from )
2003-02-16 02:33:30 +03:00
{
if ( ! to | | ! from )
return False ;
memcpy ( to , from , sizeof ( SPOOLSS_NOTIFY_MSG ) ) ;
if ( from - > len ) {
2006-08-17 18:28:03 +04:00
to - > notify . data = ( char * ) TALLOC_MEMDUP ( send_ctx , from - > notify . data , from - > len ) ;
2003-02-16 02:33:30 +03:00
if ( ! to - > notify . data ) {
2007-04-28 03:18:41 +04:00
DEBUG ( 0 , ( " copy_notify2_msg: TALLOC_MEMDUP() of size [%d] failed! \n " , from - > len ) ) ;
2003-02-16 02:33:30 +03:00
return False ;
}
}
return True ;
}
2002-09-25 19:19:00 +04:00
/*******************************************************************
Batch up print notify messages .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-06-28 04:17:15 +04:00
2003-02-16 02:33:30 +03:00
static void send_spoolss_notify2_msg ( SPOOLSS_NOTIFY_MSG * msg )
2002-06-28 04:17:15 +04:00
{
2002-09-25 19:19:00 +04:00
struct notify_queue * pnqueue , * tmp_ptr ;
2002-06-28 04:17:15 +04:00
2003-02-06 02:03:58 +03:00
/*
2003-04-10 22:43:13 +04:00
* Ensure we only have one job total_bytes and job total_pages for
* each job . There is no point in sending multiple messages that match
2003-02-06 02:03:58 +03:00
* as they will just cause flickering updates in the client .
*/
2002-06-28 04:17:15 +04:00
2004-08-31 19:11:41 +04:00
if ( ( num_messages < 100 ) & & ( msg - > type = = JOB_NOTIFY_TYPE )
& & ( msg - > field = = JOB_NOTIFY_TOTAL_BYTES
| | msg - > field = = JOB_NOTIFY_TOTAL_PAGES ) )
{
2003-04-10 22:43:13 +04:00
2004-08-31 19:11:41 +04:00
for ( tmp_ptr = notify_queue_head ; tmp_ptr ; tmp_ptr = tmp_ptr - > next )
{
2003-04-10 22:43:13 +04:00
if ( tmp_ptr - > msg - > type = = msg - > type & &
tmp_ptr - > msg - > field = = msg - > field & &
tmp_ptr - > msg - > id = = msg - > id & &
tmp_ptr - > msg - > flags = = msg - > flags & &
strequal ( tmp_ptr - > msg - > printer , msg - > printer ) ) {
2002-06-28 04:17:15 +04:00
2004-08-31 19:11:41 +04:00
DEBUG ( 5 , ( " send_spoolss_notify2_msg: replacing message 0x%02x/0x%02x for "
" printer %s in notify_queue \n " , msg - > type , msg - > field , msg - > printer ) ) ;
2002-06-28 04:17:15 +04:00
2003-04-10 22:43:13 +04:00
tmp_ptr - > msg = msg ;
return ;
}
2003-02-06 02:03:58 +03:00
}
2002-06-28 04:17:15 +04:00
}
2002-09-25 19:19:00 +04:00
/* Store the message on the pending queue. */
2002-06-28 04:17:15 +04:00
2004-12-07 21:25:53 +03:00
pnqueue = TALLOC_P ( send_ctx , struct notify_queue ) ;
2003-02-06 02:03:58 +03:00
if ( ! pnqueue ) {
DEBUG ( 0 , ( " send_spoolss_notify2_msg: Out of memory. \n " ) ) ;
return ;
}
2002-11-07 05:15:35 +03:00
2003-02-16 02:33:30 +03:00
/* allocate a new msg structure and copy the fields */
2004-12-07 21:25:53 +03:00
if ( ! ( pnqueue - > msg = TALLOC_P ( send_ctx , SPOOLSS_NOTIFY_MSG ) ) ) {
2003-07-25 08:24:40 +04:00
DEBUG ( 0 , ( " send_spoolss_notify2_msg: talloc() of size [%lu] failed! \n " ,
( unsigned long ) sizeof ( SPOOLSS_NOTIFY_MSG ) ) ) ;
2003-02-16 02:33:30 +03:00
return ;
}
copy_notify2_msg ( pnqueue - > msg , msg ) ;
2004-07-02 02:55:38 +04:00
GetTimeOfDay ( & pnqueue - > tv ) ;
2003-02-06 02:03:58 +03:00
pnqueue - > buf = NULL ;
pnqueue - > buflen = 0 ;
2002-09-25 19:19:00 +04:00
2002-11-07 05:15:35 +03:00
DEBUG ( 5 , ( " send_spoolss_notify2_msg: appending message 0x%02x/0x%02x for printer %s \
to notify_queue_head \ n " , msg->type, msg->field, msg->printer));
2003-02-06 02:03:58 +03:00
/*
* Note we add to the end of the list to ensure
2002-09-25 19:19:00 +04:00
* the messages are sent in the order they were received . JRA .
*/
2006-09-18 11:52:16 +04:00
DLIST_ADD_END ( notify_queue_head , pnqueue , struct notify_queue * ) ;
2003-04-10 22:43:13 +04:00
num_messages + + ;
2008-10-04 01:18:35 +04:00
2008-12-30 16:05:26 +03:00
if ( ( notify_event = = NULL ) & & ( smbd_event_context ( ) ! = NULL ) ) {
2008-10-04 01:18:35 +04:00
/* Add an event for 1 second's time to send this queue. */
2009-01-21 09:39:28 +03:00
notify_event = tevent_add_timer ( smbd_event_context ( ) , NULL ,
2008-10-04 01:18:35 +04:00
timeval_current_ofs ( 1 , 0 ) ,
print_notify_event_send_messages , NULL ) ;
}
2002-06-28 04:17:15 +04:00
}
2004-10-19 21:05:01 +04:00
static void send_notify_field_values ( const char * sharename , uint32 type ,
2002-06-28 04:17:15 +04:00
uint32 field , uint32 id , uint32 value1 ,
uint32 value2 , uint32 flags )
{
2003-02-06 02:03:58 +03:00
struct spoolss_notify_msg * msg ;
2002-06-28 04:17:15 +04:00
2003-02-06 02:03:58 +03:00
if ( lp_disable_spoolss ( ) )
return ;
2002-06-28 04:17:15 +04:00
2003-02-06 02:03:58 +03:00
if ( ! create_send_ctx ( ) )
return ;
2002-06-28 04:17:15 +04:00
2004-12-07 21:25:53 +03:00
msg = TALLOC_P ( send_ctx , struct spoolss_notify_msg ) ;
2003-02-06 02:03:58 +03:00
if ( ! msg )
return ;
ZERO_STRUCTP ( msg ) ;
2004-10-19 21:05:01 +04:00
fstrcpy ( msg - > printer , sharename ) ;
2003-02-06 02:03:58 +03:00
msg - > type = type ;
msg - > field = field ;
msg - > id = id ;
msg - > notify . value [ 0 ] = value1 ;
msg - > notify . value [ 1 ] = value2 ;
msg - > flags = flags ;
send_spoolss_notify2_msg ( msg ) ;
2002-06-28 04:17:15 +04:00
}
2004-10-19 21:05:01 +04:00
static void send_notify_field_buffer ( const char * sharename , uint32 type ,
2002-06-28 04:17:15 +04:00
uint32 field , uint32 id , uint32 len ,
2005-09-30 21:13:37 +04:00
const char * buffer )
2002-06-28 04:17:15 +04:00
{
2003-02-06 02:03:58 +03:00
struct spoolss_notify_msg * msg ;
if ( lp_disable_spoolss ( ) )
return ;
2002-06-28 04:17:15 +04:00
2003-02-06 02:03:58 +03:00
if ( ! create_send_ctx ( ) )
return ;
2004-12-07 21:25:53 +03:00
msg = TALLOC_P ( send_ctx , struct spoolss_notify_msg ) ;
2003-02-06 02:03:58 +03:00
if ( ! msg )
return ;
2002-06-28 04:17:15 +04:00
2003-02-06 02:03:58 +03:00
ZERO_STRUCTP ( msg ) ;
2002-06-28 04:17:15 +04:00
2004-10-19 21:05:01 +04:00
fstrcpy ( msg - > printer , sharename ) ;
2003-02-06 02:03:58 +03:00
msg - > type = type ;
msg - > field = field ;
msg - > id = id ;
msg - > len = len ;
2005-09-30 21:13:37 +04:00
msg - > notify . data = CONST_DISCARD ( char * , buffer ) ;
2003-02-06 02:03:58 +03:00
send_spoolss_notify2_msg ( msg ) ;
2002-06-28 04:17:15 +04:00
}
/* Send a message that the printer status has changed */
2004-10-19 21:05:01 +04:00
void notify_printer_status_byname ( const char * sharename , uint32 status )
2002-06-28 04:17:15 +04:00
{
/* Printer status stored in value1 */
2009-02-23 13:43:32 +03:00
int snum = print_queue_snum ( sharename ) ;
2004-10-19 21:05:01 +04:00
send_notify_field_values ( sharename , PRINTER_NOTIFY_TYPE ,
2009-02-23 13:43:32 +03:00
PRINTER_NOTIFY_STATUS , snum ,
2002-06-28 04:17:15 +04:00
status , 0 , 0 ) ;
}
void notify_printer_status ( int snum , uint32 status )
{
2004-10-19 21:05:01 +04:00
const char * sharename = SERVICE ( snum ) ;
2002-06-28 04:17:15 +04:00
2004-10-19 21:05:01 +04:00
if ( sharename )
notify_printer_status_byname ( sharename , status ) ;
2002-06-28 04:17:15 +04:00
}
2004-10-19 21:05:01 +04:00
void notify_job_status_byname ( const char * sharename , uint32 jobid , uint32 status ,
2002-06-28 04:17:15 +04:00
uint32 flags )
{
/* Job id stored in id field, status in value1 */
2004-10-19 21:05:01 +04:00
send_notify_field_values ( sharename , JOB_NOTIFY_TYPE ,
2002-06-28 04:17:15 +04:00
JOB_NOTIFY_STATUS , jobid ,
status , 0 , flags ) ;
}
2004-10-19 21:05:01 +04:00
void notify_job_status ( const char * sharename , uint32 jobid , uint32 status )
2002-06-28 04:17:15 +04:00
{
2004-10-19 21:05:01 +04:00
notify_job_status_byname ( sharename , jobid , status , 0 ) ;
2002-06-28 04:17:15 +04:00
}
2004-10-19 21:05:01 +04:00
void notify_job_total_bytes ( const char * sharename , uint32 jobid ,
uint32 size )
2002-06-28 04:17:15 +04:00
{
/* Job id stored in id field, status in value1 */
2004-10-19 21:05:01 +04:00
send_notify_field_values ( sharename , JOB_NOTIFY_TYPE ,
2002-06-28 04:17:15 +04:00
JOB_NOTIFY_TOTAL_BYTES , jobid ,
size , 0 , 0 ) ;
}
2004-10-19 21:05:01 +04:00
void notify_job_total_pages ( const char * sharename , uint32 jobid ,
uint32 pages )
2002-06-28 04:17:15 +04:00
{
/* Job id stored in id field, status in value1 */
2004-10-19 21:05:01 +04:00
send_notify_field_values ( sharename , JOB_NOTIFY_TYPE ,
2002-06-28 04:17:15 +04:00
JOB_NOTIFY_TOTAL_PAGES , jobid ,
pages , 0 , 0 ) ;
}
2004-10-19 21:05:01 +04:00
void notify_job_username ( const char * sharename , uint32 jobid , char * name )
2002-06-28 04:17:15 +04:00
{
send_notify_field_buffer (
2004-10-19 21:05:01 +04:00
sharename , JOB_NOTIFY_TYPE , JOB_NOTIFY_USER_NAME ,
2002-06-28 04:17:15 +04:00
jobid , strlen ( name ) + 1 , name ) ;
}
2004-10-19 21:05:01 +04:00
void notify_job_name ( const char * sharename , uint32 jobid , char * name )
2002-06-28 04:17:15 +04:00
{
send_notify_field_buffer (
2004-10-19 21:05:01 +04:00
sharename , JOB_NOTIFY_TYPE , JOB_NOTIFY_DOCUMENT ,
2002-06-28 04:17:15 +04:00
jobid , strlen ( name ) + 1 , name ) ;
}
2004-10-19 21:05:01 +04:00
void notify_job_submitted ( const char * sharename , uint32 jobid ,
time_t submitted )
2002-06-28 04:17:15 +04:00
{
send_notify_field_buffer (
2004-10-19 21:05:01 +04:00
sharename , JOB_NOTIFY_TYPE , JOB_NOTIFY_SUBMITTED ,
2002-06-28 04:17:15 +04:00
jobid , sizeof ( submitted ) , ( char * ) & submitted ) ;
}
2002-08-17 20:31:24 +04:00
void notify_printer_driver ( int snum , char * driver_name )
2002-06-28 04:17:15 +04:00
{
2004-10-19 21:05:01 +04:00
const char * sharename = SERVICE ( snum ) ;
2002-06-28 04:17:15 +04:00
2002-08-17 20:31:24 +04:00
send_notify_field_buffer (
2004-10-19 21:05:01 +04:00
sharename , PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_DRIVER_NAME ,
2002-08-17 20:31:24 +04:00
snum , strlen ( driver_name ) + 1 , driver_name ) ;
2002-06-28 04:17:15 +04:00
}
2002-08-17 20:31:24 +04:00
void notify_printer_comment ( int snum , char * comment )
2002-06-28 04:17:15 +04:00
{
2004-10-19 21:05:01 +04:00
const char * sharename = SERVICE ( snum ) ;
2002-06-28 04:17:15 +04:00
2002-08-17 20:31:24 +04:00
send_notify_field_buffer (
2004-10-19 21:05:01 +04:00
sharename , PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_COMMENT ,
2002-08-17 20:31:24 +04:00
snum , strlen ( comment ) + 1 , comment ) ;
2002-06-28 04:17:15 +04:00
}
2002-08-17 20:31:24 +04:00
void notify_printer_sharename ( int snum , char * share_name )
2002-06-28 04:17:15 +04:00
{
2004-10-19 21:05:01 +04:00
const char * sharename = SERVICE ( snum ) ;
2002-08-17 20:31:24 +04:00
send_notify_field_buffer (
2004-10-19 21:05:01 +04:00
sharename , PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_SHARE_NAME ,
2002-08-17 20:31:24 +04:00
snum , strlen ( share_name ) + 1 , share_name ) ;
2002-06-28 04:17:15 +04:00
}
2004-05-27 19:38:54 +04:00
void notify_printer_printername ( int snum , char * printername )
{
2004-10-19 21:05:01 +04:00
const char * sharename = SERVICE ( snum ) ;
2004-05-27 19:38:54 +04:00
send_notify_field_buffer (
2004-10-19 21:05:01 +04:00
sharename , PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_PRINTER_NAME ,
2004-05-27 19:38:54 +04:00
snum , strlen ( printername ) + 1 , printername ) ;
}
2002-08-17 20:31:24 +04:00
void notify_printer_port ( int snum , char * port_name )
2002-06-28 04:17:15 +04:00
{
2004-10-19 21:05:01 +04:00
const char * sharename = SERVICE ( snum ) ;
2002-08-17 20:31:24 +04:00
send_notify_field_buffer (
2004-10-19 21:05:01 +04:00
sharename , PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_PORT_NAME ,
2002-08-17 20:31:24 +04:00
snum , strlen ( port_name ) + 1 , port_name ) ;
2002-06-28 04:17:15 +04:00
}
2002-08-17 20:31:24 +04:00
void notify_printer_location ( int snum , char * location )
2002-06-28 04:17:15 +04:00
{
2004-10-19 21:05:01 +04:00
const char * sharename = SERVICE ( snum ) ;
2002-08-17 20:31:24 +04:00
send_notify_field_buffer (
2004-10-19 21:05:01 +04:00
sharename , PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_LOCATION ,
2002-08-17 20:31:24 +04:00
snum , strlen ( location ) + 1 , location ) ;
2002-06-28 04:17:15 +04:00
}
2002-11-26 03:46:31 +03:00
2005-09-30 21:13:37 +04:00
void notify_printer_byname ( const char * printername , uint32 change , const char * value )
2002-11-26 03:46:31 +03:00
{
int snum = print_queue_snum ( printername ) ;
int type = PRINTER_NOTIFY_TYPE ;
if ( snum = = - 1 )
return ;
2003-02-15 01:25:12 +03:00
send_notify_field_buffer ( printername , type , change , snum , strlen ( value ) + 1 , value ) ;
2002-11-26 03:46:31 +03:00
}
/****************************************************************************
Return a malloced list of pid_t ' s that are interested in getting update
messages on this print queue . Used in printing / notify to send the messages .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-01-21 09:39:28 +03:00
static bool print_notify_pid_list ( const char * printername , TALLOC_CTX * mem_ctx ,
size_t * p_num_pids , pid_t * * pp_pid_list )
2002-11-26 03:46:31 +03:00
{
struct tdb_print_db * pdb = NULL ;
TDB_CONTEXT * tdb = NULL ;
TDB_DATA data ;
2007-10-19 04:40:25 +04:00
bool ret = True ;
2002-11-26 03:46:31 +03:00
size_t i , num_pids , offset ;
pid_t * pid_list ;
* p_num_pids = 0 ;
* pp_pid_list = NULL ;
pdb = get_print_db_byname ( printername ) ;
if ( ! pdb )
return False ;
tdb = pdb - > tdb ;
2006-04-17 15:49:06 +04:00
if ( tdb_read_lock_bystring_with_timeout ( tdb , NOTIFY_PID_LIST_KEY , 10 ) = = - 1 ) {
2002-11-26 03:46:31 +03:00
DEBUG ( 0 , ( " print_notify_pid_list: Failed to lock printer %s database \n " ,
printername ) ) ;
if ( pdb )
release_print_db ( pdb ) ;
return False ;
}
data = get_printer_notify_pid_list ( tdb , printername , True ) ;
if ( ! data . dptr ) {
ret = True ;
goto done ;
}
num_pids = data . dsize / 8 ;
2007-04-30 06:39:34 +04:00
if ( num_pids ) {
if ( ( pid_list = TALLOC_ARRAY ( mem_ctx , pid_t , num_pids ) ) = = NULL ) {
ret = False ;
goto done ;
}
} else {
pid_list = NULL ;
2002-11-26 03:46:31 +03:00
}
2007-07-29 13:51:06 +04:00
for ( i = 0 , offset = 0 ; i < num_pids ; offset + = 8 , i + + )
2002-11-26 03:46:31 +03:00
pid_list [ i ] = ( pid_t ) IVAL ( data . dptr , offset ) ;
* pp_pid_list = pid_list ;
* p_num_pids = num_pids ;
ret = True ;
done :
tdb_read_unlock_bystring ( tdb , NOTIFY_PID_LIST_KEY ) ;
if ( pdb )
release_print_db ( pdb ) ;
SAFE_FREE ( data . dptr ) ;
return ret ;
}