summaryrefslogtreecommitdiffstats
path: root/kdeprint/cups/cupsdoprint.c
diff options
context:
space:
mode:
Diffstat (limited to 'kdeprint/cups/cupsdoprint.c')
-rw-r--r--kdeprint/cups/cupsdoprint.c257
1 files changed, 257 insertions, 0 deletions
diff --git a/kdeprint/cups/cupsdoprint.c b/kdeprint/cups/cupsdoprint.c
new file mode 100644
index 000000000..743042b2a
--- /dev/null
+++ b/kdeprint/cups/cupsdoprint.c
@@ -0,0 +1,257 @@
+/*
+ * This file is part of the KDE libraries
+ * Copyright (c) 2001 Michael Goffioul <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#include <config.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <cups/cups.h>
+#include <cups/ipp.h>
+
+#define BUFSIZE 1024
+#define BUFSIZE2 32
+
+#define USE_LOG 0
+
+/* global variables */
+char passwd[BUFSIZE2] = {0};
+int pwd_asked = 0;
+#if USE_LOG
+FILE *debugF = NULL;
+#endif
+
+/* utility functions */
+static void error(const char* msg)
+{
+ fprintf(stderr, "%s\n", msg);
+#if USE_LOG
+ if (debugF != NULL) fclose(debugF);
+#endif
+ exit(-1);
+}
+
+static void usage()
+{
+ error("usage: cupsdoprint [-H host[:port]][-P dest][-J name][-o opt=value[,...]][-U login[:password]] files...");
+}
+
+static char * shell_quote(const char *s)
+{
+ char *result;
+ char *p;
+ p = result = malloc(strlen(s)*4+3);
+ *p++ = '\'';
+ while(*s)
+ {
+ if (*s == '\'')
+ {
+ *p++ = '\'';
+ *p++ = '\\';
+ *p++ = '\'';
+ *p++ = '\'';
+ s++;
+ }
+ else
+ {
+ *p++ = *s++;
+ }
+ }
+ *p++ = '\'';
+ *p = '\0';
+ return result;
+}
+
+static const char* getPasswordCB(const char* prompt)
+{
+ char buf[ 256 ] = {0}, *c;
+ char *_user = shell_quote( cupsUser() ), *_passwd = NULL;
+ FILE *output;
+
+ snprintf( buf, sizeof( buf )-1, "dcop kded kdeprintd requestPassword %s %s %d %d",
+ _user,
+ cupsServer(),
+ ippPort(),
+ pwd_asked );
+ free( _user );
+ _user = NULL;
+ output = popen( buf, "r" );
+ if ( output != NULL )
+ {
+ while ( fgets( buf, sizeof( buf )-1, output ) )
+ {
+ _user = _passwd = NULL;
+ if ( strcmp( buf, "::" ) != 0 )
+ {
+ c = strchr( buf, ':' );
+ if ( c != NULL )
+ {
+ *c = '\0';
+ _user = buf;
+ _passwd = ++c;
+ c = strchr( c, ':' );
+ if ( c != NULL )
+ {
+ *c = '\0';
+ /* retrieve password sequence number */
+ pwd_asked = atoi( ++c );
+ /* update CUPS with current username */
+ cupsSetUser( _user );
+ /* copy password to a non temporary location */
+ strlcpy( passwd, _passwd, BUFSIZE2 );
+ _passwd = passwd;
+ }
+ else
+ _passwd = NULL;
+ }
+ }
+ }
+ pclose( output );
+ }
+ else
+ return NULL;
+
+ /* erase buffer containing unencrypted password, for security */
+ memset( buf, 0, 256 );
+
+ /* if OK, _passwd should point to global passwd variable, otherwise it should be NULL */
+ return _passwd;
+}
+
+/* main function */
+int main(int argc, char* argv[])
+{
+ int c, port = -1;
+ char printer[BUFSIZE] = {0}, jobname[BUFSIZE] = {0}, host[BUFSIZE] = {0};
+ char login[BUFSIZE2] = {0};
+ char *a;
+ cups_option_t *options = NULL;
+ int num_options = 0;
+ char* files[100] = {0};
+ int num_files = 0;
+ int jobID = 0;
+
+#if USE_LOG
+ debugF = fopen("/tmp/cupsdoprint.debug","w");
+ if (debugF == NULL)
+ error("unable to open log file");
+#endif
+
+ while ((c=getopt(argc, argv, "P:J:H:o:U:?")) != -1)
+ {
+#if USE_LOG
+ fprintf(debugF,"%c: %s\n",c,optarg);
+#endif
+ switch (c)
+ {
+ case 'P':
+ strlcpy(printer, optarg, BUFSIZE);
+ if ((a=strchr(printer, '/')) != NULL)
+ error("This utility doesn't support printer instances");
+ break;
+ case 'J':
+ strlcpy(jobname, optarg, BUFSIZE);
+ break;
+ case 'H':
+ strlcpy(host, optarg, BUFSIZE);
+ if ((a=strchr(host, ':')) != NULL)
+ {
+ *a = 0;
+ port = atoi(++a);
+ if (port == 0)
+ error("Wrong port value");
+ }
+ break;
+ case 'U':
+ strlcpy(login, optarg, BUFSIZE2);
+ if ((a=strchr(login, ':')) != NULL)
+ {
+ *a = 0;
+ strlcpy(passwd, ++a, BUFSIZE2);
+ }
+ break;
+ case 'o':
+#if USE_LOG
+ fprintf(debugF,"Parsing options (n=%d)\n",num_options);
+#endif
+ num_options = cupsParseOptions(optarg, num_options, &options);
+#if USE_LOG
+ fprintf(debugF,"Options parsed (n=%d)\n",num_options);
+#endif
+ break;
+ case '?':
+ default:
+ usage();
+ break;
+ }
+ }
+
+ /* check the printer */
+ if (!*printer)
+ {
+ printer[BUFSIZE-1] = '\0';
+ if (getenv("PRINTER") != NULL)
+ strlcpy(printer, getenv("PRINTER"), BUFSIZE-1);
+ else
+ error("No printer specified (and PRINTER variable is empty)");
+ }
+
+ /* CUPS settings */
+ if (host[0] != 0) cupsSetServer(host);
+ if (port > 0) ippSetPort(port);
+ if (login[0] != 0) cupsSetUser(login);
+ if (jobname[0] == 0) strcpy(jobname,"KDE Print System");
+ cupsSetPasswordCB(getPasswordCB);
+
+ /* check for files */
+ if (optind < 1 || optind >= argc)
+ error("This utility doesn't support printing from STDIN");
+ else
+ for (c=optind; c<argc; c++)
+ {
+ if (access(argv[c], R_OK) != 0)
+ {
+ fprintf(stderr, "%s: ", argv[c]);
+ error("file not found or not readable");
+ }
+ else
+ files[num_files++] = strdup(argv[c]);
+ }
+
+#if USE_LOG
+ fprintf(debugF,"Processed options:\n");
+ for (c=0; c<num_options; c++)
+ fprintf(debugF,"%s = %s\n",options[c].name,options[c].value);
+#endif
+ /* print files */
+ jobID = cupsPrintFiles(printer, num_files, files, jobname, num_options, options);
+ /* erase unemcrypted password for security */
+ memset( passwd, 0, BUFSIZE2 );
+ /* check job creation status */
+ if (jobID <= 0)
+ error(ippErrorString(cupsLastError()));
+
+#if USE_LOG
+ fclose(debugF);
+#endif
+ return 0;
+}