summaryrefslogtreecommitdiffstats
path: root/src/pwgui
diff options
context:
space:
mode:
Diffstat (limited to 'src/pwgui')
-rw-r--r--src/pwgui/config.h5
-rw-r--r--src/pwgui/main.cpp135
-rw-r--r--src/pwgui/pwgui.cpp59
-rw-r--r--src/pwgui/pwgui.h31
-rw-r--r--src/pwgui/pwgui.ui145
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>