From 66971c5a9f12719f8193ceac19614d9c0e98fe69 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 18 Sep 2014 16:08:50 +0200 Subject: Fixed stupid bugs --- src/pwgui/main.cpp | 73 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/src/pwgui/main.cpp b/src/pwgui/main.cpp index 3d6059c..319cd40 100644 --- a/src/pwgui/main.cpp +++ b/src/pwgui/main.cpp @@ -19,7 +19,11 @@ #define NAMELEN 400 #define BUFLEN 1000 -#define ENVLEN 10000 +#define ENVLEN 20000 + +#define DEBUG(...) fprintf(stderr, "DEBUG: [pwgui] " __VA_ARGS__) +#define WARNING(...) fprintf(stderr, "WARNING: [pwgui] " __VA_ARGS__) +#define ERROR(...) fprintf(stderr, "ERROR: [pwgui] " __VA_ARGS__) #define CUSTOM_CUPS_NO_SUCH_PRINTER 50 @@ -56,7 +60,7 @@ int main(int argc, char *argv[]) // First check parameter count if (argc != 6 && argc != 7) { - fputs("ERROR: Invalid number of arguments passed.\n", stderr); + ERROR("Invalid number of arguments passed.\n"); return CUPS_BACKEND_FAILED; } @@ -67,7 +71,7 @@ int main(int argc, char *argv[]) } else if (strstr(argv[0], ":/") != NULL) { snprintf(device, NAMELEN, "%s", argv[0]); } else { - fputs("ERROR: No device URI given.\n", stderr); + ERROR("No device URI given.\n"); return CUPS_BACKEND_FAILED; } @@ -80,19 +84,20 @@ int main(int argc, char *argv[]) if (access(backend, X_OK | R_OK) != 0) { helper_getpiduid(argv[2], argv[3]); helper_messageBox("PrinterGUI", "Kein Backend für den gewählten Drucker vorhanden."); - fprintf(stderr, "ERROR: Backend %s is not executable.\n", backend); + ERROR("Backend %s is not executable. Over and out.\n", backend); return CUPS_BACKEND_FAILED; } // argv[3] is title, get printergui pid from it if (!helper_getpiduid(argv[2], argv[3])) { // El cheapo validation failed. Don't enable "smart mode" (GUI etc), just exec real backend - fputs("ERROR: Dumb mode - will exec actual backend.\n", stderr); + ERROR("Dumb mode - will exec actual backend.\n"); // Mimic cups behaviour wrt dropping privs (Only 0700 or 0500 == root) helper_loadlpuser(); struct stat st; if (stat(backend, &st) != 0 || (st.st_mode & 0011) != 0) helper_dropprivs(); kill(pid, SIGTERM); + WARNING("Over and out.\n"); execv(backend, argv); exit(127); } @@ -105,7 +110,7 @@ int main(int argc, char *argv[]) int fh = open(tmpfile, O_CREAT | O_WRONLY | O_TRUNC, 0600); if (fh < 0) { helper_messageBox("PrinterGUI", "Konnte temporäre Datei für den Druckjob nicht anlegen."); - fprintf(stderr, "ERROR: Could not open %s for writing..\n", tmpfile); + ERROR("Could not open %s for writing. Over and out.\n", tmpfile); return CUPS_BACKEND_FAILED; } char buffer[BUFLEN]; @@ -116,20 +121,20 @@ int main(int argc, char *argv[]) if (bytes == 0) break; if (bytes < 0) { helper_messageBox("PrinterGUI", "Konnte den Druckjob nicht auf STDIN empfangen."); - fprintf(stderr, "ERROR: Could not read print job from STDIN.\n"); + ERROR("Could not read print job from STDIN. Over and out.\n"); remove(tmpfile); return CUPS_BACKEND_FAILED; } if ((ret = write(fh, buffer, bytes)) != bytes) { helper_messageBox("PrinterGUI", "Konnte Druckjob nicht in temporäre Datei schreiben."); - fprintf(stderr, "ERROR: Could not write %d bytes to %s (wrote %d)\n", (int)bytes, tmpfile, (int)ret); + ERROR("Could not write %d bytes to %s (wrote %d). Over and out.\n", (int)bytes, tmpfile, (int)ret); remove(tmpfile); return CUPS_BACKEND_FAILED; } total += bytes; } close(fh); - fprintf(stderr, "ERROR: Read %d bytes from stdin.\n", total); + DEBUG("Read %d bytes from stdin.\n", total); // } else { // File given, check if file exists @@ -137,7 +142,7 @@ int main(int argc, char *argv[]) int fh = open(tmpfile, O_RDONLY); if (fh < 0) { helper_messageBox("PrinterGUI", "Konnte den Druckjob nicht vom Dateisystem lesen."); - fprintf(stderr, "ERROR: Could not open %s for reading..\n", tmpfile); + ERROR("Could not open %s for reading. Over and out.\n", tmpfile); return CUPS_BACKEND_FAILED; } close(fh); @@ -154,11 +159,11 @@ int main(int argc, char *argv[]) char creds[NAMELEN], *pass = NULL; snprintf(creds, NAMELEN, "%s", argv[2]); do { - fputs("ERROR: Opening PW dialog....\n", stderr); + WARNING("Direct printing failed. Opening PW dialog....\n"); int pfd[2]; if (pipe(pfd) != 0) { helper_messageBox("PrinterGUI", "Konnte pipe für die GUI nicht anlegen."); - fputs("ERROR: Could not create pipe for GUI.\n", stderr); + ERROR("Could not create pipe for GUI. Over and out.\n"); return CUPS_BACKEND_FAILED; } const pid_t pid = fork(); @@ -182,7 +187,7 @@ int main(int argc, char *argv[]) waitpid(pid, NULL, 0); // Don't check status, just look at pipe data if (bytes <= 0) { // Probably means user pressed cancel helper_messageBox("PrinterGUI", "Druckauftrag abgebrochen."); - fputs("ERROR: Could not read anything from pipe after showing GUI.\n", stderr); + ERROR("Could not read anything from pipe after showing GUI. Over and out.\n"); remove(tmpfile); return CUPS_BACKEND_CANCEL; } @@ -194,7 +199,7 @@ int main(int argc, char *argv[]) helper_cupsError(status); } while (status != CUPS_BACKEND_OK); remove(tmpfile); - fprintf(stderr, "ERROR: Job submitted.\n"); + ERROR("Job submitted. Over and out.\n"); return CUPS_BACKEND_OK; } @@ -251,11 +256,11 @@ static int run_backend(char *backend, char *uri, char *jobid, char *user, char * int readlen = 0; while ((readlen = read(pipefd[0], buffer, BUFLEN-1)) > 0) { buffer[readlen] = '\0'; - fprintf(stderr, "ERROR: BACKEND: %s\n", buffer); + ERROR("BACKEND: %s\n", buffer); if (strstr(buffer, "Unable to get printer status (Unauthorized)") != NULL) { needAuth = true; if (kill(pid, SIGTERM) < 0) { - fprintf(stderr, "ERROR: Sending kill1 to backend %d failed: %d\n", (int)pid, errno); + ERROR("Sending SIGTERM to backend %d failed: %d\n", (int)pid, errno); } break; } else if (strstr(buffer, "Destination printer does not exist") != NULL) { @@ -274,19 +279,19 @@ static int run_backend(char *backend, char *uri, char *jobid, char *user, char * } } if (needAuth) { - fprintf(stderr, "ERROR: Killed backend because of 'unauthorized' message (iprint crap?), trying with auth\n"); + ERROR("Killed backend because of 'unauthorized' message (iprint crap?), trying with auth\n"); return CUPS_BACKEND_AUTH_REQUIRED; } if (nonexistent) { - fprintf(stderr, "ERROR: Destination printer does not exist!\n"); + ERROR("Destination printer does not exist!\n"); return CUSTOM_CUPS_NO_SUCH_PRINTER; } if (!WIFEXITED(status)) { - fprintf(stderr, "ERROR: Running backend %s failed!\n", backend); + ERROR("Running backend %s failed!\n", backend); return CUPS_BACKEND_FAILED; } status = WEXITSTATUS(status); - if (status != CUPS_BACKEND_OK) fprintf(stderr, "ERROR: Backend returned %d\n", status); + if (status != CUPS_BACKEND_OK) ERROR("Backend returned %d\n", status); return status; } @@ -296,34 +301,34 @@ static bool helper_getpiduid(char *user, char *title) // and we have to be able to kill it, only then we assume we should bother the user // with an authentication dialog if (strncmp(title, "gui-", 4) != 0) { - fprintf(stderr, "WARNING: Job Title doesnt start with 'gui-' (Is: %s)\n", title); + WARNING("Job Title doesnt start with 'gui-' (Is: %s)\n", title); return false; // Wrong job title } int p = atoi(title + 4); struct stat st; struct passwd *pw = getpwnam(user); if (pw == NULL) { - fprintf(stderr, "WARNING: Cannot getpwnam %s\n", user); + WARNING("Cannot getpwnam %s\n", user); return false; } char bin[PATH_MAX+1], tmp[100]; snprintf(tmp, 100, "/proc/%d/exe", p); if (realpath(tmp, bin) == NULL) { - fprintf(stderr, "WARNING: Cannot get realpath of %s\n", tmp); + WARNING("Cannot get realpath of %s\n", tmp); return false; } char *last = strrchr(bin, '/'); if (last == NULL || strcmp(last, "/printergui") != 0) { - fprintf(stderr, "WARNING: %s does not end in /printergui\n", bin); + WARNING("%s does not end in /printergui\n", bin); return false; // Wrong process } // PID passed via job title seems to be the printergui if (lstat(tmp, &st) < 0) { - fprintf(stderr, "WARNING: Could not lstat() %s\n", tmp); + WARNING("Could not lstat() %s\n", tmp); return false; } if (st.st_uid != pw->pw_uid) { - fprintf(stderr, "WARNING: Owner of %s: %d, owner of job: %d (%s)\n", tmp, (int)st.st_uid, (int)pw->pw_uid, user); + WARNING("Owner of %s: %d, owner of job: %d (%s)\n", tmp, (int)st.st_uid, (int)pw->pw_uid, user); return false; // Print job user doesn't match printergui process owner } // All checks passed, make stuff global @@ -348,7 +353,7 @@ static bool helper_getpiduid(char *user, char *title) gui_env[bytes+1] = '\0'; } } - fprintf(stderr, "DEBUG: getpiduid successful!\n"); + DEBUG("getpiduid successful!\n"); return true; } @@ -369,7 +374,7 @@ static void helper_dropprivs() setuid(ruid); chdir("/"); if (setuid(0) != -1) { - fputs("ERROR: setuid-fu!?\n", stderr); + ERROR("setuid-fu!?\n"); exit(CUPS_BACKEND_FAILED); } } @@ -383,6 +388,7 @@ static void helper_copyenv() char *value = equal + 1; *equal = '\0'; setenv(ptr, value, 1); + DEBUG("Setting Env: '%s' = '%s'\n", ptr, value); *equal = '='; } ptr += strlen(ptr) + 1; @@ -465,18 +471,23 @@ static int helper_cupsError(const int code) case CUSTOM_CUPS_NO_SUCH_PRINTER: helper_messageBox("CUPS Fehler", "Die Druckerwarteschlange existiert nicht auf dem print server. Fehlerhafte lokale printers.conf?"); return CUPS_BACKEND_CANCEL; + default: + ERROR("Unknown cupsError code %d\n", code); + helper_messageBox("CUPS Fehler", "Unbekannter Fehler beim Drucken", true); + break; } return code; } static void helper_messageBox(const char *caption, const char *text, const bool error) { + WARNING("Trying to MsgBox: %s\n", text); const pid_t pid = fork(); if (pid == 0) { // Child - Qt char *argv[1]; - argv[1] = (char*)"bla"; - int argc; + argv[0] = (char*)"bla"; + int argc = 1; helper_dropprivs(); helper_copyenv(); QApplication a(argc, argv); @@ -485,7 +496,7 @@ static void helper_messageBox(const char *caption, const char *text, const bool } else { QMessageBox::information(NULL, QString::fromUtf8(caption), QString::fromUtf8(text)); } - exit(a.exec()); + exit(0); return; } // Main (Parent) -- cgit v1.2.3-55-g7522