2001-03-16 03:35:57 +03:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2001-03-16 03:35:57 +03:00
printing command routines
Copyright ( C ) Andrew Tridgell 1992 - 2000
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
2001-03-16 03:35:57 +03: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/>.
2001-03-16 03:35:57 +03:00
*/
2003-11-12 04:51:10 +03:00
# include "includes.h"
2001-03-16 03:35:57 +03:00
# include "printing.h"
2006-12-12 20:38:42 +03:00
extern struct current_user current_user ;
extern userdom_struct current_user_info ;
2001-03-16 03:35:57 +03:00
/****************************************************************************
2007-11-22 00:56:36 +03:00
Run a given print command
a null terminated list of value / substitute pairs is provided
for local substitution strings
2001-03-16 03:35:57 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static int print_run_command ( int snum , const char * printername , bool do_sub ,
2005-09-30 21:13:37 +04:00
const char * command , int * outfd , . . . )
2001-03-16 03:35:57 +03:00
{
2007-11-22 00:56:36 +03:00
char * syscmd ;
2002-07-15 14:35:28 +04:00
char * arg ;
2001-03-16 03:35:57 +03:00
int ret ;
2007-11-22 00:56:36 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2001-03-16 03:35:57 +03:00
va_list ap ;
2001-04-13 23:12:06 +04:00
va_start ( ap , outfd ) ;
2001-04-11 02:01:53 +04:00
2004-10-19 21:05:01 +04:00
/* check for a valid system printername and valid command to run */
2001-03-16 03:35:57 +03:00
2007-11-22 00:56:36 +03:00
if ( ! printername | | ! * printername ) {
2008-01-27 09:31:56 +03:00
va_end ( ap ) ;
2004-10-19 21:05:01 +04:00
return - 1 ;
2007-11-22 00:56:36 +03:00
}
2004-10-19 21:05:01 +04:00
2007-11-22 00:56:36 +03:00
if ( ! command | | ! * command ) {
2008-01-27 09:31:56 +03:00
va_end ( ap ) ;
2001-03-16 03:35:57 +03:00
return - 1 ;
2007-11-22 00:56:36 +03:00
}
2001-03-16 03:35:57 +03:00
2007-11-22 00:56:36 +03:00
syscmd = talloc_strdup ( ctx , command ) ;
if ( ! syscmd ) {
2008-01-27 09:31:56 +03:00
va_end ( ap ) ;
2007-11-22 00:56:36 +03:00
return - 1 ;
}
2001-03-16 03:35:57 +03:00
while ( ( arg = va_arg ( ap , char * ) ) ) {
char * value = va_arg ( ap , char * ) ;
2007-11-22 00:56:36 +03:00
syscmd = talloc_string_sub ( ctx , syscmd , arg , value ) ;
if ( ! syscmd ) {
2008-01-27 09:31:56 +03:00
va_end ( ap ) ;
2007-11-22 00:56:36 +03:00
return - 1 ;
}
2001-03-16 03:35:57 +03:00
}
va_end ( ap ) ;
2007-11-22 00:56:36 +03:00
syscmd = talloc_string_sub ( ctx , syscmd , " %p " , printername ) ;
if ( ! syscmd ) {
return - 1 ;
}
if ( do_sub & & snum ! = - 1 ) {
syscmd = talloc_sub_advanced ( ctx ,
lp_servicename ( snum ) ,
current_user_info . unix_name ,
" " ,
current_user . ut . gid ,
get_current_username ( ) ,
current_user_info . domain ,
syscmd ) ;
if ( ! syscmd ) {
return - 1 ;
}
}
2007-05-14 18:23:51 +04:00
ret = smbrun_no_sanitize ( syscmd , outfd ) ;
2001-03-16 03:35:57 +03:00
DEBUG ( 3 , ( " Running the command `%s' gave %d \n " , syscmd , ret ) ) ;
return ret ;
}
/****************************************************************************
delete a print job
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
static int generic_job_delete ( const char * sharename , const char * lprm_command , struct printjob * pjob )
2001-03-16 03:35:57 +03:00
{
fstring jobstr ;
/* need to delete the spooled entry */
slprintf ( jobstr , sizeof ( jobstr ) - 1 , " %d " , pjob - > sysjob ) ;
2005-09-30 21:13:37 +04:00
return print_run_command ( - 1 , sharename , False , lprm_command , NULL ,
2001-03-16 03:35:57 +03:00
" %j " , jobstr ,
" %T " , http_timestring ( pjob - > starttime ) ,
NULL ) ;
}
/****************************************************************************
pause a job
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int generic_job_pause ( int snum , struct printjob * pjob )
{
fstring jobstr ;
/* need to pause the spooled entry */
slprintf ( jobstr , sizeof ( jobstr ) - 1 , " %d " , pjob - > sysjob ) ;
2004-10-19 21:05:01 +04:00
return print_run_command ( snum , PRINTERNAME ( snum ) , True ,
2001-04-14 04:19:12 +04:00
lp_lppausecommand ( snum ) , NULL ,
2001-03-16 03:35:57 +03:00
" %j " , jobstr ,
NULL ) ;
}
/****************************************************************************
resume a job
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int generic_job_resume ( int snum , struct printjob * pjob )
{
fstring jobstr ;
2007-11-22 00:56:36 +03:00
2001-03-16 03:35:57 +03:00
/* need to pause the spooled entry */
slprintf ( jobstr , sizeof ( jobstr ) - 1 , " %d " , pjob - > sysjob ) ;
2004-10-19 21:05:01 +04:00
return print_run_command ( snum , PRINTERNAME ( snum ) , True ,
2001-04-14 04:19:12 +04:00
lp_lpresumecommand ( snum ) , NULL ,
2001-03-16 03:35:57 +03:00
" %j " , jobstr ,
NULL ) ;
}
/****************************************************************************
Submit a file for printing - called from print_job_end ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int generic_job_submit ( int snum , struct printjob * pjob )
{
2007-11-22 00:56:36 +03:00
int ret = - 1 ;
char * current_directory = NULL ;
char * print_directory = NULL ;
char * wd = NULL ;
char * p = NULL ;
char * jobname = NULL ;
TALLOC_CTX * ctx = talloc_tos ( ) ;
2002-03-20 02:33:32 +03:00
fstring job_page_count , job_size ;
2001-03-16 03:35:57 +03:00
/* we print from the directory path to give the best chance of
parsing the lpq output */
2007-11-22 00:56:36 +03:00
current_directory = TALLOC_ARRAY ( ctx ,
char ,
PATH_MAX + 1 ) ;
if ( ! current_directory ) {
return - 1 ;
}
2001-03-16 03:35:57 +03:00
wd = sys_getwd ( current_directory ) ;
2007-11-22 00:56:36 +03:00
if ( ! wd ) {
return - 1 ;
}
2001-03-16 03:35:57 +03:00
2007-11-22 00:56:36 +03:00
print_directory = talloc_strdup ( ctx , pjob - > filename ) ;
if ( ! print_directory ) {
return - 1 ;
}
2001-07-04 11:36:09 +04:00
p = strrchr_m ( print_directory , ' / ' ) ;
2007-11-22 00:56:36 +03:00
if ( ! p ) {
return - 1 ;
}
2001-03-16 03:35:57 +03:00
* p + + = 0 ;
2007-11-22 00:56:36 +03:00
if ( chdir ( print_directory ) ! = 0 ) {
return - 1 ;
}
2001-03-16 03:35:57 +03:00
2007-11-22 00:56:36 +03:00
jobname = talloc_strdup ( ctx , pjob - > jobname ) ;
if ( ! jobname ) {
ret = - 1 ;
goto out ;
}
jobname = talloc_string_sub ( ctx , jobname , " ' " , " _ " ) ;
if ( ! jobname ) {
ret = - 1 ;
goto out ;
}
2002-03-20 02:33:32 +03:00
slprintf ( job_page_count , sizeof ( job_page_count ) - 1 , " %d " , pjob - > page_count ) ;
2003-11-03 17:34:25 +03:00
slprintf ( job_size , sizeof ( job_size ) - 1 , " %lu " , ( unsigned long ) pjob - > size ) ;
2001-03-16 03:35:57 +03:00
/* send it to the system spooler */
2004-10-19 21:05:01 +04:00
ret = print_run_command ( snum , PRINTERNAME ( snum ) , True ,
2002-03-20 02:33:32 +03:00
lp_printcommand ( snum ) , NULL ,
" %s " , p ,
" %J " , jobname ,
" %f " , p ,
" %z " , job_size ,
" %c " , job_page_count ,
NULL ) ;
2001-03-16 03:35:57 +03:00
2007-11-22 00:56:36 +03:00
out :
2001-03-16 03:35:57 +03:00
2007-11-22 00:56:36 +03:00
chdir ( wd ) ;
TALLOC_FREE ( current_directory ) ;
2001-03-16 03:35:57 +03:00
return ret ;
}
/****************************************************************************
get the current list of queued jobs
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-10-19 21:05:01 +04:00
static int generic_queue_get ( const char * printer_name ,
enum printing_types printing_type ,
char * lpq_command ,
print_queue_struct * * q ,
print_status_struct * status )
2001-03-16 03:35:57 +03:00
{
char * * qlines ;
2001-04-13 04:37:00 +04:00
int fd ;
2001-03-16 03:35:57 +03:00
int numlines , i , qcount ;
2001-04-13 23:12:06 +04:00
print_queue_struct * queue = NULL ;
2001-03-16 03:35:57 +03:00
2004-10-19 21:05:01 +04:00
/* never do substitution when running the 'lpq command' since we can't
get it rigt when using the background update daemon . Make the caller
do it before passing off the command string to us here . */
print_run_command ( - 1 , printer_name , False , lpq_command , & fd , NULL ) ;
2001-03-16 03:35:57 +03:00
2001-04-13 04:37:00 +04:00
if ( fd = = - 1 ) {
DEBUG ( 5 , ( " generic_queue_get: Can't read print queue status for printer %s \n " ,
printer_name ) ) ;
return 0 ;
}
2001-03-16 03:35:57 +03:00
numlines = 0 ;
2006-02-04 01:19:41 +03:00
qlines = fd_lines_load ( fd , & numlines , 0 ) ;
2001-04-13 04:37:00 +04:00
close ( fd ) ;
2001-03-16 03:35:57 +03:00
/* turn the lpq output into a series of job structures */
qcount = 0 ;
2001-03-28 22:12:49 +04:00
ZERO_STRUCTP ( status ) ;
2006-06-20 05:27:39 +04:00
if ( numlines & & qlines ) {
2004-12-07 21:25:53 +03:00
queue = SMB_MALLOC_ARRAY ( print_queue_struct , numlines + 1 ) ;
2006-03-08 04:18:18 +03:00
if ( ! queue ) {
file_lines_free ( qlines ) ;
* q = NULL ;
return 0 ;
}
2006-03-08 09:42:39 +03:00
memset ( queue , ' \0 ' , sizeof ( print_queue_struct ) * ( numlines + 1 ) ) ;
for ( i = 0 ; i < numlines ; i + + ) {
/* parse the line */
if ( parse_lpq_entry ( printing_type , qlines [ i ] ,
& queue [ qcount ] , status , qcount = = 0 ) ) {
qcount + + ;
}
}
2001-03-16 03:35:57 +03:00
}
2006-03-08 04:18:18 +03:00
file_lines_free ( qlines ) ;
2001-03-16 03:35:57 +03:00
* q = queue ;
return qcount ;
}
/****************************************************************************
pause a queue
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int generic_queue_pause ( int snum )
{
2004-10-19 21:05:01 +04:00
return print_run_command ( snum , PRINTERNAME ( snum ) , True , lp_queuepausecommand ( snum ) , NULL , NULL ) ;
2001-03-16 03:35:57 +03:00
}
/****************************************************************************
resume a queue
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int generic_queue_resume ( int snum )
{
2004-10-19 21:05:01 +04:00
return print_run_command ( snum , PRINTERNAME ( snum ) , True , lp_queueresumecommand ( snum ) , NULL , NULL ) ;
2001-03-16 03:35:57 +03:00
}
2004-10-19 21:05:01 +04:00
/****************************************************************************
* Generic printing interface definitions . . .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct printif generic_printif =
{
DEFAULT_PRINTING ,
generic_queue_get ,
generic_queue_pause ,
generic_queue_resume ,
generic_job_delete ,
generic_job_pause ,
generic_job_resume ,
generic_job_submit ,
} ;