Blame berkeley/lpq.c

Packit 2fc92b
/*
Packit 2fc92b
 * "lpq" command for CUPS.
Packit 2fc92b
 *
Packit 2fc92b
 * Copyright 2007-2016 by Apple Inc.
Packit 2fc92b
 * Copyright 1997-2006 by Easy Software Products.
Packit 2fc92b
 *
Packit 2fc92b
 * These coded instructions, statements, and computer programs are the
Packit 2fc92b
 * property of Apple Inc. and are protected by Federal copyright
Packit 2fc92b
 * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
Packit 2fc92b
 * which should have been included with this file.  If this file is
Packit 2fc92b
 * missing or damaged, see the license at "http://www.cups.org/".
Packit 2fc92b
 */
Packit 2fc92b
Packit 2fc92b
/*
Packit 2fc92b
 * Include necessary headers...
Packit 2fc92b
 */
Packit 2fc92b
Packit 2fc92b
#include <cups/cups-private.h>
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
/*
Packit 2fc92b
 * Local functions...
Packit 2fc92b
 */
Packit 2fc92b
Packit 2fc92b
static http_t	*connect_server(const char *, http_t *);
Packit 2fc92b
static int	show_jobs(const char *, http_t *, const char *,
Packit 2fc92b
		          const char *, const int, const int);
Packit 2fc92b
static void	show_printer(const char *, http_t *, const char *);
Packit 2fc92b
static void	usage(void) __attribute__((noreturn));
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
/*
Packit 2fc92b
 * 'main()' - Parse options and commands.
Packit 2fc92b
 */
Packit 2fc92b
Packit 2fc92b
int
Packit 2fc92b
main(int  argc,				/* I - Number of command-line arguments */
Packit 2fc92b
     char *argv[])			/* I - Command-line arguments */
Packit 2fc92b
{
Packit 2fc92b
  int		i;			/* Looping var */
Packit 2fc92b
  http_t	*http;			/* Connection to server */
Packit 2fc92b
  const char	*opt,			/* Option pointer */
Packit 2fc92b
		*dest,			/* Desired printer */
Packit 2fc92b
		*user,			/* Desired user */
Packit 2fc92b
		*val;			/* Environment variable name */
Packit 2fc92b
  char		*instance;		/* Printer instance */
Packit 2fc92b
  int		id,			/* Desired job ID */
Packit 2fc92b
		all,			/* All printers */
Packit 2fc92b
		interval,		/* Reporting interval */
Packit 2fc92b
		longstatus;		/* Show file details */
Packit 2fc92b
  cups_dest_t	*named_dest;		/* Named destination */
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
  _cupsSetLocale(argv);
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * Check for command-line options...
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  http       = NULL;
Packit 2fc92b
  dest       = NULL;
Packit 2fc92b
  user       = NULL;
Packit 2fc92b
  id         = 0;
Packit 2fc92b
  interval   = 0;
Packit 2fc92b
  longstatus = 0;
Packit 2fc92b
  all        = 0;
Packit 2fc92b
Packit 2fc92b
  for (i = 1; i < argc; i ++)
Packit 2fc92b
  {
Packit 2fc92b
    if (argv[i][0] == '+')
Packit 2fc92b
    {
Packit 2fc92b
      interval = atoi(argv[i] + 1);
Packit 2fc92b
    }
Packit 2fc92b
    else if (argv[i][0] == '-')
Packit 2fc92b
    {
Packit 2fc92b
      for (opt = argv[i] + 1; *opt; opt ++)
Packit 2fc92b
      {
Packit 2fc92b
	switch (*opt)
Packit 2fc92b
	{
Packit 2fc92b
	  case 'E' : /* Encrypt */
Packit 2fc92b
#ifdef HAVE_SSL
Packit 2fc92b
	      cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
Packit 2fc92b
Packit 2fc92b
	      if (http)
Packit 2fc92b
		httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
Packit 2fc92b
#else
Packit 2fc92b
	      _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]);
Packit 2fc92b
#endif /* HAVE_SSL */
Packit 2fc92b
	      break;
Packit 2fc92b
Packit 2fc92b
	  case 'U' : /* Username */
Packit 2fc92b
	      if (opt[1] != '\0')
Packit 2fc92b
	      {
Packit 2fc92b
		cupsSetUser(opt + 1);
Packit 2fc92b
		opt += strlen(opt) - 1;
Packit 2fc92b
	      }
Packit 2fc92b
	      else
Packit 2fc92b
	      {
Packit 2fc92b
		i ++;
Packit 2fc92b
		if (i >= argc)
Packit 2fc92b
		{
Packit 2fc92b
		  _cupsLangPrintf(stderr, _("%s: Error - expected username after \"-U\" option."), argv[0]);
Packit 2fc92b
		  return (1);
Packit 2fc92b
		}
Packit 2fc92b
Packit 2fc92b
		cupsSetUser(argv[i]);
Packit 2fc92b
	      }
Packit 2fc92b
	      break;
Packit 2fc92b
Packit 2fc92b
	  case 'P' : /* Printer */
Packit 2fc92b
	      if (opt[1] != '\0')
Packit 2fc92b
	      {
Packit 2fc92b
		dest = opt + 1;
Packit 2fc92b
		opt += strlen(opt) - 1;
Packit 2fc92b
	      }
Packit 2fc92b
	      else
Packit 2fc92b
	      {
Packit 2fc92b
		i ++;
Packit 2fc92b
Packit 2fc92b
		if (i >= argc)
Packit 2fc92b
		{
Packit 2fc92b
		  httpClose(http);
Packit 2fc92b
Packit 2fc92b
		  usage();
Packit 2fc92b
		}
Packit 2fc92b
Packit 2fc92b
		dest = argv[i];
Packit 2fc92b
	      }
Packit 2fc92b
Packit 2fc92b
	      if ((instance = strchr(dest, '/')) != NULL)
Packit 2fc92b
		*instance++ = '\0';
Packit 2fc92b
Packit 2fc92b
	      http = connect_server(argv[0], http);
Packit 2fc92b
Packit 2fc92b
	      if ((named_dest = cupsGetNamedDest(http, dest, instance)) == NULL)
Packit 2fc92b
	      {
Packit 2fc92b
		if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST ||
Packit 2fc92b
		    cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED)
Packit 2fc92b
		  _cupsLangPrintf(stderr, _("%s: Error - add '/version=1.1' to server name."), argv[0]);
Packit 2fc92b
		else if (instance)
Packit 2fc92b
		  _cupsLangPrintf(stderr, _("%s: Error - unknown destination \"%s/%s\"."), argv[0], dest, instance);
Packit 2fc92b
		else
Packit 2fc92b
		  _cupsLangPrintf(stderr, _("%s: Unknown destination \"%s\"."), argv[0], dest);
Packit 2fc92b
Packit 2fc92b
		return (1);
Packit 2fc92b
	      }
Packit 2fc92b
Packit 2fc92b
	      cupsFreeDests(1, named_dest);
Packit 2fc92b
	      break;
Packit 2fc92b
Packit 2fc92b
	  case 'a' : /* All printers */
Packit 2fc92b
	      all = 1;
Packit 2fc92b
	      break;
Packit 2fc92b
Packit 2fc92b
	  case 'h' : /* Connect to host */
Packit 2fc92b
	      if (http)
Packit 2fc92b
	      {
Packit 2fc92b
		httpClose(http);
Packit 2fc92b
		http = NULL;
Packit 2fc92b
	      }
Packit 2fc92b
Packit 2fc92b
	      if (opt[1] != '\0')
Packit 2fc92b
	      {
Packit 2fc92b
		cupsSetServer(opt + 1);
Packit 2fc92b
		opt += strlen(opt) - 1;
Packit 2fc92b
	      }
Packit 2fc92b
	      else
Packit 2fc92b
	      {
Packit 2fc92b
		i ++;
Packit 2fc92b
Packit 2fc92b
		if (i >= argc)
Packit 2fc92b
		{
Packit 2fc92b
		  _cupsLangPrintf(stderr, _("%s: Error - expected hostname after \"-h\" option."), argv[0]);
Packit 2fc92b
		  return (1);
Packit 2fc92b
		}
Packit 2fc92b
		else
Packit 2fc92b
		  cupsSetServer(argv[i]);
Packit 2fc92b
	      }
Packit 2fc92b
	      break;
Packit 2fc92b
Packit 2fc92b
	  case 'l' : /* Long status */
Packit 2fc92b
	      longstatus = 1;
Packit 2fc92b
	      break;
Packit 2fc92b
Packit 2fc92b
	  default :
Packit 2fc92b
	      httpClose(http);
Packit 2fc92b
Packit 2fc92b
	      usage();
Packit 2fc92b
	}
Packit 2fc92b
      }
Packit 2fc92b
    }
Packit 2fc92b
    else if (isdigit(argv[i][0] & 255))
Packit 2fc92b
    {
Packit 2fc92b
      id = atoi(argv[i]);
Packit 2fc92b
    }
Packit 2fc92b
    else
Packit 2fc92b
    {
Packit 2fc92b
      user = argv[i];
Packit 2fc92b
    }
Packit 2fc92b
  }
Packit 2fc92b
Packit 2fc92b
  http = connect_server(argv[0], http);
Packit 2fc92b
Packit 2fc92b
  if (dest == NULL && !all)
Packit 2fc92b
  {
Packit 2fc92b
    if ((named_dest = cupsGetNamedDest(http, NULL, NULL)) == NULL)
Packit 2fc92b
    {
Packit 2fc92b
      if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST ||
Packit 2fc92b
          cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED)
Packit 2fc92b
      {
Packit 2fc92b
	_cupsLangPrintf(stderr,
Packit 2fc92b
	                _("%s: Error - add '/version=1.1' to server name."),
Packit 2fc92b
			argv[0]);
Packit 2fc92b
        return (1);
Packit 2fc92b
      }
Packit 2fc92b
Packit 2fc92b
      val = NULL;
Packit 2fc92b
Packit 2fc92b
      if ((dest = getenv("LPDEST")) == NULL)
Packit 2fc92b
      {
Packit 2fc92b
	if ((dest = getenv("PRINTER")) != NULL)
Packit 2fc92b
	{
Packit 2fc92b
          if (!strcmp(dest, "lp"))
Packit 2fc92b
            dest = NULL;
Packit 2fc92b
	  else
Packit 2fc92b
	    val = "PRINTER";
Packit 2fc92b
	}
Packit 2fc92b
      }
Packit 2fc92b
      else
Packit 2fc92b
	val = "LPDEST";
Packit 2fc92b
Packit 2fc92b
      if (dest && val)
Packit 2fc92b
	_cupsLangPrintf(stderr,
Packit 2fc92b
	                _("%s: Error - %s environment variable names "
Packit 2fc92b
			  "non-existent destination \"%s\"."), argv[0], val,
Packit 2fc92b
			dest);
Packit 2fc92b
      else
Packit 2fc92b
	_cupsLangPrintf(stderr,
Packit 2fc92b
	                _("%s: Error - no default destination available."),
Packit 2fc92b
			argv[0]);
Packit 2fc92b
      httpClose(http);
Packit 2fc92b
      return (1);
Packit 2fc92b
    }
Packit 2fc92b
Packit 2fc92b
    dest = named_dest->name;
Packit 2fc92b
  }
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * Show the status in a loop...
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  for (;;)
Packit 2fc92b
  {
Packit 2fc92b
    if (dest)
Packit 2fc92b
      show_printer(argv[0], http, dest);
Packit 2fc92b
Packit 2fc92b
    i = show_jobs(argv[0], http, dest, user, id, longstatus);
Packit 2fc92b
Packit 2fc92b
    if (i && interval)
Packit 2fc92b
    {
Packit 2fc92b
      fflush(stdout);
Packit 2fc92b
      sleep((unsigned)interval);
Packit 2fc92b
    }
Packit 2fc92b
    else
Packit 2fc92b
      break;
Packit 2fc92b
  }
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * Close the connection to the server and return...
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  httpClose(http);
Packit 2fc92b
Packit 2fc92b
  return (0);
Packit 2fc92b
}
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
/*
Packit 2fc92b
 * 'connect_server()' - Connect to the server as necessary...
Packit 2fc92b
 */
Packit 2fc92b
Packit 2fc92b
static http_t *				/* O - New HTTP connection */
Packit 2fc92b
connect_server(const char *command,	/* I - Command name */
Packit 2fc92b
               http_t     *http)	/* I - Current HTTP connection */
Packit 2fc92b
{
Packit 2fc92b
  if (!http)
Packit 2fc92b
  {
Packit 2fc92b
    http = httpConnectEncrypt(cupsServer(), ippPort(),
Packit 2fc92b
	                      cupsEncryption());
Packit 2fc92b
Packit 2fc92b
    if (http == NULL)
Packit 2fc92b
    {
Packit 2fc92b
      _cupsLangPrintf(stderr, _("%s: Unable to connect to server."), command);
Packit 2fc92b
      exit(1);
Packit 2fc92b
    }
Packit 2fc92b
  }
Packit 2fc92b
Packit 2fc92b
  return (http);
Packit 2fc92b
}
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
/*
Packit 2fc92b
 * 'show_jobs()' - Show jobs.
Packit 2fc92b
 */
Packit 2fc92b
Packit 2fc92b
static int				/* O - Number of jobs in queue */
Packit 2fc92b
show_jobs(const char *command,		/* I - Command name */
Packit 2fc92b
          http_t     *http,		/* I - HTTP connection to server */
Packit 2fc92b
          const char *dest,		/* I - Destination */
Packit 2fc92b
	  const char *user,		/* I - User */
Packit 2fc92b
	  const int  id,		/* I - Job ID */
Packit 2fc92b
	  const int  longstatus)	/* I - 1 if long report desired */
Packit 2fc92b
{
Packit 2fc92b
  ipp_t		*request,		/* IPP Request */
Packit 2fc92b
		*response;		/* IPP Response */
Packit 2fc92b
  ipp_attribute_t *attr;		/* Current attribute */
Packit 2fc92b
  const char	*jobdest,		/* Pointer into job-printer-uri */
Packit 2fc92b
		*jobuser,		/* Pointer to job-originating-user-name */
Packit 2fc92b
		*jobname;		/* Pointer to job-name */
Packit 2fc92b
  ipp_jstate_t	jobstate;		/* job-state */
Packit 2fc92b
  int		jobid,			/* job-id */
Packit 2fc92b
		jobsize,		/* job-k-octets */
Packit 2fc92b
		jobcount,		/* Number of jobs */
Packit 2fc92b
		jobcopies,		/* Number of copies */
Packit 2fc92b
		rank;			/* Rank of job */
Packit 2fc92b
  char		resource[1024];		/* Resource string */
Packit 2fc92b
  char		rankstr[255];		/* Rank string */
Packit 2fc92b
  char		namestr[1024];		/* Job name string */
Packit 2fc92b
  static const char * const jobattrs[] =/* Job attributes we want to see */
Packit 2fc92b
		{
Packit 2fc92b
		  "copies",
Packit 2fc92b
		  "job-id",
Packit 2fc92b
		  "job-k-octets",
Packit 2fc92b
		  "job-name",
Packit 2fc92b
		  "job-originating-user-name",
Packit 2fc92b
		  "job-printer-uri",
Packit 2fc92b
		  "job-priority",
Packit 2fc92b
		  "job-state"
Packit 2fc92b
		};
Packit 2fc92b
  static const char * const ranks[10] =	/* Ranking strings */
Packit 2fc92b
		{
Packit 2fc92b
		  "th",
Packit 2fc92b
		  "st",
Packit 2fc92b
		  "nd",
Packit 2fc92b
		  "rd",
Packit 2fc92b
		  "th",
Packit 2fc92b
		  "th",
Packit 2fc92b
		  "th",
Packit 2fc92b
		  "th",
Packit 2fc92b
		  "th",
Packit 2fc92b
		  "th"
Packit 2fc92b
		};
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
  DEBUG_printf(("show_jobs(http=%p, dest=%p, user=%p, id=%d, longstatus%d)\n",
Packit 2fc92b
                http, dest, user, id, longstatus));
Packit 2fc92b
Packit 2fc92b
  if (http == NULL)
Packit 2fc92b
    return (0);
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * Build an IPP_GET_JOBS or IPP_GET_JOB_ATTRIBUTES request, which requires
Packit 2fc92b
  * the following attributes:
Packit 2fc92b
  *
Packit 2fc92b
  *    attributes-charset
Packit 2fc92b
  *    attributes-natural-language
Packit 2fc92b
  *    job-uri or printer-uri
Packit 2fc92b
  *    requested-attributes
Packit 2fc92b
  *    requesting-user-name
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  request = ippNewRequest(id ? IPP_GET_JOB_ATTRIBUTES : IPP_GET_JOBS);
Packit 2fc92b
Packit 2fc92b
  if (id)
Packit 2fc92b
  {
Packit 2fc92b
    snprintf(resource, sizeof(resource), "ipp://localhost/jobs/%d", id);
Packit 2fc92b
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
Packit 2fc92b
                 NULL, resource);
Packit 2fc92b
  }
Packit 2fc92b
  else if (dest)
Packit 2fc92b
  {
Packit 2fc92b
    httpAssembleURIf(HTTP_URI_CODING_ALL, resource, sizeof(resource), "ipp",
Packit 2fc92b
                     NULL, "localhost", 0, "/printers/%s", dest);
Packit 2fc92b
Packit 2fc92b
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
Packit 2fc92b
                 NULL, resource);
Packit 2fc92b
  }
Packit 2fc92b
  else
Packit 2fc92b
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
Packit 2fc92b
                 NULL, "ipp://localhost/");
Packit 2fc92b
Packit 2fc92b
  if (user)
Packit 2fc92b
  {
Packit 2fc92b
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
Packit 2fc92b
                 "requesting-user-name", NULL, user);
Packit 2fc92b
    ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1);
Packit 2fc92b
  }
Packit 2fc92b
  else
Packit 2fc92b
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
Packit 2fc92b
                 "requesting-user-name", NULL, cupsUser());
Packit 2fc92b
Packit 2fc92b
  ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
Packit 2fc92b
                "requested-attributes",
Packit 2fc92b
                (int)(sizeof(jobattrs) / sizeof(jobattrs[0])), NULL, jobattrs);
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * Do the request and get back a response...
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  jobcount = 0;
Packit 2fc92b
Packit 2fc92b
  if ((response = cupsDoRequest(http, request, "/")) != NULL)
Packit 2fc92b
  {
Packit 2fc92b
    if (response->request.status.status_code > IPP_OK_CONFLICT)
Packit 2fc92b
    {
Packit 2fc92b
      _cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString());
Packit 2fc92b
      ippDelete(response);
Packit 2fc92b
      return (0);
Packit 2fc92b
    }
Packit 2fc92b
Packit 2fc92b
    rank = 1;
Packit 2fc92b
Packit 2fc92b
   /*
Packit 2fc92b
    * Loop through the job list and display them...
Packit 2fc92b
    */
Packit 2fc92b
Packit 2fc92b
    for (attr = response->attrs; attr != NULL; attr = attr->next)
Packit 2fc92b
    {
Packit 2fc92b
     /*
Packit 2fc92b
      * Skip leading attributes until we hit a job...
Packit 2fc92b
      */
Packit 2fc92b
Packit 2fc92b
      while (attr != NULL && attr->group_tag != IPP_TAG_JOB)
Packit 2fc92b
        attr = attr->next;
Packit 2fc92b
Packit 2fc92b
      if (attr == NULL)
Packit 2fc92b
        break;
Packit 2fc92b
Packit 2fc92b
     /*
Packit 2fc92b
      * Pull the needed attributes from this job...
Packit 2fc92b
      */
Packit 2fc92b
Packit 2fc92b
      jobid       = 0;
Packit 2fc92b
      jobsize     = 0;
Packit 2fc92b
      jobstate    = IPP_JOB_PENDING;
Packit 2fc92b
      jobname     = "unknown";
Packit 2fc92b
      jobuser     = "unknown";
Packit 2fc92b
      jobdest     = NULL;
Packit 2fc92b
      jobcopies   = 1;
Packit 2fc92b
Packit 2fc92b
      while (attr != NULL && attr->group_tag == IPP_TAG_JOB)
Packit 2fc92b
      {
Packit 2fc92b
        if (!strcmp(attr->name, "job-id") &&
Packit 2fc92b
	    attr->value_tag == IPP_TAG_INTEGER)
Packit 2fc92b
	  jobid = attr->values[0].integer;
Packit 2fc92b
Packit 2fc92b
        if (!strcmp(attr->name, "job-k-octets") &&
Packit 2fc92b
	    attr->value_tag == IPP_TAG_INTEGER)
Packit 2fc92b
	  jobsize = attr->values[0].integer;
Packit 2fc92b
Packit 2fc92b
        if (!strcmp(attr->name, "job-state") &&
Packit 2fc92b
	    attr->value_tag == IPP_TAG_ENUM)
Packit 2fc92b
	  jobstate = (ipp_jstate_t)attr->values[0].integer;
Packit 2fc92b
Packit 2fc92b
        if (!strcmp(attr->name, "job-printer-uri") &&
Packit 2fc92b
	    attr->value_tag == IPP_TAG_URI)
Packit 2fc92b
	  if ((jobdest = strrchr(attr->values[0].string.text, '/')) != NULL)
Packit 2fc92b
	    jobdest ++;
Packit 2fc92b
Packit 2fc92b
        if (!strcmp(attr->name, "job-originating-user-name") &&
Packit 2fc92b
	    attr->value_tag == IPP_TAG_NAME)
Packit 2fc92b
	  jobuser = attr->values[0].string.text;
Packit 2fc92b
Packit 2fc92b
        if (!strcmp(attr->name, "job-name") &&
Packit 2fc92b
	    attr->value_tag == IPP_TAG_NAME)
Packit 2fc92b
	  jobname = attr->values[0].string.text;
Packit 2fc92b
Packit 2fc92b
        if (!strcmp(attr->name, "copies") &&
Packit 2fc92b
	    attr->value_tag == IPP_TAG_INTEGER)
Packit 2fc92b
	  jobcopies = attr->values[0].integer;
Packit 2fc92b
Packit 2fc92b
        attr = attr->next;
Packit 2fc92b
      }
Packit 2fc92b
Packit 2fc92b
     /*
Packit 2fc92b
      * See if we have everything needed...
Packit 2fc92b
      */
Packit 2fc92b
Packit 2fc92b
      if (jobdest == NULL || jobid == 0)
Packit 2fc92b
      {
Packit 2fc92b
        if (attr == NULL)
Packit 2fc92b
	  break;
Packit 2fc92b
	else
Packit 2fc92b
          continue;
Packit 2fc92b
      }
Packit 2fc92b
Packit 2fc92b
      if (!longstatus && jobcount == 0)
Packit 2fc92b
	_cupsLangPuts(stdout,
Packit 2fc92b
	              _("Rank    Owner   Job     File(s)"
Packit 2fc92b
		        "                         Total Size"));
Packit 2fc92b
Packit 2fc92b
      jobcount ++;
Packit 2fc92b
Packit 2fc92b
     /*
Packit 2fc92b
      * Display the job...
Packit 2fc92b
      */
Packit 2fc92b
Packit 2fc92b
      if (jobstate == IPP_JOB_PROCESSING)
Packit 2fc92b
	strlcpy(rankstr, "active", sizeof(rankstr));
Packit 2fc92b
      else
Packit 2fc92b
      {
Packit 2fc92b
       /*
Packit 2fc92b
        * Make the rank show the "correct" suffix for each number
Packit 2fc92b
	* (11-13 are the only special cases, for English anyways...)
Packit 2fc92b
	*/
Packit 2fc92b
Packit 2fc92b
	if ((rank % 100) >= 11 && (rank % 100) <= 13)
Packit 2fc92b
	  snprintf(rankstr, sizeof(rankstr), "%dth", rank);
Packit 2fc92b
	else
Packit 2fc92b
	  snprintf(rankstr, sizeof(rankstr), "%d%s", rank, ranks[rank % 10]);
Packit 2fc92b
Packit 2fc92b
	rank ++;
Packit 2fc92b
      }
Packit 2fc92b
Packit 2fc92b
      if (longstatus)
Packit 2fc92b
      {
Packit 2fc92b
        _cupsLangPuts(stdout, "\n");
Packit 2fc92b
Packit 2fc92b
        if (jobcopies > 1)
Packit 2fc92b
	  snprintf(namestr, sizeof(namestr), "%d copies of %s", jobcopies,
Packit 2fc92b
	           jobname);
Packit 2fc92b
	else
Packit 2fc92b
	  strlcpy(namestr, jobname, sizeof(namestr));
Packit 2fc92b
Packit 2fc92b
        _cupsLangPrintf(stdout, _("%s: %-33.33s [job %d localhost]"),
Packit 2fc92b
	                jobuser, rankstr, jobid);
Packit 2fc92b
        _cupsLangPrintf(stdout, _("        %-39.39s %.0f bytes"),
Packit 2fc92b
	                namestr, 1024.0 * jobsize);
Packit 2fc92b
      }
Packit 2fc92b
      else
Packit 2fc92b
        _cupsLangPrintf(stdout,
Packit 2fc92b
	                _("%-7s %-7.7s %-7d %-31.31s %.0f bytes"),
Packit 2fc92b
			rankstr, jobuser, jobid, jobname, 1024.0 * jobsize);
Packit 2fc92b
Packit 2fc92b
      if (attr == NULL)
Packit 2fc92b
        break;
Packit 2fc92b
    }
Packit 2fc92b
Packit 2fc92b
    ippDelete(response);
Packit 2fc92b
  }
Packit 2fc92b
  else
Packit 2fc92b
  {
Packit 2fc92b
    _cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString());
Packit 2fc92b
    return (0);
Packit 2fc92b
  }
Packit 2fc92b
Packit 2fc92b
  if (jobcount == 0)
Packit 2fc92b
    _cupsLangPuts(stdout, _("no entries"));
Packit 2fc92b
Packit 2fc92b
  return (jobcount);
Packit 2fc92b
}
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
/*
Packit 2fc92b
 * 'show_printer()' - Show printer status.
Packit 2fc92b
 */
Packit 2fc92b
Packit 2fc92b
static void
Packit 2fc92b
show_printer(const char *command,	/* I - Command name */
Packit 2fc92b
             http_t     *http,		/* I - HTTP connection to server */
Packit 2fc92b
             const char *dest)		/* I - Destination */
Packit 2fc92b
{
Packit 2fc92b
  ipp_t		*request,		/* IPP Request */
Packit 2fc92b
		*response;		/* IPP Response */
Packit 2fc92b
  ipp_attribute_t *attr;		/* Current attribute */
Packit 2fc92b
  ipp_pstate_t	state;			/* Printer state */
Packit 2fc92b
  char		uri[HTTP_MAX_URI];	/* Printer URI */
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
  if (http == NULL)
Packit 2fc92b
    return;
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
Packit 2fc92b
  * attributes:
Packit 2fc92b
  *
Packit 2fc92b
  *    attributes-charset
Packit 2fc92b
  *    attributes-natural-language
Packit 2fc92b
  *    printer-uri
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
Packit 2fc92b
Packit 2fc92b
  httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
Packit 2fc92b
                   "localhost", 0, "/printers/%s", dest);
Packit 2fc92b
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
Packit 2fc92b
               "printer-uri", NULL, uri);
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * Do the request and get back a response...
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  if ((response = cupsDoRequest(http, request, "/")) != NULL)
Packit 2fc92b
  {
Packit 2fc92b
    if (response->request.status.status_code > IPP_OK_CONFLICT)
Packit 2fc92b
    {
Packit 2fc92b
      _cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString());
Packit 2fc92b
      ippDelete(response);
Packit 2fc92b
      return;
Packit 2fc92b
    }
Packit 2fc92b
Packit 2fc92b
    if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL)
Packit 2fc92b
      state = (ipp_pstate_t)attr->values[0].integer;
Packit 2fc92b
    else
Packit 2fc92b
      state = IPP_PRINTER_STOPPED;
Packit 2fc92b
Packit 2fc92b
    switch (state)
Packit 2fc92b
    {
Packit 2fc92b
      case IPP_PRINTER_IDLE :
Packit 2fc92b
          _cupsLangPrintf(stdout, _("%s is ready"), dest);
Packit 2fc92b
	  break;
Packit 2fc92b
      case IPP_PRINTER_PROCESSING :
Packit 2fc92b
          _cupsLangPrintf(stdout, _("%s is ready and printing"),
Packit 2fc92b
	                  dest);
Packit 2fc92b
	  break;
Packit 2fc92b
      case IPP_PRINTER_STOPPED :
Packit 2fc92b
          _cupsLangPrintf(stdout, _("%s is not ready"), dest);
Packit 2fc92b
	  break;
Packit 2fc92b
    }
Packit 2fc92b
Packit 2fc92b
    ippDelete(response);
Packit 2fc92b
  }
Packit 2fc92b
  else
Packit 2fc92b
    _cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString());
Packit 2fc92b
}
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
/*
Packit 2fc92b
 * 'usage()' - Show program usage.
Packit 2fc92b
 */
Packit 2fc92b
Packit 2fc92b
static void
Packit 2fc92b
usage(void)
Packit 2fc92b
{
Packit 2fc92b
  _cupsLangPuts(stderr,
Packit 2fc92b
                _("Usage: lpq [-P dest] [-U username] [-h hostname[:port]] "
Packit 2fc92b
		  "[-l] [+interval]"));
Packit 2fc92b
  exit(1);
Packit 2fc92b
}