LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File poll_ppd_base.c of Package cups (Project DISCONTINUED:openSUSE:11.1)

/*
 *
 *   poll_ppd_base
 *   -------------
 #
 #   A simple tool for getting a list of all installed PPD files
 #   with printer manufacturer and printer model, polling the database
 #   of the CUPS daemon. This program is mainly intended to be called
 #   from installation/configuration scripts for CUPS.
 #
 #   ONLY WORKS WITH CUPS DAEMON RUNNING!
 #   The CUPS library (libcups.so.*) must be installed!
 #
 #   Compile with: gcc -opoll_ppd_base -lcups poll_ppd_base.c
 #
 *   Copyright 2000 by Till Kamppeter
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License as
 *   published by the Free Software Foundation; either version 2 of the
 *   License, or (at your option) any later version.
 *
 *   This program 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 General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 *   02111-1307  USA
 *
 */

/*
 * Include necessary headers...
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <cups/cups.h>
#include <cups/ipp.h>
#include <cups/language.h>

// IPP Request routines for getting the printer type, stolen from QTCUPS from
// Michael Goffioul (file qtcups/cupshelper.cpp)

ipp_t* newIppRequest()
{
  ipp_t *request;
  cups_lang_t *lang;
  request = ippNew();
  request->request.op.request_id = 1;
  lang = cupsLangDefault();
  ippAddString(request,IPP_TAG_OPERATION,IPP_TAG_CHARSET,"attributes-charset",NULL,cupsLangEncoding(lang));
  ippAddString(request,IPP_TAG_OPERATION,IPP_TAG_LANGUAGE,"attributes-natural-language",NULL,lang->language);
  return request;
} 

ipp_t* processRequest(ipp_t *req, const char *res)
{
  http_t  *HTTP;
  ipp_t   *answer;
  HTTP = httpConnect(cupsServer(),ippPort());
  if (!HTTP) {
    ippDelete(req);
    return 0;
  }
  answer = cupsDoRequest(HTTP,req,res);
  httpClose(HTTP);
  if (!answer) return 0;
  if (answer->state == IPP_ERROR || answer->state == IPP_IDLE) {
    ippDelete(answer);
    return 0;
  }
  return answer;
} 

ipp_t *getPPDList()
{
  ipp_t       *request = newIppRequest();
  char        str[1024];
  const char* server = cupsServer();
  int         port = ippPort();

  request->request.op.operation_id = CUPS_GET_PPDS;
  if ((!server) || (port < 0)) return NULL;
  sprintf(str,"ipp://%s:%d/printers/",cupsServer(),ippPort());
  ippAddString(request,IPP_TAG_OPERATION,IPP_TAG_URI,"printer-uri",NULL,str);
  //str.sprintf("/printers/%s",name);
  request = processRequest(request,"/");
  return request;
} 

/*
 *  Main program
 */

int                 /* O - exit state */
main(int  argc,     /* I - Number of command-line arguments */
     char *argv[])  /* I - Command-line arguments */
{
  int		i,j;		/* Looping vars */
  int           makelen = 0;    /* Length of current manufacturer name */
  int           makelist = 0;   /* List of manufacturers */
  int           makegiven = 0;  /* List of models for given manufacturer */
  int           all = 0;        /* LIst of all models */
  char          *make;          /* Chosen manufacturer */
  ipp_t         *ppdlist;       /* List of PPD files resulting from IPP */
                                /* request */
  ipp_attribute_t *attr,        /* Current attribute */
                *last;          /* Last attribute */
  char          *currmake,      /* current data red from PPD list */
                *currmod,
                *currlang,
                *currfile,
                *c;
  char          buffer[80],
                buffer2[256];
  int           lineprinted = 1; /* Is the current line already printed to
                                    stdout */
  
  // read command line arguments

  for (i = 1; i < argc; i ++)
    if (argv[i][0] == '-') {
      switch (argv[i][1]) {
	case 'm' : /* Manufacturer options */
          if (argv[i][2] != '\0') {
            if (strcmp(argv[i],"-ml") == 0) {
              makelist = 1;
            } else {
              make = argv[i] + 2;
              makegiven = 1;
            }              
          } else {
            i ++;
            if (!(make = argv[i])) return 1;
            makegiven = 1;              
          }
          break;
        case 'a' : /* List all PPD files */
          all = 1;
          break;
	default :
          fprintf(stderr,"Unknown option \'%c\'!\n", argv[i][1]);
          fprintf(stderr,"Start program without options for help!\n");
          return(1);
      }
    } else {
      fprintf(stderr,"Unknown option \'%s\'!", argv[i]);
      fprintf(stderr,"Start program without options for help!\n");
      return(1);
    }
  if ((all) || (makegiven)) { // list all PPDs or PPDs of given manufacturer
    ppdlist = getPPDList();
    if (!ppdlist) return 1;
    for (attr = ppdlist->attrs; // go through all entries
         attr != NULL;
         attr = attr->next)
      if (attr->name) {
        // read data items
        if (strcmp(attr->name, "ppd-name") == 0) {
	  currfile = attr->values[0].string.text;
          lineprinted = 0;
        } else if (strcmp(attr->name, "ppd-make") == 0) {
          currmake = attr->values[0].string.text;
        } else if (strcmp(attr->name, "ppd-make-and-model") == 0) {
          currmod = attr->values[0].string.text;
        } else if (strcmp(attr->name, "ppd-natural-language") == 0) {
          currlang = attr->values[0].string.text;
        }
      } else { // attr->name = NULL ==> data set completed
        lineprinted = 1;
        // Fill empty entries with some default stuff
        if (!currmod) currmod = "UNKNOWN";
        if (!currmake) currmake = "UNKNOWN";
        if (!currlang) currlang = "en";
        // Remove the manufacturer's name from the model entries
        makelen = strlen(currmake);
        if (strcasecmp(currmake,"UNKNOWN") != 0) {
          if (strncasecmp(currmake,currmod,makelen) == 0) {
            currmod += makelen;
            while ((*currmod == ' ') ||
                   (*currmod == '-') || 
                   (*currmod == '\t')) currmod ++;
          }
        }
	// Make the manufacturer's name all-uppercase
        currmake = strcpy(buffer,currmake);
        for (i = 0; i < makelen; i ++) buffer[i] = toupper(buffer[i]);
	// Clean up the driver info
        currmod = strcpy(buffer2,currmod);
        if (c = strstr(currmod, "Foomatic + Postscript")) {
          memmove(c, "PostScript", 10);
	  memmove(c + 10, c + 21, strlen(c) - 20);
        } else if (c = strstr(currmod, "Foomatic")) {
	  memmove(c + 11, c + 8, strlen(c) - 7);
          memmove(c, "GhostScript", 11);
        } else if (c = strstr(currmod, "CUPS+GIMP-print")) {
	  memmove(c + 17, c + 15, strlen(c) - 14);
          memmove(c, "CUPS + GIMP-Print", 17);
        } else if (c = strstr(currmod, "Series CUPS")) {
	  memmove(c + 12, c + 11, strlen(c) - 10);
          memmove(c, "Series, CUPS", 12);
        } else if (!((strstr(currmod, "PostScript")) ||
                     (strstr(currmod, "Postscript")) ||
                     (strstr(currmod, "POSTSCRIPT")))) {
          memmove(currmod + strlen(currmod), ", PostScript", 13);
        }
        // Put data to stdout when "all" is chosen or when the manufacturer
        // matches the given one.
        if ((currfile) && ((all) || !strcasecmp(currmake,make)))
          printf("%s|%s|%s|%s\n",currfile,currmake,currmod,currlang);
      }
      if (!lineprinted) {
        // Fill empty entries with some default stuff
        if (!currmod) currmod = "UNKNOWN";
        if (!currmake) currmake = "UNKNOWN";
        if (!currlang) currlang = "en";
        // Remove the manufacturer's name from the model entries
        makelen = strlen(currmake);
        if (strcasecmp(currmake,"UNKNOWN") != 0) {
          if (strncasecmp(currmake,currmod,makelen) == 0) {
            currmod += makelen;
            while ((*currmod == ' ') ||
                   (*currmod == '-') || 
                   (*currmod == '\t')) currmod ++;
          }
        }
	// Make the manufacturer's name all-uppercase
        currmake = strcpy(buffer,currmake);
        for (i = 0; i < makelen; i ++) buffer[i] = toupper(buffer[i]);
	// Clean up the driver info
        currmod = strcpy(buffer2,currmod);
        if (c = strstr(currmod, "Foomatic + Postscript")) {
          memmove(c, "PostScript", 10);
	  memmove(c + 10, c + 21, strlen(c) - 20);
        } else if (c = strstr(currmod, "Foomatic")) {
	  memmove(c + 11, c + 8, strlen(c) - 7);
          memmove(c, "GhostScript", 11);
        } else if (c = strstr(currmod, "CUPS+GIMP-print")) {
	  memmove(c + 17, c + 15, strlen(c) - 14);
          memmove(c, "CUPS + GIMP-Print", 17);
        } else if (c = strstr(currmod, "Series CUPS")) {
	  memmove(c + 12, c + 11, strlen(c) - 10);
          memmove(c, "Series, CUPS", 12);
        } else if (!((strstr(currmod, "PostScript")) ||
                     (strstr(currmod, "Postscript")) ||
                     (strstr(currmod, "POSTSCRIPT")))) {
          memmove(currmod + strlen(currmod), ", PostScript", 13);
        }
        // Put data to stdout when "all" is chosen or when the manufacturer
        // matches the given one.
        if ((currfile) && ((all) || !strcasecmp(currmake,make)))
          printf("%s|%s|%s|%s\n",currfile,currmake,currmod,currlang);
      }
  } else if (makelist) { // list all manufacturers
    ppdlist = getPPDList(); 
    if (!ppdlist) return 1;
    for (attr = ppdlist->attrs, last = NULL; // go through all entries
         attr != NULL;
         attr = attr->next)
      if (attr->name && strcmp(attr->name, "ppd-make") == 0)
	                    // only search for manufacturerer entriees
        if (last == NULL ||
            strcasecmp(last->values[0].string.text,
                       attr->values[0].string.text) != 0)
	                    // Do not take the same manufacturer twice
          {
            // Put found manufacturer to stdout
            printf("%s\n",attr->values[0].string.text);
            last = attr;
          }
  } else { // Help!
    fprintf(stderr,"Usage:\n");
    fprintf(stderr,"------\n");
    fprintf(stderr,"\n");
    fprintf(stderr,"   poll_ppd_base\n");
    fprintf(stderr,"\n");
    fprintf(stderr,"      This help page\n");
    fprintf(stderr,"\n");
    fprintf(stderr,"   poll_ppd_base -a\n");
    fprintf(stderr,"\n");
    fprintf(stderr,"      List all PPD files\n");
    fprintf(stderr,"\n");
    fprintf(stderr,"   poll_ppd_base -ml\n");
    fprintf(stderr,"\n");
    fprintf(stderr,"      List of all printer manufacturers supported by the PPD files installed\n");
    fprintf(stderr,"\n");
    fprintf(stderr,"   poll_ppd_base -m <manufacturers name>\n");
    fprintf(stderr,"\n");
    fprintf(stderr,"      List of all supported printer models of this manufacturer\n");
    fprintf(stderr,"\n");
    fprintf(stderr,"ONLY WORKS WITH CUPS DAEMON RUNNING!\n");
    fprintf(stderr,"\n");
    return(1);
  }
  return(0);
}