loadparm: make the source3/ lp_ functions take an explicit TALLOC_CTX *.
[samba.git] / source3 / printing / print_generic.c
index 8525d6208b7644aa872b11263964dbf342735b79..efe910d7b44b80b1b4aa6c107210b04cddc3baca 100644 (file)
@@ -24,45 +24,67 @@ extern struct current_user current_user;
 extern userdom_struct current_user_info;
 
 /****************************************************************************
-run a given print command 
-a null terminated list of value/substitute pairs is provided
-for local substitution strings
+ Run a given print command
+ a null terminated list of value/substitute pairs is provided
+ for local substitution strings
 ****************************************************************************/
 static int print_run_command(int snum, const char* printername, bool do_sub,
                             const char *command, int *outfd, ...)
 {
-       pstring syscmd;
+       char *syscmd;
        char *arg;
        int ret;
+       TALLOC_CTX *ctx = talloc_tos();
        va_list ap;
        va_start(ap, outfd);
 
        /* check for a valid system printername and valid command to run */
 
-       if ( !printername || !*printername ) 
+       if ( !printername || !*printername ) {
+               va_end(ap);
                return -1;
+       }
 
-       if (!command || !*command) 
+       if (!command || !*command) {
+               va_end(ap);
                return -1;
+       }
 
-       pstrcpy(syscmd, command);
+       syscmd = talloc_strdup(ctx, command);
+       if (!syscmd) {
+               va_end(ap);
+               return -1;
+       }
 
        while ((arg = va_arg(ap, char *))) {
                char *value = va_arg(ap,char *);
-               pstring_sub(syscmd, arg, value);
+               syscmd = talloc_string_sub(ctx, syscmd, arg, value);
+               if (!syscmd) {
+                       va_end(ap);
+                       return -1;
+               }
        }
        va_end(ap);
-  
-       pstring_sub( syscmd, "%p", printername );
-
-       if ( do_sub && snum != -1 )
-               standard_sub_advanced(lp_servicename(snum),
-                                     current_user_info.unix_name, "",
-                                     current_user.ut.gid,
-                                     get_current_username(),
-                                     current_user_info.domain,
-                                     syscmd, sizeof(syscmd));
-               
+
+       syscmd = talloc_string_sub(ctx, syscmd, "%p", printername);
+       if (!syscmd) {
+               return -1;
+       }
+
+       if (do_sub && snum != -1) {
+               syscmd = talloc_sub_advanced(ctx,
+                               lp_servicename(talloc_tos(), snum),
+                               current_user_info.unix_name,
+                               "",
+                               current_user.ut.gid,
+                               get_current_username(),
+                               current_user_info.domain,
+                               syscmd);
+               if (!syscmd) {
+                       return -1;
+               }
+       }
+
        ret = smbrun_no_sanitize(syscmd,outfd);
 
        DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
@@ -82,7 +104,7 @@ static int generic_job_delete( const char *sharename, const char *lprm_command,
        slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
        return print_run_command( -1, sharename, False, lprm_command, NULL,
                   "%j", jobstr,
-                  "%T", http_timestring(pjob->starttime),
+                  "%T", http_timestring(talloc_tos(), pjob->starttime),
                   NULL);
 }
 
@@ -95,8 +117,8 @@ static int generic_job_pause(int snum, struct printjob *pjob)
        
        /* need to pause the spooled entry */
        slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
-       return print_run_command(snum, PRINTERNAME(snum), True,
-                                lp_lppausecommand(snum), NULL,
+       return print_run_command(snum, lp_printername(talloc_tos(), snum), True,
+                                lp_lppausecommand(talloc_tos(), snum), NULL,
                                 "%j", jobstr,
                                 NULL);
 }
@@ -107,80 +129,31 @@ resume a job
 static int generic_job_resume(int snum, struct printjob *pjob)
 {
        fstring jobstr;
-       
+
        /* need to pause the spooled entry */
        slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
-       return print_run_command(snum, PRINTERNAME(snum), True,
-                                lp_lpresumecommand(snum), NULL,
+       return print_run_command(snum, lp_printername(talloc_tos(), snum), True,
+                                lp_lpresumecommand(talloc_tos(), snum), NULL,
                                 "%j", jobstr,
                                 NULL);
 }
 
-/****************************************************************************
- Submit a file for printing - called from print_job_end()
-****************************************************************************/
-
-static int generic_job_submit(int snum, struct printjob *pjob)
-{
-       int ret;
-       pstring current_directory;
-       pstring print_directory;
-       char *wd, *p;
-       pstring jobname;
-       fstring job_page_count, job_size;
-
-       /* we print from the directory path to give the best chance of
-           parsing the lpq output */
-       wd = sys_getwd(current_directory);
-       if (!wd)
-               return 0;
-
-       pstrcpy(print_directory, pjob->filename);
-       p = strrchr_m(print_directory,'/');
-       if (!p)
-               return 0;
-       *p++ = 0;
-
-       if (chdir(print_directory) != 0)
-               return 0;
-
-       pstrcpy(jobname, pjob->jobname);
-       pstring_sub(jobname, "'", "_");
-       slprintf(job_page_count, sizeof(job_page_count)-1, "%d", pjob->page_count);
-       slprintf(job_size, sizeof(job_size)-1, "%lu", (unsigned long)pjob->size);
-
-       /* send it to the system spooler */
-       ret = print_run_command(snum, PRINTERNAME(snum), True,
-                       lp_printcommand(snum), NULL,
-                       "%s", p,
-                       "%J", jobname,
-                       "%f", p,
-                       "%z", job_size,
-                       "%c", job_page_count,
-                       NULL);
-
-       chdir(wd);
-
-        return ret;
-}
-
-
 /****************************************************************************
 get the current list of queued jobs
 ****************************************************************************/
-static int generic_queue_get(const char *printer_name, 
+static int generic_queue_get(const char *printer_name,
                              enum printing_types printing_type,
                              char *lpq_command,
-                             print_queue_struct **q, 
+                             print_queue_struct **q,
                              print_status_struct *status)
 {
        char **qlines;
        int fd;
        int numlines, i, qcount;
        print_queue_struct *queue = NULL;
-       
+
        /* never do substitution when running the 'lpq command' since we can't
-          get it rigt when using the background update daemon.  Make the caller 
+          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);
@@ -190,9 +163,9 @@ static int generic_queue_get(const char *printer_name,
                        printer_name ));
                return 0;
        }
-       
+
        numlines = 0;
-       qlines = fd_lines_load(fd, &numlines,0);
+       qlines = fd_lines_load(fd, &numlines,0,NULL);
        close(fd);
 
        /* turn the lpq output into a series of job structures */
@@ -201,7 +174,7 @@ static int generic_queue_get(const char *printer_name,
        if (numlines && qlines) {
                queue = SMB_MALLOC_ARRAY(print_queue_struct, numlines+1);
                if (!queue) {
-                       file_lines_free(qlines);
+                       TALLOC_FREE(qlines);
                        *q = NULL;
                        return 0;
                }
@@ -213,20 +186,129 @@ static int generic_queue_get(const char *printer_name,
                                            &queue[qcount],status,qcount==0)) {
                                qcount++;
                        }
-               }               
+               }
        }
 
-       file_lines_free(qlines);
+       TALLOC_FREE(qlines);
         *q = queue;
        return qcount;
 }
 
+/****************************************************************************
+ Submit a file for printing - called from print_job_end()
+****************************************************************************/
+
+static int generic_job_submit(int snum, struct printjob *pjob,
+                             enum printing_types printing_type,
+                             char *lpq_cmd)
+{
+       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();
+       fstring job_page_count, job_size;
+       print_queue_struct *q;
+       print_status_struct status;
+
+       /* we print from the directory path to give the best chance of
+           parsing the lpq output */
+       wd = sys_getwd();
+       if (!wd) {
+               return -1;
+       }
+
+       current_directory = talloc_strdup(ctx, wd);
+       SAFE_FREE(wd);
+
+       if (!current_directory) {
+               return -1;
+       }
+       print_directory = talloc_strdup(ctx, pjob->filename);
+       if (!print_directory) {
+               return -1;
+       }
+       p = strrchr_m(print_directory,'/');
+       if (!p) {
+               return -1;
+       }
+       *p++ = 0;
+
+       if (chdir(print_directory) != 0) {
+               return -1;
+       }
+
+       jobname = talloc_strdup(ctx, pjob->jobname);
+       if (!jobname) {
+               ret = -1;
+               goto out;
+       }
+       jobname = talloc_string_sub(ctx, jobname, "'", "_");
+       if (!jobname) {
+               ret = -1;
+               goto out;
+       }
+       slprintf(job_page_count, sizeof(job_page_count)-1, "%d", pjob->page_count);
+       slprintf(job_size, sizeof(job_size)-1, "%lu", (unsigned long)pjob->size);
+
+       /* send it to the system spooler */
+       ret = print_run_command(snum, lp_printername(talloc_tos(), snum), True,
+                       lp_printcommand(talloc_tos(), snum), NULL,
+                       "%s", p,
+                       "%J", jobname,
+                       "%f", p,
+                       "%z", job_size,
+                       "%c", job_page_count,
+                       NULL);
+       if (ret != 0) {
+               ret = -1;
+               goto out;
+       }
+
+       /*
+        * check the queue for the newly submitted job, this allows us to
+        * determine the backend job identifier (sysjob).
+        */
+       pjob->sysjob = -1;
+       ret = generic_queue_get(lp_printername(talloc_tos(), snum),
+                               printing_type, lpq_cmd, &q, &status);
+       if (ret > 0) {
+               int i;
+               for (i = 0; i < ret; i++) {
+                       if (strcmp(q[i].fs_file, p) == 0) {
+                               pjob->sysjob = q[i].sysjob;
+                               DEBUG(5, ("new job %u (%s) matches sysjob %d\n",
+                                         pjob->jobid, jobname, pjob->sysjob));
+                               break;
+                       }
+               }
+               SAFE_FREE(q);
+               ret = 0;
+       }
+       if (pjob->sysjob == -1) {
+               DEBUG(0, ("failed to get sysjob for job %u (%s), tracking as "
+                         "Unix job\n", pjob->jobid, jobname));
+       }
+
+
+ out:
+
+       if (chdir(current_directory) == -1) {
+               smb_panic("chdir failed in generic_job_submit");
+       }
+       TALLOC_FREE(current_directory);
+        return ret;
+}
+
 /****************************************************************************
  pause a queue
 ****************************************************************************/
 static int generic_queue_pause(int snum)
 {
-       return print_run_command(snum, PRINTERNAME(snum), True, lp_queuepausecommand(snum), NULL, NULL);
+       return print_run_command(snum, lp_printername(talloc_tos(), snum), True,
+                                lp_queuepausecommand(talloc_tos(), snum), NULL, NULL);
 }
 
 /****************************************************************************
@@ -234,7 +316,8 @@ static int generic_queue_pause(int snum)
 ****************************************************************************/
 static int generic_queue_resume(int snum)
 {
-       return print_run_command(snum, PRINTERNAME(snum), True, lp_queueresumecommand(snum), NULL, NULL);
+       return print_run_command(snum, lp_printername(talloc_tos(), snum), True,
+                                lp_queueresumecommand(talloc_tos(), snum), NULL, NULL);
 }
 
 /****************************************************************************