summaryrefslogtreecommitdiffstats
path: root/src/pwgui/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/pwgui/main.cpp')
-rw-r--r--src/pwgui/main.cpp135
1 files changed, 135 insertions, 0 deletions
diff --git a/src/pwgui/main.cpp b/src/pwgui/main.cpp
new file mode 100644
index 0000000..d75f280
--- /dev/null
+++ b/src/pwgui/main.cpp
@@ -0,0 +1,135 @@
+#include "pwgui.h"
+#include "config.h"
+#include <QApplication>
+#include <cups/backend.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#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);
+}
+