Revert "Revert "s3-printing: reload shares after pcap cache fill""
[samba.git] / source3 / printing / print_cups.c
index ecdd0e4f3839d1428d4cacbd010c86de61320b03..a8cc538942ea32d250abfb7a70c1e26c5bf888da 100644 (file)
@@ -428,8 +428,8 @@ static bool cups_pcap_load_async(int *pfd)
 
        close_all_print_db();
 
-       if (!reinit_after_fork(smbd_messaging_context(),
-                              smbd_event_context(), true)) {
+       if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(),
+                                              smbd_event_context(), true))) {
                DEBUG(0,("cups_pcap_load_async: reinit_after_fork() failed\n"));
                smb_panic("cups_pcap_load_async: reinit_after_fork() failed");
        }
@@ -440,13 +440,19 @@ static bool cups_pcap_load_async(int *pfd)
        _exit(0);
 }
 
+struct cups_async_cb_args {
+       int pipe_fd;
+       void (*post_cache_fill_fn)(void);
+};
+
 static void cups_async_callback(struct event_context *event_ctx,
                                struct fd_event *event,
                                uint16 flags,
                                void *p)
 {
        TALLOC_CTX *frame = talloc_stackframe();
-       int fd = *(int *)p;
+       struct cups_async_cb_args *cb_args = (struct cups_async_cb_args *)p;
+       int fd = cb_args->pipe_fd;
        struct pcap_cache *tmp_pcap_cache = NULL;
 
        DEBUG(5,("cups_async_callback: callback received for printer data. "
@@ -540,27 +546,36 @@ static void cups_async_callback(struct event_context *event_ctx,
 
                /* And the systemwide pcap cache. */
                pcap_cache_replace(local_pcap_copy);
+
+               /* Caller may have requested post cache fill callback */
+               if (cb_args->post_cache_fill_fn) {
+                       cb_args->post_cache_fill_fn();
+               }
        } else {
                DEBUG(2,("cups_async_callback: failed to read a new "
                        "printer list\n"));
        }
        close(fd);
-       TALLOC_FREE(p);
+       TALLOC_FREE(cb_args);
        TALLOC_FREE(cache_fd_event);
 }
 
-bool cups_cache_reload(void)
+bool cups_cache_reload(void (*post_cache_fill_fn)(void))
 {
-       int *p_pipe_fd = TALLOC_P(NULL, int);
+       struct cups_async_cb_args *cb_args;
+       int *p_pipe_fd;
 
-       if (!p_pipe_fd) {
+       cb_args = TALLOC_P(NULL, struct cups_async_cb_args);
+       if (!cb_args) {
                return false;
        }
-
+       cb_args->post_cache_fill_fn = post_cache_fill_fn;
+       p_pipe_fd = &cb_args->pipe_fd;
        *p_pipe_fd = -1;
 
        /* Set up an async refresh. */
        if (!cups_pcap_load_async(p_pipe_fd)) {
+               talloc_free(cb_args);
                return false;
        }
        if (!local_pcap_copy) {
@@ -573,7 +588,7 @@ bool cups_cache_reload(void)
                cups_async_callback(smbd_event_context(),
                                        NULL,
                                        EVENT_FD_READ,
-                                       (void *)p_pipe_fd);
+                                       (void *)cb_args);
                if (!local_pcap_copy) {
                        return false;
                }
@@ -590,10 +605,10 @@ bool cups_cache_reload(void)
                                        NULL, *p_pipe_fd,
                                        EVENT_FD_READ,
                                        cups_async_callback,
-                                       (void *)p_pipe_fd);
+                                       (void *)cb_args);
                if (!cache_fd_event) {
                        close(*p_pipe_fd);
-                       TALLOC_FREE(p_pipe_fd);
+                       talloc_free(cb_args);
                        return false;
                }
        }
@@ -900,6 +915,7 @@ static int cups_job_submit(int snum, struct printjob *pjob)
        http_t          *http = NULL;           /* HTTP connection to server */
        ipp_t           *request = NULL,        /* IPP Request */
                        *response = NULL;       /* IPP Response */
+       ipp_attribute_t *attr_job_id = NULL;    /* IPP Attribute "job-id" */
        cups_lang_t     *language = NULL;       /* Default language */
        char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
        const char      *clientname = NULL;     /* hostname of client for job-originating-host attribute */
@@ -912,9 +928,10 @@ static int cups_job_submit(int snum, struct printjob *pjob)
        char *cupsoptions = NULL;
        char *filename = NULL;
        size_t size;
+       uint32_t jobid = (uint32_t)-1;
        char addr[INET6_ADDRSTRLEN];
 
-       DEBUG(5,("cups_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
+       DEBUG(5,("cups_job_submit(%d, %p)\n", snum, pjob));
 
        /*
         * Make sure we don't ask for passwords...
@@ -978,12 +995,20 @@ static int cups_job_submit(int snum, struct printjob *pjob)
                     "job-originating-host-name", NULL,
                      clientname);
 
+       /* Get the jobid from the filename. */
+       jobid = print_parse_jobid(pjob->filename);
+       if (jobid == (uint32_t)-1) {
+               DEBUG(0,("cups_job_submit: failed to parse jobid from name %s\n",
+                               pjob->filename ));
+               jobid = 0;
+       }
+
        if (!push_utf8_talloc(frame, &jobname, pjob->jobname, &size)) {
                goto out;
        }
        new_jobname = talloc_asprintf(frame,
                        "%s%.8u %s", PRINT_SPOOL_PREFIX,
-                       (unsigned int)pjob->smbjob,
+                       (unsigned int)jobid,
                        jobname);
        if (new_jobname == NULL) {
                goto out;
@@ -1021,6 +1046,13 @@ static int cups_job_submit(int snum, struct printjob *pjob)
                                 ippErrorString(cupsLastError())));
                } else {
                        ret = 0;
+                       attr_job_id = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER);
+                       if(attr_job_id) {
+                               pjob->sysjob = attr_job_id->values[0].integer;
+                               DEBUG(5,("cups_job_submit: job-id %d\n", pjob->sysjob));
+                       } else {
+                               DEBUG(0,("Missing job-id attribute in IPP response"));
+                       }
                }
        } else {
                DEBUG(0,("Unable to print file to `%s' - %s\n", PRINTERNAME(snum),
@@ -1365,6 +1397,8 @@ static int cups_queue_get(const char *sharename,
                if (!pull_utf8_talloc(frame, &msg,
                                attr->values[0].string.text,
                                &size)) {
+                       SAFE_FREE(queue);
+                       qcount = 0;
                        goto out;
                }
                fstrcpy(status->message, msg);