#include "pwgui.h" #include "config.h" #include #include #include #include #include #include #include #include #include #include #define NAMELEN 400 #define BUFLEN 1000 static int run_backend(char *backend, char *uri, char *jobid, char *user, char *title, char *copies, char *options, char *file, char *password); int main(int argc, char *argv[]) { char tmpfile[NAMELEN]; char device[NAMELEN]; char backend[NAMELEN]; int spoolres; // Pretty much what smbspool does, but in a generalized way if (argc > 2 && strstr(argv[0], ":/") == NULL && strstr(argv[1], ":/") != NULL) { argv++; argc--; } // First check parameter count if (argc != 6 && argc != 7) { fputs("ERROR: Invalid number of arguments passed.\n", stderr); return CUPS_BACKEND_FAILED; } if (argc == 6) { // Data comes from stdin, save... snprintf(tmpfile, NAMELEN, "/tmp/print-%s-%d-%s-%d", argv[1], (int)time(NULL), argv[2], (int)getpid()); int fh = open(tmpfile, O_CREAT | O_WRONLY | O_TRUNC, 0600); if (fh < 0) { fprintf(stderr, "ERROR: Could not open %s for writing..\n", tmpfile); return CUPS_BACKEND_FAILED; } char buffer[BUFLEN]; size_t bytes, ret; while (!feof(stdin)) { bytes = fread(buffer, BUFLEN, 1, stdin); if (bytes == 0) break; if ((ret = write(fh, buffer, bytes)) != bytes) { fprintf(stderr, "ERROR: Could not write %d bytes to %s (wrote %d)\n", (int)bytes, tmpfile, (int)ret); remove(tmpfile); return CUPS_BACKEND_FAILED; } } close(fh); // } else { // File given, check if file exists snprintf(tmpfile, NAMELEN, "%s", argv[6]); int fh = open(tmpfile, O_RDONLY); if (fh < 0) { fprintf(stderr, "ERROR: Could not open %s for reading..\n", tmpfile); return CUPS_BACKEND_FAILED; } close(fh); // } // Determine device uri char *env = getenv("DEVICE_URI"); if (env != NULL && strchr(env, ':') != NULL) { snprintf(device, NAMELEN, "%s", env); } else if (strstr(argv[0], ":/") != NULL) { snprintf(device, NAMELEN, "%s", argv[0]); } else { fputs("ERROR: No device URI given.\n", stderr); return CUPS_BACKEND_FAILED; } // Get backend from uri char *colon = strchr(device, ':'); *colon = '\0'; snprintf(backend, NAMELEN, "%s/%s", BACKEND_PATH, device); *colon = ':'; // Is valid? if (access(backend, X_OK | R_OK) != 0) { fprintf(stderr, "ERROR: Backend %s is not executable.\n", backend); return CUPS_BACKEND_FAILED; } // Try right away with what we got spoolres = run_backend(backend, device, argv[1], argv[2], argv[3], argv[4], argv[5], tmpfile, NULL); if (spoolres == CUPS_BACKEND_OK) return spoolres; // Yay // Dialog - TODO: Drop privileges here! QApplication a(argc, argv); PwGui w(NULL); w.show(); return a.exec(); // TODO ..... } static int run_backend(char *backend, char *uri, char *jobid, char *user, char *title, char *copies, char *options, char *file, char *password) { pid_t pid = fork(); if (pid == 0) { // Child if (user != NULL) setenv("AUTH_USERNAME", user, 1); if (password != NULL) setenv("AUTH_PASSWORD", password, 1); char *args[8]; args[0] = uri; args[1] = jobid; args[2] = user; args[3] = title; args[4] = copies; args[5] = options; args[6] = file; args[7] = NULL; execv(backend, args); exit(127); return 127; } // Main - wait for it... int status; waitpid(pid, &status, 0); if (!WIFEXITED(status)) { fprintf(stderr, "ERROR: Running backend %s failed!\n", backend); return CUPS_BACKEND_FAILED; } return WEXITSTATUS(status); }