void reload_printers(void) { int snum; int n_services = lp_numservices(); int pnum = lp_servicenumber(PRINTERS_NAME); const char *pname; pcap_cache_reload(); /* remove stale printers */ for (snum = 0; snum < n_services; snum++) { /* avoid removing PRINTERS_NAME or non-autoloaded printers */ if (snum == pnum || !(lp_snum_ok(snum) && lp_print_ok(snum) && lp_autoloaded(snum))) continue; pname = lp_printername(snum); if (!pcap_printername_ok(pname)) { DEBUG(3, ("removing stale printer %s\n", pname)); if (is_printer_published(NULL, snum, NULL)) nt_printer_publish(NULL, snum, SPOOL_DS_UNPUBLISH); del_a_printer(pname); lp_killservice(snum); } } load_printers(); }
/**************************************************************************** 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, lp_printername(talloc_tos(), snum), True, lp_lpresume_command(talloc_tos(), snum), NULL, "%j", jobstr, NULL); }
/**************************************************************************** purge stale printers and reload from pre-populated pcap cache **************************************************************************/ void reload_printers(struct tevent_context *ev, struct messaging_context *msg_ctx) { int n_services; int pnum; int snum; const char *pname; n_services = lp_numservices(); pnum = lp_servicenumber(PRINTERS_NAME); DEBUG(10, ("reloading printer services from pcap cache\n")); /* * Add default config for printers added to smb.conf file and remove * stale printers */ for (snum = 0; snum < n_services; snum++) { /* avoid removing PRINTERS_NAME */ if (snum == pnum) { continue; } /* skip no-printer services */ if (!(lp_snum_ok(snum) && lp_print_ok(snum))) { continue; } pname = lp_printername(snum); /* check printer, but avoid removing non-autoloaded printers */ if (lp_autoloaded(snum) && !pcap_printername_ok(pname)) { DEBUG(3, ("removing stale printer %s\n", pname)); lp_killservice(snum); } } /* Make sure deleted printers are gone */ load_printers(ev, msg_ctx); }
/**************************************************************************** resume a queue ****************************************************************************/ static int generic_queue_resume(int snum) { return print_run_command(snum, lp_printername(talloc_tos(), snum), True, lp_queueresume_command(talloc_tos(), snum), NULL, NULL); }
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_print_command(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(2, ("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, lp_printername(snum), True, lp_queuepausecommand(snum), NULL, NULL); }
static int generic_job_submit(int snum, struct printjob *pjob) { 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; /* 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(snum), True, lp_printcommand(snum), NULL, "%s", p, "%J", jobname, "%f", p, "%z", job_size, "%c", job_page_count, NULL); out: if (chdir(current_directory) == -1) { smb_panic("chdir failed in generic_job_submit"); } TALLOC_FREE(current_directory); return ret; }
/** * @brief Purge stale printer shares and reload from pre-populated pcap cache. * * This function should normally only be called as a callback on a successful * pcap_cache_reload(), or on client enumeration. * * @param[in] ev The event context. * * @param[in] msg_ctx The messaging context. */ void delete_and_reload_printers(struct tevent_context *ev, struct messaging_context *msg_ctx) { int n_services; int pnum; int snum; const char *pname; bool ok; time_t pcap_last_update; TALLOC_CTX *frame = talloc_stackframe(); ok = pcap_cache_loaded(&pcap_last_update); if (!ok) { DEBUG(1, ("pcap cache not loaded\n")); talloc_free(frame); return; } if (reload_last_pcap_time == pcap_last_update) { DEBUG(5, ("skipping printer reload, already up to date.\n")); talloc_free(frame); return; } reload_last_pcap_time = pcap_last_update; /* Get pcap printers updated */ load_printers(ev, msg_ctx); n_services = lp_numservices(); pnum = lp_servicenumber(PRINTERS_NAME); DEBUG(10, ("reloading printer services from pcap cache\n")); /* * Add default config for printers added to smb.conf file and remove * stale printers */ for (snum = 0; snum < n_services; snum++) { /* avoid removing PRINTERS_NAME */ if (snum == pnum) { continue; } /* skip no-printer services */ if (!snum_is_shared_printer(snum)) { continue; } pname = lp_printername(frame, snum); /* check printer, but avoid removing non-autoloaded printers */ if (lp_autoloaded(snum) && !pcap_printername_ok(pname)) { lp_killservice(snum); } } /* Make sure deleted printers are gone */ load_printers(ev, msg_ctx); talloc_free(frame); }
static int iprint_job_submit(int snum, struct printjob *pjob, enum printing_types printing_type, char *lpq_cmd) { int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ char uri[HTTP_MAX_URI]; /* printer-uri attribute */ DEBUG(5,("iprint_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob)); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(iprint_passwd_cb); /* * Try to connect to the server... */ if ((http = httpConnect(iprint_server(), ippPort())) == NULL) { DEBUG(0,("Unable to connect to iPrint server %s - %s\n", iprint_server(), strerror(errno))); goto out; } /* * Build an IPP_PRINT_JOB request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name * [document-data] */ request = ippNew(); ippSetOperation(request, IPP_PRINT_JOB); ippSetRequestId(request, 1); language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), lp_printername(snum)); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, pjob->user); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-originating-host-name", NULL, pjob->clientmachine); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, pjob->jobname); /* * Do the request and get back a response... */ slprintf(uri, sizeof(uri) - 1, "/ipp/%s", lp_printername(snum)); if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) { if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to print file to %s - %s\n", lp_printername(snum), ippErrorString(cupsLastError()))); } else { ret = 0; } } else { DEBUG(0,("Unable to print file to `%s' - %s\n", lp_printername(snum), ippErrorString(cupsLastError()))); } if ( ret == 0 ) unlink(pjob->filename); /* else print_job_end will do it for us */ if ( ret == 0 ) { attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER); if (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_JOB) { pjob->sysjob = ippGetInteger(attr, 0); } } out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); return ret; }
static int iprint_job_resume(int snum, struct printjob *pjob) { int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ cups_lang_t *language = NULL; /* Default language */ char uri[HTTP_MAX_URI]; /* printer-uri attribute */ char httpPath[HTTP_MAX_URI]; /* path portion of the printer-uri */ DEBUG(5,("iprint_job_resume(%d, %p (%d))\n", snum, pjob, pjob->sysjob)); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(iprint_passwd_cb); /* * Try to connect to the server... */ if ((http = httpConnect(iprint_server(), ippPort())) == NULL) { DEBUG(0,("Unable to connect to iPrint server %s - %s\n", iprint_server(), strerror(errno))); goto out; } /* * Build an IPP_RELEASE_JOB request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * job-id * requesting-user-name */ request = ippNew(); ippSetOperation(request, IPP_RELEASE_JOB); ippSetRequestId(request, 1); language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), lp_printername(snum)); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", pjob->sysjob); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, pjob->user); /* * Do the request and get back a response... */ slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", lp_printername(snum)); if ((response = cupsDoRequest(http, request, httpPath)) != NULL) { if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob, ippErrorString(cupsLastError()))); } else { ret = 0; } } else { DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob, ippErrorString(cupsLastError()))); } out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); return ret; }
/** * @brief Purge stale printers and reload from pre-populated pcap cache. * * This function should normally only be called as a callback on a successful * pcap_cache_reload(). * * This function can cause DELETION of printers and drivers from our registry, * so calling it on a failed pcap reload may REMOVE permanently all printers * and drivers. * * @param[in] ev The event context. * * @param[in] msg_ctx The messaging context. */ static void delete_and_reload_printers_full(struct tevent_context *ev, struct messaging_context *msg_ctx) { struct auth_session_info *session_info = NULL; struct spoolss_PrinterInfo2 *pinfo2 = NULL; int n_services; int pnum; int snum; const char *pname; const char *sname; NTSTATUS status; n_services = lp_numservices(); pnum = lp_servicenumber(PRINTERS_NAME); status = make_session_info_system(talloc_tos(), &session_info); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("reload_printers: " "Could not create system session_info\n")); /* can't remove stale printers before we * are fully initilized */ return; } /* * Add default config for printers added to smb.conf file and remove * stale printers */ for (snum = 0; snum < n_services; snum++) { /* avoid removing PRINTERS_NAME */ if (snum == pnum) { continue; } /* skip no-printer services */ if (!snum_is_shared_printer(snum)) { continue; } sname = lp_const_servicename(snum); pname = lp_printername(session_info, snum); /* check printer, but avoid removing non-autoloaded printers */ if (lp_autoloaded(snum) && !pcap_printername_ok(pname)) { DEBUG(3, ("removing stale printer %s\n", pname)); if (is_printer_published(session_info, session_info, msg_ctx, NULL, lp_servicename(session_info, snum), &pinfo2)) { nt_printer_publish(session_info, session_info, msg_ctx, pinfo2, DSPRINT_UNPUBLISH); TALLOC_FREE(pinfo2); } nt_printer_remove(session_info, session_info, msg_ctx, pname); } else { DEBUG(8, ("Adding default registry entry for printer " "[%s], if it doesn't exist.\n", sname)); nt_printer_add(session_info, session_info, msg_ctx, sname); } } /* finally, purge old snums */ delete_and_reload_printers(); TALLOC_FREE(session_info); }