diff options
Diffstat (limited to 'src/pwgui')
-rw-r--r-- | src/pwgui/config.h | 5 | ||||
-rw-r--r-- | src/pwgui/main.cpp | 135 | ||||
-rw-r--r-- | src/pwgui/pwgui.cpp | 59 | ||||
-rw-r--r-- | src/pwgui/pwgui.h | 31 | ||||
-rw-r--r-- | src/pwgui/pwgui.ui | 145 |
5 files changed, 375 insertions, 0 deletions
diff --git a/src/pwgui/config.h b/src/pwgui/config.h new file mode 100644 index 0000000..a06d9db --- /dev/null +++ b/src/pwgui/config.h @@ -0,0 +1,5 @@ +// This is where pwgui will look for backends. +// Works exactly like /usr/lib/cups/backend, but don't +// use that as it would cause pwgui invoking itself again... +#define BACKEND_PATH "/opt/openslx/cups/backend" + 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); +} + diff --git a/src/pwgui/pwgui.cpp b/src/pwgui/pwgui.cpp new file mode 100644 index 0000000..31dd822 --- /dev/null +++ b/src/pwgui/pwgui.cpp @@ -0,0 +1,59 @@ +#include "pwgui.h" +#include "ui_pwgui.h" +#include <QMessageBox> +#include <QTimer> +#include <QDesktopWidget> + +// ____________________________________________________________________________ +PwGui::PwGui(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::PwGui) { + // Initialize UI + initializeUI(); +} + +// ____________________________________________________________________________ +PwGui::~PwGui() { + delete ui; +} + +// ____________________________________________________________________________ +void PwGui::initializeUI() { + ui->setupUi(this); + + /* + // Prefill username + if (this->user != NULL) { + ui->lineEditUser->setText(QString::fromUtf8(user)); + } + */ + + // Protect password from being seen + ui->lineEditPass->setEchoMode(QLineEdit::Password); + ui->lineEditPass->setInputMethodHints(ui->lineEditPass->inputMethodHints() | Qt::ImhNoAutoUppercase); + + /* Main Window properties */ + + // Disable close button + this->setWindowFlags((this->windowFlags() & ~Qt::WindowCloseButtonHint) | Qt::WindowStaysOnTopHint); + // center dialog on screen center + QRect desktopRect = QApplication::desktop()->screenGeometry(this); + this->move( desktopRect.width()/2-this->width()/2, + desktopRect.height()/2-this->height()/2); +} + +/* +void PwGui::on_buttonCancel_clicked() { + // Quit with code 1 + QCoreApplication::instance()->exit(1); +} +*/ + +// ____________________________________________________________________________ +void PwGui::on_checkStatusTimer() { + static int retries = 0; + if (++retries > 20) { + QCoreApplication::instance()->quit(); + } +} + diff --git a/src/pwgui/pwgui.h b/src/pwgui/pwgui.h new file mode 100644 index 0000000..3e56ec8 --- /dev/null +++ b/src/pwgui/pwgui.h @@ -0,0 +1,31 @@ +#ifndef AUTHENTICATION_H +#define AUTHENTICATION_H + +#include <QMainWindow> +#include <QDebug> +#include <QTimer> + +namespace Ui { +class PwGui; +} + +class QTimer; + +class PwGui : public QMainWindow +{ + Q_OBJECT + +public: + explicit PwGui(QWidget *parent = 0); + ~PwGui(); + +private slots: + void on_checkStatusTimer(); + +private: + Ui::PwGui *ui; + void initializeUI(); + QTimer* checkStatusTimer; +}; + +#endif // AUTHENTICATION_H diff --git a/src/pwgui/pwgui.ui b/src/pwgui/pwgui.ui new file mode 100644 index 0000000..236df30 --- /dev/null +++ b/src/pwgui/pwgui.ui @@ -0,0 +1,145 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PwGui</class> + <widget class="QMainWindow" name="PwGui"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>310</width> + <height>160</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="windowTitle"> + <string>Drucken - Authentifizierung</string> + </property> + <widget class="QWidget" name="verticalLayoutWidget"> + <property name="geometry"> + <rect> + <x>9</x> + <y>9</y> + <width>291</width> + <height>141</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Benutzername</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLineEdit" name="lineEditUser"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Passwort</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLineEdit" name="lineEditPass"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QLabel" name="labelStatus"> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="frameShape"> + <enum>QFrame::Panel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Sunken</enum> + </property> + <property name="text"> + <string>Bitte Anmelden</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </widget> + <resources/> + <connections/> +</ui> |