1/* 2 Unix SMB/CIFS implementation. 3 printing command routines 4 Copyright (C) Andrew Tridgell 1992-2000 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18*/ 19 20#include "includes.h" 21#include "printing.h" 22 23extern struct current_user current_user; 24extern userdom_struct current_user_info; 25 26/**************************************************************************** 27 Run a given print command 28 a null terminated list of value/substitute pairs is provided 29 for local substitution strings 30****************************************************************************/ 31static int print_run_command(int snum, const char* printername, bool do_sub, 32 const char *command, int *outfd, ...) 33{ 34 char *syscmd; 35 char *arg; 36 int ret; 37 TALLOC_CTX *ctx = talloc_tos(); 38 va_list ap; 39 va_start(ap, outfd); 40 41 /* check for a valid system printername and valid command to run */ 42 43 if ( !printername || !*printername ) { 44 va_end(ap); 45 return -1; 46 } 47 48 if (!command || !*command) { 49 va_end(ap); 50 return -1; 51 } 52 53 syscmd = talloc_strdup(ctx, command); 54 if (!syscmd) { 55 va_end(ap); 56 return -1; 57 } 58 59 while ((arg = va_arg(ap, char *))) { 60 char *value = va_arg(ap,char *); 61 syscmd = talloc_string_sub(ctx, syscmd, arg, value); 62 if (!syscmd) { 63 va_end(ap); 64 return -1; 65 } 66 } 67 va_end(ap); 68 69 syscmd = talloc_string_sub(ctx, syscmd, "%p", printername); 70 if (!syscmd) { 71 return -1; 72 } 73 74 if (do_sub && snum != -1) { 75 syscmd = talloc_sub_advanced(ctx, 76 lp_servicename(snum), 77 current_user_info.unix_name, 78 "", 79 current_user.ut.gid, 80 get_current_username(), 81 current_user_info.domain, 82 syscmd); 83 if (!syscmd) { 84 return -1; 85 } 86 } 87 88 ret = smbrun_no_sanitize(syscmd,outfd); 89 90 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); 91 92 return ret; 93} 94 95 96/**************************************************************************** 97delete a print job 98****************************************************************************/ 99static int generic_job_delete( const char *sharename, const char *lprm_command, struct printjob *pjob) 100{ 101 fstring jobstr; 102 103 /* need to delete the spooled entry */ 104 slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob); 105 return print_run_command( -1, sharename, False, lprm_command, NULL, 106 "%j", jobstr, 107 "%T", http_timestring(talloc_tos(), pjob->starttime), 108 NULL); 109} 110 111/**************************************************************************** 112pause a job 113****************************************************************************/ 114static int generic_job_pause(int snum, struct printjob *pjob) 115{ 116 fstring jobstr; 117 118 /* need to pause the spooled entry */ 119 slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob); 120 return print_run_command(snum, PRINTERNAME(snum), True, 121 lp_lppausecommand(snum), NULL, 122 "%j", jobstr, 123 NULL); 124} 125 126/**************************************************************************** 127resume a job 128****************************************************************************/ 129static int generic_job_resume(int snum, struct printjob *pjob) 130{ 131 fstring jobstr; 132 133 /* need to pause the spooled entry */ 134 slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob); 135 return print_run_command(snum, PRINTERNAME(snum), True, 136 lp_lpresumecommand(snum), NULL, 137 "%j", jobstr, 138 NULL); 139} 140 141/**************************************************************************** 142 Submit a file for printing - called from print_job_end() 143****************************************************************************/ 144 145static int generic_job_submit(int snum, struct printjob *pjob) 146{ 147 int ret = -1; 148 char *current_directory = NULL; 149 char *print_directory = NULL; 150 char *wd = NULL; 151 char *p = NULL; 152 char *jobname = NULL; 153 TALLOC_CTX *ctx = talloc_tos(); 154 fstring job_page_count, job_size; 155 156 /* we print from the directory path to give the best chance of 157 parsing the lpq output */ 158 current_directory = TALLOC_ARRAY(ctx, 159 char, 160 PATH_MAX+1); 161 if (!current_directory) { 162 return -1; 163 } 164 wd = sys_getwd(current_directory); 165 if (!wd) { 166 return -1; 167 } 168 169 print_directory = talloc_strdup(ctx, pjob->filename); 170 if (!print_directory) { 171 return -1; 172 } 173 p = strrchr_m(print_directory,'/'); 174 if (!p) { 175 return -1; 176 } 177 *p++ = 0; 178 179 if (chdir(print_directory) != 0) { 180 return -1; 181 } 182 183 jobname = talloc_strdup(ctx, pjob->jobname); 184 if (!jobname) { 185 ret = -1; 186 goto out; 187 } 188 jobname = talloc_string_sub(ctx, jobname, "'", "_"); 189 if (!jobname) { 190 ret = -1; 191 goto out; 192 } 193 slprintf(job_page_count, sizeof(job_page_count)-1, "%d", pjob->page_count); 194 slprintf(job_size, sizeof(job_size)-1, "%lu", (unsigned long)pjob->size); 195 196 /* send it to the system spooler */ 197 ret = print_run_command(snum, PRINTERNAME(snum), True, 198 lp_printcommand(snum), NULL, 199 "%s", p, 200 "%J", jobname, 201 "%f", p, 202 "%z", job_size, 203 "%c", job_page_count, 204 NULL); 205 206 out: 207 208 if (chdir(wd) == -1) { 209 smb_panic("chdir failed in generic_job_submit"); 210 } 211 TALLOC_FREE(current_directory); 212 return ret; 213} 214 215 216/**************************************************************************** 217get the current list of queued jobs 218****************************************************************************/ 219static int generic_queue_get(const char *printer_name, 220 enum printing_types printing_type, 221 char *lpq_command, 222 print_queue_struct **q, 223 print_status_struct *status) 224{ 225 char **qlines; 226 int fd; 227 int numlines, i, qcount; 228 print_queue_struct *queue = NULL; 229 230 /* never do substitution when running the 'lpq command' since we can't 231 get it rigt when using the background update daemon. Make the caller 232 do it before passing off the command string to us here. */ 233 234 print_run_command(-1, printer_name, False, lpq_command, &fd, NULL); 235 236 if (fd == -1) { 237 DEBUG(5,("generic_queue_get: Can't read print queue status for printer %s\n", 238 printer_name )); 239 return 0; 240 } 241 242 numlines = 0; 243 qlines = fd_lines_load(fd, &numlines,0,NULL); 244 close(fd); 245 246 /* turn the lpq output into a series of job structures */ 247 qcount = 0; 248 ZERO_STRUCTP(status); 249 if (numlines && qlines) { 250 queue = SMB_MALLOC_ARRAY(print_queue_struct, numlines+1); 251 if (!queue) { 252 TALLOC_FREE(qlines); 253 *q = NULL; 254 return 0; 255 } 256 memset(queue, '\0', sizeof(print_queue_struct)*(numlines+1)); 257 258 for (i=0; i<numlines; i++) { 259 /* parse the line */ 260 if (parse_lpq_entry(printing_type,qlines[i], 261 &queue[qcount],status,qcount==0)) { 262 qcount++; 263 } 264 } 265 } 266 267 TALLOC_FREE(qlines); 268 *q = queue; 269 return qcount; 270} 271 272/**************************************************************************** 273 pause a queue 274****************************************************************************/ 275static int generic_queue_pause(int snum) 276{ 277 return print_run_command(snum, PRINTERNAME(snum), True, lp_queuepausecommand(snum), NULL, NULL); 278} 279 280/**************************************************************************** 281 resume a queue 282****************************************************************************/ 283static int generic_queue_resume(int snum) 284{ 285 return print_run_command(snum, PRINTERNAME(snum), True, lp_queueresumecommand(snum), NULL, NULL); 286} 287 288/**************************************************************************** 289 * Generic printing interface definitions... 290 ***************************************************************************/ 291 292struct printif generic_printif = 293{ 294 DEFAULT_PRINTING, 295 generic_queue_get, 296 generic_queue_pause, 297 generic_queue_resume, 298 generic_job_delete, 299 generic_job_pause, 300 generic_job_resume, 301 generic_job_submit, 302}; 303 304