summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--CMakeLists.txt138
-rw-r--r--src/maingui/main.cpp (renamed from src/main.cpp)18
-rw-r--r--src/maingui/printergui.cpp (renamed from src/mainwindow.cpp)177
-rw-r--r--src/maingui/printergui.h (renamed from src/mainwindow.h)20
-rw-r--r--src/maingui/printergui.ui (renamed from src/mainwindow.ui)100
-rw-r--r--src/printergui.pro22
-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
12 files changed, 639 insertions, 215 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5f2faeb
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+*.swp
+*~
+build/
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..7530b78
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,138 @@
+################################################################################
+# General
+################################################################################
+
+PROJECT(printergui)
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0)
+
+# set compiler optimizations for debug and release
+IF (CMAKE_BUILD_TYPE STREQUAL "")
+ SET(CMAKE_BUILD_TYPE Debug)
+ENDIF()
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g -Wall -Wunused -Wunreachable-code -pedantic")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -Wall")
+SET(CMAKE_CXX_FLAGS_RELEASE "-O2" )
+
+# local cmake modules
+SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
+
+# this command finds libraries and sets all required variables
+FIND_PACKAGE(Qt4 REQUIRED)
+FIND_PACKAGE(Cups REQUIRED)
+
+# some includes
+INCLUDE_DIRECTORIES(
+ ${CMAKE_SOURCE_DIR}
+ ${CMAKE_BINARY_DIR}
+)
+
+################################################################################
+# Variables
+################################################################################
+
+# printergui (maingui)
+FILE(GLOB MAINGUI_SRCS
+ src/maingui/*.cpp
+)
+
+# password gui (printpwgui
+FILE(GLOB PWGUI_SRCS
+ src/pwgui/*.cpp
+)
+
+################################################################################
+# Qt
+################################################################################
+
+# .ui files
+FILE(GLOB MAINGUI_UIS
+ src/maingui/*.ui
+)
+
+FILE(GLOB PWGUI_UIS
+ src/pwgui/*.ui
+)
+
+# .qrc files
+#SET(MAINGUI_RCS pvsmgr.qrc)
+#SET(PWGUI_RCS pvsclient.qrc)
+
+# includes all header files that should be treated with moc
+SET(MAINGUI_MOC_HDRS
+ src/maingui/printergui.h
+)
+
+SET(PWGUI_MOC_HDRS
+ src/pwgui/pwgui.h
+)
+
+# i18n
+#FILE(GLOB MAINGUI_TSS
+# i18n/server/*.ts
+#)
+
+#FILE(GLOB PWGUI_TSS
+# i18n/client/*.ts
+#)
+
+
+# include Qt modules
+#SET(QT_USE_QTDBUS TRUE)
+#SET(QT_USE_QTNETWORK TRUE)
+#SET(QT_USE_QTWEBKIT TRUE)
+
+# add some useful macros and variables
+# (QT_USE_FILE is a variable defined by FIND_PACKAGE( Qt4 ) that contains
+# a path to CMake script)
+INCLUDE(${QT_USE_FILE})
+
+# this will run rcc on .qrc files
+#QT4_ADD_RESOURCES(MAINGUI_RC_SRCS ${MAINGUI_RCS})
+#QT4_ADD_RESOURCES(PWGUI_RC_SRCS ${PWGUI_RCS})
+
+# this will run uic on .ui files
+QT4_WRAP_UI(MAINGUI_UI_HDRS ${MAINGUI_UIS})
+QT4_WRAP_UI(PWGUI_UI_HDRS ${PWGUI_UIS})
+
+# this will run moc
+QT4_WRAP_CPP(MAINGUI_MOC_SRCS ${MAINGUI_MOC_HDRS})
+QT4_WRAP_CPP(PWGUI_MOC_SRCS ${PWGUI_MOC_HDRS})
+
+# i18n, run lupdate and lrelease)
+#QT4_CREATE_TRANSLATION(MAINGUI_QMS ${MAINGUI_SRCS} ${MAINGUI_UI_HDRS} ${MAINGUI_TSS})
+#QT4_CREATE_TRANSLATION(PWGUI_QMS ${PWGUI_SRCS} ${PWGUI_UI_HDRS} ${PWGUI_TSS})
+
+################################################################################
+# Build
+################################################################################
+
+ADD_EXECUTABLE(printergui
+ ${MAINGUI_SRCS}
+ ${MAINGUI_MOC_SRCS}
+ ${MAINGUI_UI_HDRS}
+ ${MAINGUI_RC_SRCS}
+ ${MAINGUI_QMS}
+)
+
+ADD_EXECUTABLE(printpwgui
+ ${PWGUI_SRCS}
+ ${PWGUI_MOC_SRCS}
+ ${PWGUI_UI_HDRS}
+ ${PWGUI_RC_SRCS}
+ ${PWGUI_QMS}
+)
+
+# link
+TARGET_LINK_LIBRARIES(printergui
+ ${QT_LIBRARIES}
+ ${CUPS_LIBRARIES}
+)
+
+TARGET_LINK_LIBRARIES(printpwgui
+ ${QT_LIBRARIES}
+)
+
+# install
+INSTALL(TARGETS printergui printpwgui RUNTIME DESTINATION bin)
+
diff --git a/src/main.cpp b/src/maingui/main.cpp
index a5582d4..f9b8bb2 100644
--- a/src/main.cpp
+++ b/src/maingui/main.cpp
@@ -1,7 +1,8 @@
#include <QApplication>
#include <fstream>
-#include "mainwindow.h"
-
+#include "printergui.h"
+#include <fcntl.h>
+#include <sys/stat.h>
int main(int argc, char *argv[])
{
@@ -10,16 +11,15 @@ int main(int argc, char *argv[])
return 2;
// Check if file exists
- std::fstream f;
- try {
- f.open(argv[2], std::ios::in);
- } catch (std::fstream::failure e) {
- return 3;
+ int fh = open(argv[2], O_RDONLY);
+ if (fh < 0) {
+ fprintf(stderr, "ERROR: Could not open %s for reading..\n", argv[2]);
+ return 2;
}
- f.close();
+ close(fh);
QApplication a(argc, argv);
- MainWindow w(argv);
+ PrinterGui w(argv);
w.show();
return a.exec();
}
diff --git a/src/mainwindow.cpp b/src/maingui/printergui.cpp
index 4b046d0..3744ffc 100644
--- a/src/mainwindow.cpp
+++ b/src/maingui/printergui.cpp
@@ -1,48 +1,55 @@
-#include "mainwindow.h"
-#include "ui_mainwindow.h"
+#include "printergui.h"
+#include "ui_printergui.h"
#include <QMessageBox>
-#include <time.h>
+#include <unistd.h>
+#include <QTimer>
-#define FIELDLEN 200
-static char _username[FIELDLEN];
-static char _password[FIELDLEN];
-
-static const char * cups_password_cb(const char *prompt)
+// ____________________________________________________________________________
+PrinterGui::PrinterGui(char *argv[], QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::PrinterGui),
+ bgTimeout(-1)
{
- char bla[200];
- snprintf(bla, 200, "/tmp/druckertest-%s-%d", _username, (int)time(NULL));
- FILE *fh = fopen(bla, "a");
- if (fh != NULL) {
- const int passlen = strlen(_password);
- fprintf(fh, "Drucke mit Authentifizierung als '%s', Passwort mit Länge '%d'\n", _username, passlen);
- fclose(fh);
+ // When called it is guaranteed that argv has (at least) 3 elements
+
+ // Set username
+ char buf[200];
+ if (getlogin_r(buf, 200) == 0) {
+ // Detect real name
+ this->user = strdup(buf);
+ } else {
+ // Fallback to what command line says
+ this->user = strdup(argv[1]);
}
- cupsSetUser(_username);
- return _password;
-}
-// ____________________________________________________________________________
-MainWindow::MainWindow(char *argv[], QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow),
- user(argv[1]),
- file(argv[2]),
- authRequired(false) {
+ // Filename
+ this->file = new char[strlen(argv[2]) + 10]; // + 10 in case we rename (ghostscript)
+ strcpy(this->file, argv[2]);
+
// Initialize cups
num_dests = cupsGetDests(&dests);
// Initialize UI
initializeUI();
+
+ // Timer
+ this->bgTimer = new QTimer(this);
+ this->bgTimer->setInterval(1000);
+ connect(bgTimer, SIGNAL(timeout()), this, SLOT(on_bgTimer_timeout()));
}
// ____________________________________________________________________________
-MainWindow::~MainWindow() {
+PrinterGui::~PrinterGui()
+{
cupsFreeDests(num_dests, dests);
- delete ui;
+ free(this->user);
+ delete[] this->file;
+ delete this->ui;
}
// ____________________________________________________________________________
-void MainWindow::initializeUI() {
+void PrinterGui::initializeUI()
+{
ui->setupUi(this);
ui->horizontalLayoutButtons->setAlignment(Qt::AlignRight);
@@ -75,15 +82,6 @@ void MainWindow::initializeUI() {
for (int i = 0; i < 3; ++i)
ui->printerList->resizeColumnToContents(i);
- // 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
@@ -95,7 +93,8 @@ void MainWindow::initializeUI() {
}
// ____________________________________________________________________________
-void MainWindow::on_printerList_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) {
+void PrinterGui::on_printerList_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
+{
ui->printerList->setFocus();
cups_dest_t *dest =cupsGetNamedDest(CUPS_HTTP_DEFAULT, current->text(0).toUtf8().constData(), NULL);
@@ -111,26 +110,6 @@ void MainWindow::on_printerList_currentItemChanged(QTreeWidgetItem *current, QTr
res = ::atoi(type);
}
- const char *auth = cupsGetOption("auth-info-required", dest->num_options, dest->options);
- if (auth != NULL && (strstr(auth, "username") != NULL || strstr(auth, "password") != NULL)) {
- res |= CUPS_PRINTER_AUTHENTICATED;
- }
-
- // Check authentication
- if (res & CUPS_PRINTER_AUTHENTICATED) {
- ui->labelUser->setEnabled(true);
- ui->labelPass->setEnabled(true);
- ui->lineEditUser->setEnabled(true);
- ui->lineEditPass->setEnabled(true);
- this->authRequired = true;
- } else {
- ui->labelUser->setEnabled(false);
- ui->labelPass->setEnabled(false);
- ui->lineEditUser->setEnabled(false);
- ui->lineEditPass->setEnabled(false);
- this->authRequired = false;
- }
-
// Check color capabilities
if (res & CUPS_PRINTER_COLOR) {
ui->comboBoxColor->setEnabled(true);
@@ -167,24 +146,29 @@ void MainWindow::on_printerList_currentItemChanged(QTreeWidgetItem *current, QTr
}
// ____________________________________________________________________________
-void MainWindow::on_buttonCancel_clicked() {
+void PrinterGui::on_buttonCancel_clicked()
+{
// Quit with code 1
QCoreApplication::instance()->exit(1);
}
// ____________________________________________________________________________
-void MainWindow::on_buttonPrint_clicked() {
+void PrinterGui::on_buttonPrint_clicked()
+{
QString cmd;
// Wenn Farbe möglich ist. Aber trotzdem Graustufen gewählt
// Schieb file durch ghostscript
if (ui->comboBoxColor->isEnabled() && ui->comboBoxColor->currentIndex() == 0) {
// Run ghostscript to make file grayscale
- cmd = QString("gs -sDEVICE=psgray -dNOPAUSE -dBATCH -dQUIET -dSAFER -sOutputFile=\"%22\" \"%1\"").arg(
- file,
- file);
- if (system(cmd.toUtf8().constData()))
- return; // TODO WARN ABOUT MISSED GS JOB
+ cmd = QString::fromUtf8("gs -sDEVICE=psgray -dNOPAUSE -dBATCH -dQUIET -dSAFER -sOutputFile=\"%1.conv\" \"%1\"")
+ .arg(QString::fromUtf8(this->file));
+ if (system(cmd.toUtf8().constData())) {
+ QMessageBox::critical(this, "PrinterGUI", "Kann Druckauftrag nicht in Graustufen konvertieren.");
+ return;
+ } else {
+ strcat(this->file, ".conv");
+ }
}
@@ -229,15 +213,7 @@ void MainWindow::on_buttonPrint_clicked() {
&(dest->options));
}
- if (!this->authRequired) {
- // Only Username
- cupsSetUser(this->user);
- } else {
- // Username + Password
- snprintf(_username, FIELDLEN, "%s", ui->lineEditUser->text().toUtf8().constData());
- snprintf(_password, FIELDLEN, "%s", ui->lineEditPass->text().toUtf8().constData());
- cupsSetPasswordCB(&cups_password_cb);
- }
+ cupsSetUser(this->user);
// Drucken
if( 0 == cupsPrintFile(dest->name,
@@ -245,46 +221,23 @@ void MainWindow::on_buttonPrint_clicked() {
NULL,
dest->num_options,
dest->options)) {
- QMessageBox msgBox;
- msgBox.setText(cupsLastErrorString());
- msgBox.exec();
- } else { // Quit with code 0
- QCoreApplication::instance()->quit();
+ QMessageBox::critical(this, "CUPS Fehler", cupsLastErrorString());
+ } else {
+ this->bgTimeout = 0;
+ this->hide();
}
}
+void PrinterGui::on_bgTimer_timeout()
+{
+ if (this->bgTimeout == -1) {
+ // Could do something here every second....
+ return;
+ }
+ if (++this->bgTimeout > 4) {
+ // Job was sent, GUI is invisible, quit after a few seconds
+ QCoreApplication::instance()->quit();
+ }
+}
-/////////////////////////////// CODE PAPIERKORB /////////////////////////////
-
-/* * Print via sysctem command * */
-// // Username, part of whoami source
-// register uid_t uid = geteuid();
-// const char *username = getpwuid(uid)->pw_name;
-// cmd = QString("lp -U %1").arg(username);
-// // Duplex
-// if (ui->comboBoxSides->isEnabled())
-// {
-// switch (ui->comboBoxSides->currentIndex()){
-// case 0:
-// cmd.append(" -o sides=one-sided");
-// break;
-// case 1:
-// cmd.append(" -o sides=two-sided-long-edge");
-// break;
-// case 2:
-// cmd.append(" -o sides=two-sided-long-edge");
-// break;
-// }
-// }
-// // Kopien
-// if (ui->lineEditCopies->isEnabled())
-// cmd.append(QString(" -n %1").arg(ui->lineEditCopies->text()));
-// // Queue
-// cmd.append(QString(" -d %1").arg(ui->printerList->currentItem()->text(0)));
-// // File
-// cmd.append(QString(" -- \"%1\"").arg(file));
-// // Print results to stdout
-// QTextStream (stdout, QIODevice::WriteOnly) << cmd;
-// // Execute the command
-// system(cmd.toUtf8().constData());
diff --git a/src/mainwindow.h b/src/maingui/printergui.h
index ec0e4a8..223d787 100644
--- a/src/mainwindow.h
+++ b/src/maingui/printergui.h
@@ -8,30 +8,34 @@
#include "cups/cups.h"
namespace Ui {
-class MainWindow;
+class PrinterGui;
}
-class MainWindow : public QMainWindow
+class QTimer;
+
+class PrinterGui : public QMainWindow
{
Q_OBJECT
public:
- explicit MainWindow(char *argv[], QWidget *parent = 0);
- ~MainWindow();
+ explicit PrinterGui(char *argv[], QWidget *parent = 0);
+ ~PrinterGui();
private slots:
void on_printerList_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
void on_buttonCancel_clicked();
void on_buttonPrint_clicked();
+ void on_bgTimer_timeout();
private:
- Ui::MainWindow *ui;
+ Ui::PrinterGui *ui;
void initializeUI();
cups_dest_t *dests;
int num_dests;
- const char * const user;
- const char * const file;
- bool authRequired;
+ char * user;
+ char * file;
+ QTimer * bgTimer;
+ int bgTimeout;
};
#endif // MAINWINDOW_H
diff --git a/src/mainwindow.ui b/src/maingui/printergui.ui
index 9533e94..8fafd23 100644
--- a/src/mainwindow.ui
+++ b/src/maingui/printergui.ui
@@ -1,17 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
- <class>MainWindow</class>
- <widget class="QMainWindow" name="MainWindow">
+ <class>PrinterGui</class>
+ <widget class="QMainWindow" name="PrinterGui">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>574</width>
+ <width>590</width>
<height>286</height>
</rect>
</property>
+ <property name="minimumSize">
+ <size>
+ <width>590</width>
+ <height>286</height>
+ </size>
+ </property>
<property name="windowTitle">
- <string>Printjob</string>
+ <string>Druckauftrag</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QGridLayout" name="gridLayout">
@@ -34,36 +40,6 @@
</item>
<item>
<layout class="QGridLayout" name="gridLayout_2">
- <item row="2" column="1">
- <layout class="QHBoxLayout" name="horizontalLayoutUser">
- <item>
- <widget class="QLabel" name="labelUser">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>User:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="lineEditUser">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- </layout>
- </item>
<item row="2" column="0">
<widget class="QComboBox" name="comboBoxColor">
<property name="enabled">
@@ -103,36 +79,6 @@
</item>
</widget>
</item>
- <item row="3" column="1">
- <layout class="QHBoxLayout" name="horizontalLayoutPass">
- <item>
- <widget class="QLabel" name="labelPass">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Password:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="lineEditPass">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- </layout>
- </item>
<item row="3" column="2">
<layout class="QHBoxLayout" name="horizontalLayoutButtons">
<item>
@@ -217,6 +163,32 @@
</item>
</layout>
</item>
+ <item row="2" column="1">
+ <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 row="3" column="1">
+ <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>
</layout>
</item>
</layout>
diff --git a/src/printergui.pro b/src/printergui.pro
deleted file mode 100644
index 5b6da93..0000000
--- a/src/printergui.pro
+++ /dev/null
@@ -1,22 +0,0 @@
-#-------------------------------------------------
-#
-# Project created by QtCreator 2013-09-26T00:51:08
-#
-#-------------------------------------------------
-
-QT += core gui
-
-greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
-
-TARGET = printergui
-TEMPLATE = app
-
-
-SOURCES += main.cpp\
- mainwindow.cpp
-
-HEADERS += mainwindow.h
-
-FORMS += mainwindow.ui
-
-LIBS += -L/usr/lib/x86_64-linux-gnu -lcups
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>