📄 job.c
字号:
case IPP_TAG_RANGE : if (attr->values[i].range.lower == attr->values[i].range.upper) snprintf(optptr, optlength - (optptr - options) - 1, "%d", attr->values[i].range.lower); else snprintf(optptr, optlength - (optptr - options) - 1, "%d-%d", attr->values[i].range.lower, attr->values[i].range.upper); break; case IPP_TAG_RESOLUTION : snprintf(optptr, optlength - (optptr - options) - 1, "%dx%d%s", attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpc"); break; case IPP_TAG_STRING : case IPP_TAG_TEXT : case IPP_TAG_NAME : case IPP_TAG_KEYWORD : case IPP_TAG_CHARSET : case IPP_TAG_LANGUAGE : for (valptr = attr->values[i].string.text; *valptr;) { if (strchr(" \t\n\\\'\"", *valptr)) *optptr++ = '\\'; *optptr++ = *valptr++; } *optptr = '\0'; break; default : break; /* anti-compiler-warning-code */ } } optptr += strlen(optptr); } } /* * Build the command-line arguments for the filters. Each filter * has 6 or 7 arguments: * * argv[0] = printer * argv[1] = job ID * argv[2] = username * argv[3] = title * argv[4] = # copies * argv[5] = options * argv[6] = filename (optional; normally stdin) * * This allows legacy printer drivers that use the old System V * printing interface to be used by CUPS. */ sprintf(jobid, "%d", current->id); snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, current->id, current->current_file + 1); argv[0] = printer->name; argv[1] = jobid; argv[2] = current->username; argv[3] = title; argv[4] = copies; argv[5] = options; argv[6] = filename; argv[7] = NULL; LogMessage(L_DEBUG, "StartJob: argv = \"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]); /* * Create environment variable strings for the filters... */ attr = ippFindAttribute(current->attrs, "attributes-natural-language", IPP_TAG_LANGUAGE); switch (strlen(attr->values[0].string.text)) { default : /* * This is an unknown or badly formatted language code; use * the POSIX locale... */ strcpy(language, "LANG=C"); break; case 2 : /* * Just the language code (ll)... */ snprintf(language, sizeof(language), "LANG=%s", attr->values[0].string.text); break; case 5 : /* * Language and country code (ll-cc)... */ snprintf(language, sizeof(language), "LANG=%c%c_%c%c", attr->values[0].string.text[0], attr->values[0].string.text[1], toupper(attr->values[0].string.text[3] & 255), toupper(attr->values[0].string.text[4] & 255)); break; } attr = ippFindAttribute(current->attrs, "document-format", IPP_TAG_MIMETYPE); if (attr != NULL && (optptr = strstr(attr->values[0].string.text, "charset=")) != NULL) snprintf(charset, sizeof(charset), "CHARSET=%s", optptr + 8); else { attr = ippFindAttribute(current->attrs, "attributes-charset", IPP_TAG_CHARSET); snprintf(charset, sizeof(charset), "CHARSET=%s", attr->values[0].string.text); } snprintf(path, sizeof(path), "PATH=%s/filter:/bin:/usr/bin", ServerBin); snprintf(content_type, sizeof(content_type), "CONTENT_TYPE=%s/%s", current->filetypes[current->current_file]->super, current->filetypes[current->current_file]->type); snprintf(device_uri, sizeof(device_uri), "DEVICE_URI=%s", printer->device_uri); cupsdSanitizeURI(printer->device_uri, sani_uri, sizeof(sani_uri)); snprintf(ppd, sizeof(ppd), "PPD=%s/ppd/%s.ppd", ServerRoot, printer->name); snprintf(printer_name, sizeof(printer_name), "PRINTER=%s", printer->name); snprintf(cache, sizeof(cache), "RIP_MAX_CACHE=%s", RIPCache); snprintf(root, sizeof(root), "CUPS_SERVERROOT=%s", ServerRoot); snprintf(tmpdir, sizeof(tmpdir), "TMPDIR=%s", TempDir); snprintf(datadir, sizeof(datadir), "CUPS_DATADIR=%s", DataDir); snprintf(fontpath, sizeof(fontpath), "CUPS_FONTPATH=%s", FontPath); sprintf(ipp_port, "IPP_PORT=%d", LocalPort); envc = 0; envp[envc ++] = path; envp[envc ++] = "SOFTWARE=CUPS/1.1"; envp[envc ++] = "USER=root"; envp[envc ++] = charset; envp[envc ++] = language; if (TZ && TZ[0]) envp[envc ++] = TZ; envp[envc ++] = ppd; envp[envc ++] = root; envp[envc ++] = cache; envp[envc ++] = tmpdir; envp[envc ++] = content_type; envp[envc ++] = device_uri; envp[envc ++] = printer_name; envp[envc ++] = datadir; envp[envc ++] = fontpath; envp[envc ++] = "CUPS_SERVER=localhost"; envp[envc ++] = ipp_port; if (getenv("VG_ARGS") != NULL) { snprintf(vg_args, sizeof(vg_args), "VG_ARGS=%s", getenv("VG_ARGS")); envp[envc ++] = vg_args; } if (getenv("LD_ASSUME_KERNEL") != NULL) { snprintf(ld_assume_kernel, sizeof(ld_assume_kernel), "LD_ASSUME_KERNEL=%s", getenv("LD_ASSUME_KERNEL")); envp[envc ++] = ld_assume_kernel; } if (getenv("LD_LIBRARY_PATH") != NULL) { snprintf(ld_library_path, sizeof(ld_library_path), "LD_LIBRARY_PATH=%s", getenv("LD_LIBRARY_PATH")); envp[envc ++] = ld_library_path; } if (getenv("LD_PRELOAD") != NULL) { snprintf(ld_preload, sizeof(ld_preload), "LD_PRELOAD=%s", getenv("LD_PRELOAD")); envp[envc ++] = ld_preload; } if (getenv("DYLD_LIBRARY_PATH") != NULL) { snprintf(dyld_library_path, sizeof(dyld_library_path), "DYLD_LIBRARY_PATH=%s", getenv("DYLD_LIBRARY_PATH")); envp[envc ++] = dyld_library_path; } if (getenv("SHLIB_PATH") != NULL) { snprintf(shlib_path, sizeof(shlib_path), "SHLIB_PATH=%s", getenv("SHLIB_PATH")); envp[envc ++] = shlib_path; } if (getenv("NLSPATH") != NULL) { snprintf(nlspath, sizeof(nlspath), "NLSPATH=%s", getenv("NLSPATH")); envp[envc ++] = nlspath; } if (Classification && !banner_page) { if ((attr = ippFindAttribute(current->attrs, "job-sheets", IPP_TAG_NAME)) == NULL) snprintf(classification, sizeof(classification), "CLASSIFICATION=%s", Classification); else if (attr->num_values > 1 && strcmp(attr->values[1].string.text, "none") != 0) snprintf(classification, sizeof(classification), "CLASSIFICATION=%s", attr->values[1].string.text); else snprintf(classification, sizeof(classification), "CLASSIFICATION=%s", attr->values[0].string.text); envp[envc ++] = classification; } if (current->dtype & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)) { snprintf(class_name, sizeof(class_name), "CLASS=%s", current->dest); envp[envc ++] = class_name; }#ifdef __APPLE__ strlcpy(processPath, "<CFProcessPath>", sizeof(processPath)); envp[envc ++] = processPath;#endif /* __APPLE__ */ envp[envc] = NULL; for (i = 0; i < envc; i ++) if (strncmp(envp[i], "DEVICE_URI=", 11)) LogMessage(L_DEBUG, "StartJob: envp[%d]=\"%s\"", i, envp[i]); else LogMessage(L_DEBUG, "StartJob: envp[%d]=\"DEVICE_URI=%s\"", i, sani_uri); current->current_file ++; /* * Make sure we have a buffer to read status info into... */ if (current->buffer == NULL) { LogMessage(L_DEBUG2, "StartJob: Allocating status buffer..."); if ((current->buffer = malloc(JOB_BUFFER_SIZE)) == NULL) { LogMessage(L_EMERG, "Unable to allocate memory for job status buffer - %s", strerror(errno)); snprintf(printer->state_message, sizeof(printer->state_message), "Unable to allocate memory for job status buffer - %s.", strerror(errno)); if (filters != NULL) free(filters); AddPrinterHistory(printer); CancelJob(current->id, 0); return; } current->bufused = 0; } /* * Now create processes for all of the filters... */ if (cupsdOpenPipe(statusfds)) { LogMessage(L_ERROR, "Unable to create job status pipes - %s.", strerror(errno)); snprintf(printer->state_message, sizeof(printer->state_message), "Unable to create status pipes - %s.", strerror(errno)); AddPrinterHistory(printer); if (filters != NULL) free(filters); CancelJob(current->id, 0); return; } LogMessage(L_DEBUG, "StartJob: statusfds = [ %d %d ]", statusfds[0], statusfds[1]); current->pipe = statusfds[0]; current->status = 0; memset(current->procs, 0, sizeof(current->procs)); filterfds[1][0] = open("/dev/null", O_RDONLY); filterfds[1][1] = -1; if (filterfds[1][0] < 0) { LogMessage(L_ERROR, "Unable to open \"/dev/null\" - %s.", strerror(errno)); snprintf(printer->state_message, sizeof(printer->state_message), "Unable to open \"/dev/null\" - %s.", strerror(errno)); AddPrinterHistory(printer); if (filters != NULL) free(filters); cupsdClosePipe(statusfds); CancelJob(current->id, 0); return; } fcntl(filterfds[1][0], F_SETFD, fcntl(filterfds[1][0], F_GETFD) | FD_CLOEXEC); LogMessage(L_DEBUG, "StartJob: filterfds[%d] = [ %d %d ]", 1, filterfds[1][0], filterfds[1][1]); for (i = 0, slot = 0; i < num_filters; i ++) { if (filters[i].filter[0] != '/') snprintf(command, sizeof(command), "%s/filter/%s", ServerBin, filters[i].filter); else strlcpy(command, filters[i].filter, sizeof(command));#ifdef __APPLE__ /* * Setting CFProcessPath lets OS X's Core Foundation code find * the bundle that may be associated with a filter or backend. */ snprintf(processPath, sizeof(processPath), "CFProcessPath=%s", command); LogMessage(L_DEBUG, "StartJob: %s\n", processPath);#endif /* __APPLE__ */ if (i < (num_filters - 1) || strncmp(printer->device_uri, "file:", 5) != 0) { if (cupsdOpenPipe(filterfds[slot])) { LogMessage(L_ERROR, "Unable to create job filter pipes - %s.", strerror(errno)); snprintf(printer->state_message, sizeof(printer->state_message), "Unable to create filter pipes - %s.", strerror(errno)); AddPrinterHistory(printer); if (filters != NULL) free(filters); cupsdClosePipe(statusfds); cupsdClosePipe(filterfds[!slot]); CancelJob(current->id, 0); return; } } else { filterfds[slot][0] = -1; if (strncmp(printer->device_uri, "file:/dev/", 10) == 0) filterfds[slot][1] = open(printer->device_uri + 5, O_WRONLY | O_EXCL); else filterfds[slot][1] = open(printer->device_uri + 5, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (filterfds[slot][1] < 0) { LogMessage(L_ERROR, "Unable to open output file \"%s\" - %s.", printer->device_uri, strerror(errno)); snprintf(printer->state_message, sizeof(printer->state_message), "Unable to open output file \"%s\" - %s.", printer->device_uri, strerror(errno)); AddPrinterHistory(printer); if (filters != NULL) free(filters); cupsdClosePipe(statusfds); CancelJob(current->id, 0); return; } fcntl(filterfds[slot][1], F_SETFD, fcntl(filterfds[slot][1], F_GETFD) | FD_CLOEXEC); } LogMessage(L_DEBUG, "StartJob: filter = \"%s\"", command); LogMessage(L_DEBUG, "StartJob: filterfds[%d] = [ %d %d ]", slot, filterfds[slot][0], filterfds[slot][1]); pid = start_process(command, argv, envp, filterfds[!slot][0], filterfds[slot][1], statusfds[1], 0, current->procs + i); cupsdClosePipe(filterfds[!slot]); if (pid == 0) { LogMessage(L_ERROR, "Unable to start filter \"%s\" - %s.", filters[i].filter, strerror(errno)); snprintf(printer->state_message, sizeof(printer->state_message), "Unable to start filter \"%s\" - %s.", filters[i].filter, strerror(errno)); AddPrinterHistory(printer); if (filters != NULL) free(filters); cupsdClosePipe(statusfds); cupsdClosePipe(filterfds[slot]); CancelJob(current->id, 0); return; } LogMessage(L_INFO, "Started filter %s (PID %d) for job %d.", command, pid, current->id); argv[6] = NULL; slot = !slot; } if (filters != NULL) free(filters); /* * Finally, pipe the final output into a backend process if needed... */ if (strncmp(printer->device_uri, "file:", 5) != 0) { sscanf(printer->device_uri, "%254[^:]", method); snprintf(command, sizeof(command), "%s/backend/%s", ServerBin, method);#ifdef __APPLE__ /* * Setting CFProcessPath lets OS X's Core Foundation code find * the bundle that may be associated with a filter or backend. */ snprintf(processPath, sizeof(processPath), "CFProcessPath=%s", command); LogMessage(L_DEBUG, "StartJob: %s\n", processPath);#endif /* __APPLE__ */ argv[0] = sani_uri; filterfds[slot][0] = -1; filterfds[slot][1] = open("/dev/null", O_WRONLY); if (filterfds[slot][1] < 0) { LogMessage(L_ERROR, "Unable to open \"/dev/null\" - %s.", strerror(errno)); snprintf(printer->state_message, sizeof(printer->state_message), "Unable to open \"/dev/null\" - %s.", strerror(errno)); AddPrinterHistory(printer); if (filters != NULL) free(filters); CancelJob(current->id, 0); return; } fcntl(filterfds[slot][1], F_SETFD, fcntl(filterfds[slot][1], F_GETFD) | FD_CLOEXEC); LogMessage(L_DEBUG, "StartJob: backend = \"%s\"", command); LogMessage(L_DEBUG, "StartJob: filterfds[%d] = [ %d %d ]", slot, filterfds[slot][0], filterfds[slot][1]); pid = start_process(command, argv, envp, filterfds[!slot][0], filterfds[slot][1], statusfds[1], 1, current->procs + i); cupsdClosePipe(filterfds[!slot]); if (pid == 0) { LogMessage(L_ERROR, "Unable to start backend \"%s\" - %s.", method, strerror(errno)); snprintf(printer->state_message, sizeof(printer->state_message), "Unable to start backend \"%s\" - %s.", method, strerror(errno)); AddPrinterHistory(printer); if (filters != NULL) free(filters); cupsdClosePipe(statusfds); cupsdClosePipe(filterfds[slot]); CancelJob(current->id, 0); return; } else { LogMessage(L_INFO, "Started backend %s (PID %d) for job %d.", command, pid, current->id); } } else { filterfds[slot][0] = -1; filterfds[slot][1] = -1; cupsdClosePipe(filterfds[!slot]); } cupsdClosePipe(filterfds[slot]); close(statusfds[1]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -