/* * This file is part of the KDE libraries * Copyright (c) 2001 Michael Goffioul * * 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 #include #include #include #include #include #include #include #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 tdeprintd 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,"TDE 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