/*
 * Filtering program for CUPS.
 *
 * Copyright 2007-2016 by Apple Inc.
 * Copyright 1997-2006 by Easy Software Products, all rights reserved.
 *
 * Licensed under Apache License v2.0.  See the file "LICENSE" for more information.
 */

/*
 * Include necessary headers...
 */

#include <cups/cups-private.h>
#include <cups/file-private.h>
#include <cups/ppd-private.h>
#include "mime.h"
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/wait.h>
#if defined(__APPLE__)
#  include <libgen.h>
#endif /* __APPLE__ */


/*
 * Local globals...
 */

static char		*DataDir = NULL;/* CUPS_DATADIR environment variable */
static char		*FontPath = NULL;
					/* CUPS_FONTPATH environment variable */
static mime_filter_t	GZIPFilter =	/* gziptoany filter */
{
  NULL,					/* Source type */
  NULL,					/* Destination type */
  0,					/* Cost */
  "gziptoany"				/* Filter program to run */
};
static char		*Path = NULL;	/* PATH environment variable */
static char		*ServerBin = NULL;
					/* CUPS_SERVERBIN environment variable */
static char		*ServerRoot = NULL;
					/* CUPS_SERVERROOT environment variable */
static char		*RIPCache = NULL;
					/* RIP_MAX_CACHE environment variable */
static char		TempFile[1024] = "";
					/* Temporary file */


/*
 * Local functions...
 */

static void		add_printer_filter(const char *command, mime_t *mime,
			                   mime_type_t *printer_type,
		                           const char  *filter);
static mime_type_t	*add_printer_filters(const char *command,
					     mime_t *mime, const char *printer,
			                     const char *ppdfile,
					     mime_type_t **prefilter_type);
static void		check_cb(void *context, _cups_fc_result_t result,
				 const char *message);
static int		compare_pids(mime_filter_t *a, mime_filter_t *b);
static char		*escape_options(int num_options, cups_option_t *options);
static int		exec_filter(const char *filter, char **argv,
			            char **envp, int infd, int outfd);
static int		exec_filters(mime_type_t *srctype,
			             cups_array_t *filters, const char *infile,
		                     const char *outfile, const char *ppdfile,
			             const char *printer, const char *user,
				     const char *title, int num_options,
			             cups_option_t *options);
static void		get_job_file(const char *job);
static int		open_pipe(int *fds);
static int		read_cups_files_conf(const char *filename);
static void		set_string(char **s, const char *val);
static void		sighandler(int sig);
static void		usage(const char *opt) _CUPS_NORETURN;


/*
 * 'main()' - Main entry for the test program.
 */

int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line args */
     char *argv[])			/* I - Command-line arguments */
{
  int		i,			/* Looping vars */
		list_filters = 0;	/* Just list the filters? */
  const char	*command,		/* Command name */
		*opt,			/* Current option */
		*printer;		/* Printer name */
  mime_type_t	*printer_type,		/* Printer MIME type */
		*prefilter_type;	/* Printer prefilter MIME type */
  char		*srctype,		/* Source type */
		*dsttype,		/* Destination type */
		super[MIME_MAX_SUPER],	/* Super-type name */
		type[MIME_MAX_TYPE];	/* Type name */
  int		compression;		/* Compression of file */
  int		cost;			/* Cost of filters */
  mime_t	*mime;			/* MIME database */
  char		mimedir[1024];		/* MIME directory */
  char		*infile,		/* File to filter */
		*outfile;		/* File to create */
  char		cupsfilesconf[1024];	/* cups-files.conf file */
  const char	*server_root;		/* CUPS_SERVERROOT environment variable */
  mime_type_t	*src,			/* Source type */
		*dst;			/* Destination type */
  cups_array_t	*filters;		/* Filters for the file */
  int		num_options;		/* Number of options */
  cups_option_t	*options;		/* Options */
  const char	*ppdfile;		/* PPD file */
  const char	*title,			/* Title string */
		*user;			/* Username */
  int		all_filters,		/* Use all filters */
		removeppd,		/* Remove PPD file */
		removeinfile;		/* Remove input file */
  int		status;			/* Execution status */


 /*
  * Setup defaults...
  */

  if ((command = strrchr(argv[0], '/')) != NULL)
    command ++;
  else
    command = argv[0];

  printer      = !strcmp(command, "convert") ? "tofile" : "cupsfilter";
  mime         = NULL;
  srctype      = NULL;
  compression  = 0;
  dsttype      = "application/pdf";
  infile       = NULL;
  outfile      = NULL;
  num_options  = 0;
  options      = NULL;
  ppdfile      = NULL;
  title        = NULL;
  user         = cupsUser();
  all_filters  = 0;
  removeppd    = 0;
  removeinfile = 0;

  if ((server_root = getenv("CUPS_SERVERROOT")) == NULL)
    server_root = CUPS_SERVERROOT;

  snprintf(cupsfilesconf, sizeof(cupsfilesconf), "%s/cups-files.conf", server_root);

 /*
  * Process command-line arguments...
  */

  _cupsSetLocale(argv);

  for (i = 1; i < argc; i ++)
  {
    if (argv[i][0] == '-')
    {
      if (!strcmp(argv[i], "--list-filters"))
      {
        list_filters = 1;
      }
      else if (!strcmp(argv[i], "--"))
      {
	i ++;
	if (i < argc && !infile)
	  infile = argv[i];
	else
	  usage(NULL);
      }
      else
      {
	for (opt = argv[i] + 1; *opt; opt ++)
	{
	  switch (*opt)
	  {
	    case 'a' : /* Specify option... */
		i ++;
		if (i < argc)
		  num_options = cupsParseOptions(argv[i], num_options, &options);
		else
		  usage(opt);
		break;

	    case 'c' : /* Specify cups-files.conf file location... */
		i ++;
		if (i < argc)
		{
		  if (!strcmp(command, "convert"))
		    num_options = cupsAddOption("copies", argv[i], num_options, &options);
		  else
		    strlcpy(cupsfilesconf, argv[i], sizeof(cupsfilesconf));
		}
		else
		  usage(opt);
		break;

	    case 'd' : /* Specify the real printer name */
		i ++;
		if (i < argc)
		  printer = argv[i];
		else
		  usage(opt);
		break;

	    case 'D' : /* Delete input file after conversion */
		removeinfile = 1;
		break;

	    case 'e' : /* Use every filter from the PPD file */
		all_filters = 1;
		break;

	    case 'f' : /* Specify input file... */
		i ++;
		if (i < argc && !infile)
		  infile = argv[i];
		else
		  usage(opt);
		break;

	    case 'i' : /* Specify source MIME type... */
		i ++;
		if (i < argc)
		{
		  if (sscanf(argv[i], "%15[^/]/%255s", super, type) != 2)
		    usage(opt);

		  srctype = argv[i];
		}
		else
		  usage(opt);
		break;

	    case 'j' : /* Get job file or specify destination MIME type... */
		if (strcmp(command, "convert"))
		{
		  i ++;
		  if (i < argc)
		  {
		    get_job_file(argv[i]);
		    infile = TempFile;
		  }
		  else
		    usage(opt);

		  break;
		}

	    case 'm' : /* Specify destination MIME type... */
		i ++;
		if (i < argc)
		{
		  if (sscanf(argv[i], "%15[^/]/%255s", super, type) != 2)
		    usage(opt);

		  dsttype = argv[i];
		}
		else
		  usage(opt);
		break;

	    case 'n' : /* Specify number of copies... */
		i ++;
		if (i < argc)
		  num_options = cupsAddOption("copies", argv[i], num_options, &options);
		else
		  usage(opt);
		break;

	    case 'o' : /* Specify option(s) or output filename */
		i ++;
		if (i < argc)
		{
		  if (!strcmp(command, "convert"))
		  {
		    if (outfile)
		      usage(NULL);
		    else
		      outfile = argv[i];
		  }
		  else
		    num_options = cupsParseOptions(argv[i], num_options, &options);
		}
		else
		  usage(opt);
		break;

	    case 'p' : /* Specify PPD file... */
	    case 'P' : /* Specify PPD file... */
		i ++;
		if (i < argc)
		  ppdfile = argv[i];
		else
		  usage(opt);
		break;

	    case 't' : /* Specify title... */
	    case 'J' : /* Specify title... */
		i ++;
		if (i < argc)
		  title = argv[i];
		else
		  usage(opt);
		break;

	    case 'u' : /* Delete PPD file after conversion */
		removeppd = 1;
		break;

	    case 'U' : /* Specify username... */
		i ++;
		if (i < argc)
		  user = argv[i];
		else
		  usage(opt);
		break;

	    default : /* Something we don't understand... */
		usage(opt);
		break;
	  }
	}
      }
    }
    else if (!infile)
    {
      if (strcmp(command, "convert"))
	infile = argv[i];
      else
	usage(NULL);
    }
    else
    {
      _cupsLangPuts(stderr,
                    _("cupsfilter: Only one filename can be specified."));
      usage(NULL);
    }
  }

  if (!infile && !srctype)
    usage(NULL);

  if (!title)
  {
    if (!infile)
      title = "(stdin)";
    else if ((title = strrchr(infile, '/')) != NULL)
      title ++;
    else
      title = infile;
  }

 /*
  * Load the cups-files.conf file and create the MIME database...
  */

  if (read_cups_files_conf(cupsfilesconf))
    return (1);

  snprintf(mimedir, sizeof(mimedir), "%s/mime", DataDir);

  mime = mimeLoadTypes(NULL, mimedir);
  mime = mimeLoadTypes(mime, ServerRoot);
  mime = mimeLoadFilters(mime, mimedir, Path);
  mime = mimeLoadFilters(mime, ServerRoot, Path);

  if (!mime)
  {
    _cupsLangPrintf(stderr,
                    _("%s: Unable to read MIME database from \"%s\" or "
		      "\"%s\"."),
		    command, mimedir, ServerRoot);
    return (1);
  }

  prefilter_type = NULL;

  if (all_filters)
    printer_type = add_printer_filters(command, mime, printer, ppdfile,
				       &prefilter_type);
  else
    printer_type   = mimeType(mime, "application", "vnd.cups-postscript");

 /*
  * Get the source and destination types...
  */

  if (srctype)
  {
   /* sscanf return value already checked above */
    sscanf(srctype, "%15[^/]/%255s", super, type);
    if ((src = mimeType(mime, super, type)) == NULL)
    {
      _cupsLangPrintf(stderr,
		      _("%s: Unknown source MIME type %s/%s."),
		      command, super, type);
      return (1);
    }
  }
  else if ((src = mimeFileType(mime, infile, infile, &compression)) == NULL)
  {
    _cupsLangPrintf(stderr,
                    _("%s: Unable to determine MIME type of \"%s\"."),
		    command, infile);
    return (1);
  }

 /* sscanf return value already checked above */
  sscanf(dsttype, "%15[^/]/%255s", super, type);
  if (!_cups_strcasecmp(super, "printer"))
    dst = printer_type;
  else if ((dst = mimeType(mime, super, type)) == NULL)
  {
    _cupsLangPrintf(stderr,
                    _("%s: Unknown destination MIME type %s/%s."),
		    command, super, type);
    return (1);
  }

 /*
  * Figure out how to filter the file...
  */

  if (src == dst)
  {
   /*
    * Special case - no filtering needed...
    */

    filters = cupsArrayNew(NULL, NULL);
    cupsArrayAdd(filters, &GZIPFilter);
    GZIPFilter.src = src;
    GZIPFilter.dst = dst;
  }
  else if ((filters = mimeFilter(mime, src, dst, &cost)) == NULL)
  {
    _cupsLangPrintf(stderr,
                    _("%s: No filter to convert from %s/%s to %s/%s."),
		    command, src->super, src->type, dst->super, dst->type);
    return (1);
  }
  else if (compression)
    cupsArrayInsert(filters, &GZIPFilter);

  if (prefilter_type)
  {
   /*
    * Add pre-filters...
    */

    mime_filter_t	*filter,	/* Current filter */
			*prefilter;	/* Current pre-filter */
    cups_array_t	*prefilters = cupsArrayNew(NULL, NULL);
					/* New filters array */


    for (filter = (mime_filter_t *)cupsArrayFirst(filters);
	 filter;
	 filter = (mime_filter_t *)cupsArrayNext(filters))
    {
      if ((prefilter = mimeFilterLookup(mime, filter->src,
                                        prefilter_type)) != NULL)
	cupsArrayAdd(prefilters, prefilter);

      cupsArrayAdd(prefilters, filter);
    }

    cupsArrayDelete(filters);
    filters = prefilters;
  }

  if (list_filters)
  {
   /*
    * List filters...
    */

    mime_filter_t	*filter;	/* Current filter */

    for (filter = (mime_filter_t *)cupsArrayFirst(filters);
	 filter;
	 filter = (mime_filter_t *)cupsArrayNext(filters))
      if (strcmp(filter->filter, "-"))
        _cupsLangPuts(stdout, filter->filter);

    status = 0;
  }
  else
  {
   /*
    * Run filters...
    */

    status = exec_filters(src, filters, infile, outfile, ppdfile, printer, user,
			  title, num_options, options);
  }

 /*
  * Remove files as needed, then exit...
  */

  if (TempFile[0])
    unlink(TempFile);

  if (removeppd && ppdfile)
    unlink(ppdfile);

  if (removeinfile && infile)
    unlink(infile);

  return (status);
}


/*
 * 'add_printer_filter()' - Add a single filters from a PPD file.
 */

static void
add_printer_filter(
    const char  *command,		/* I - Command name */
    mime_t      *mime,			/* I - MIME database */
    mime_type_t *filtertype,		/* I - Printer or prefilter MIME type */
    const char  *filter)		/* I - Filter to add */
{
  char		super[MIME_MAX_SUPER],	/* Super-type for filter */
		type[MIME_MAX_TYPE],	/* Type for filter */
		dsuper[MIME_MAX_SUPER],	/* Destination super-type for filter */
		dtype[MIME_MAX_TYPE],	/* Destination type for filter */
		dest[MIME_MAX_SUPER + MIME_MAX_TYPE + 2],
					/* Destination super/type */
		program[1024];		/* Program/filter name */
  int		cost;			/* Cost of filter */
  size_t	maxsize = 0;		/* Maximum supported file size */
  mime_type_t	*temptype,		/* MIME type looping var */
		*desttype;		/* Destination MIME type */
  mime_filter_t	*filterptr;		/* MIME filter */


 /*
  * Parse the filter string; it should be in one of the following formats:
  *
  *     source/type cost program
  *     source/type cost maxsize(nnnn) program
  *     source/type dest/type cost program
  *     source/type dest/type cost maxsize(nnnn) program
  */

  if (sscanf(filter, "%15[^/]/%255s%*[ \t]%15[^/]/%255s%d%*[ \t]%1023[^\n]",
             super, type, dsuper, dtype, &cost, program) == 6)
  {
    snprintf(dest, sizeof(dest), "%s/%s/%s", filtertype->type, dsuper, dtype);

    if ((desttype = mimeType(mime, "printer", dest)) == NULL)
      desttype = mimeAddType(mime, "printer", dest);
  }
  else
  {
    if (sscanf(filter, "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super, type, &cost,
               program) == 4)
    {
      desttype = filtertype;
    }
    else
    {
      _cupsLangPrintf(stderr, _("%s: Invalid filter string \"%s\"."), command,
		      filter);
      return;
    }
  }

  if (!strncmp(program, "maxsize(", 8))
  {
    char	*ptr;			/* Pointer into maxsize(nnnn) program */

    maxsize = (size_t)strtoll(program + 8, &ptr, 10);

    if (*ptr != ')')
    {
      printf("testmime: Invalid filter string \"%s\".\n", filter);
      return;
    }

    ptr ++;
    while (_cups_isspace(*ptr))
      ptr ++;

    _cups_strcpy(program, ptr);
  }

 /*
  * See if the filter program exists; if not, stop the printer and flag
  * the error!
  */

  if (strcmp(program, "-"))
  {
    char filename[1024];		/* Full path to program */

    if (program[0] == '/')
      strlcpy(filename, program, sizeof(filename));
    else
      snprintf(filename, sizeof(filename), "%s/filter/%s", ServerBin, program);

    if (_cupsFileCheck(filename, _CUPS_FILE_CHECK_PROGRAM, !geteuid(), check_cb,
                       (void *)command))
      return;
  }

 /*
  * Add the filter to the MIME database, supporting wildcards as needed...
  */

  for (temptype = mimeFirstType(mime);
       temptype;
       temptype = mimeNextType(mime))
    if (((super[0] == '*' && _cups_strcasecmp(temptype->super, "printer")) ||
         !_cups_strcasecmp(temptype->super, super)) &&
        (type[0] == '*' || !_cups_strcasecmp(temptype->type, type)))
    {
      if (desttype != filtertype)
      {
        filterptr = mimeAddFilter(mime, temptype, desttype, cost, program);

        if (!mimeFilterLookup(mime, desttype, filtertype))
          mimeAddFilter(mime, desttype, filtertype, 0, "-");
      }
      else
        filterptr = mimeAddFilter(mime, temptype, filtertype, cost, program);

      if (filterptr)
	filterptr->maxsize = maxsize;
    }
}


/*
 * 'add_printer_filters()' - Add filters from a PPD file.
 */

static mime_type_t *			/* O - Printer type or NULL on error */
add_printer_filters(
    const char  *command,		/* I - Command name */
    mime_t      *mime,			/* I - MIME database */
    const char  *printer,		/* I - Printer name */
    const char  *ppdfile,		/* I - PPD file */
    mime_type_t **prefilter_type)	/* O - Prefilter type */
{
  ppd_file_t	*ppd;			/* PPD file data */
  _ppd_cache_t	*pc;			/* Cache data for PPD */
  const char	*value;			/* Filter definition value */
  mime_type_t	*printer_type;		/* Printer filter type */


  if ((ppd = _ppdOpenFile(ppdfile, _PPD_LOCALIZATION_NONE)) == NULL)
  {
    ppd_status_t	status;		/* PPD load status */
    int			linenum;	/* Line number */

    status = ppdLastError(&linenum);
    _cupsLangPrintf(stderr, _("%s: Unable to open PPD file: %s on line %d."),
                    command, ppdErrorString(status), linenum);
    return (NULL);
  }

  pc = _ppdCacheCreateWithPPD(ppd);
  if (!pc)
    return (NULL);

  printer_type    = mimeAddType(mime, "printer", printer);
  *prefilter_type = NULL;

  if (pc->filters)
  {
    for (value = (const char *)cupsArrayFirst(pc->filters);
         value;
         value = (const char *)cupsArrayNext(pc->filters))
      add_printer_filter(command, mime, printer_type, value);
  }
  else
  {
    add_printer_filter(command, mime, printer_type,
                       "application/vnd.cups-raw 0 -");
    add_printer_filter(command, mime, printer_type,
                       "application/vnd.cups-postscript 0 -");
  }

  if (pc->prefilters)
  {
    *prefilter_type = mimeAddType(mime, "prefilter", printer);

    for (value = (const char *)cupsArrayFirst(pc->prefilters);
         value;
         value = (const char *)cupsArrayNext(pc->prefilters))
      add_printer_filter(command, mime, *prefilter_type, value);
  }

  return (printer_type);
}


/*
 * 'check_cb()' - Callback function for _cupsFileCheck.
 */

static void
check_cb(void              *context,	/* I - Context (command name) */
         _cups_fc_result_t result,	/* I - Result of check */
	 const char        *message)	/* I - Localized message */
{
  (void)result;

  _cupsLangPrintf(stderr, _("%s: %s"), (char *)context, message);
}


/*
 * 'compare_pids()' - Compare two filter PIDs...
 */

static int				/* O - Result of comparison */
compare_pids(mime_filter_t *a,		/* I - First filter */
             mime_filter_t *b)		/* I - Second filter */
{
 /*
  * Because we're particularly lazy, we store the process ID in the "cost"
  * variable...
  */

  return (a->cost - b->cost);
}


/*
 * 'escape_options()' - Convert an options array to a string.
 */

static char *				/* O - Option string */
escape_options(
    int           num_options,		/* I - Number of options */
    cups_option_t *options)		/* I - Options */
{
  int		i;			/* Looping var */
  cups_option_t	*option;		/* Current option */
  size_t	bytes;			/* Number of bytes needed */
  char		*s,			/* Option string */
		*sptr,			/* Pointer into string */
		*vptr;			/* Pointer into value */


 /*
  * Figure out the worst-case number of bytes we need for the option string.
  */

  for (i = num_options, option = options, bytes = 1; i > 0; i --, option ++)
    bytes += 2 * (strlen(option->name) + strlen(option->value)) + 2;

  if ((s = malloc(bytes)) == NULL)
    return (NULL);

 /*
  * Copy the options to the string...
  */

  for (i = num_options, option = options, sptr = s; i > 0; i --, option ++)
  {
    if (!strcmp(option->name, "copies"))
      continue;

    if (sptr > s)
      *sptr++ = ' ';

    strlcpy(sptr, option->name, bytes - (size_t)(sptr - s));
    sptr += strlen(sptr);
    *sptr++ = '=';

    for (vptr = option->value; *vptr;)
    {
      if (strchr("\\ \t\n", *vptr))
        *sptr++ = '\\';

      *sptr++ = *vptr++;
    }
  }

  *sptr = '\0';

  return (s);
}


/*
 * 'exec_filter()' - Execute a single filter.
 */

static int				/* O - Process ID or -1 on error */
exec_filter(const char *filter,		/* I - Filter to execute */
            char       **argv,		/* I - Argument list */
	    char       **envp,		/* I - Environment list */
	    int        infd,		/* I - Stdin file descriptor */
	    int        outfd)		/* I - Stdout file descriptor */
{
  int		pid,			/* Process ID */
		fd;			/* Temporary file descriptor */
#if defined(__APPLE__)
  char		processPath[1024],	/* CFProcessPath environment variable */
		linkpath[1024];		/* Link path for symlinks... */
  int		linkbytes;		/* Bytes for link path */


 /*
  * Add special voodoo magic for macOS - this allows macOS
  * programs to access their bundle resources properly...
  */

  if ((linkbytes = readlink(filter, linkpath, sizeof(linkpath) - 1)) > 0)
  {
   /*
    * Yes, this is a symlink to the actual program, nul-terminate and
    * use it...
    */

    linkpath[linkbytes] = '\0';

    if (linkpath[0] == '/')
      snprintf(processPath, sizeof(processPath), "CFProcessPath=%s",
	       linkpath);
    else
      snprintf(processPath, sizeof(processPath), "CFProcessPath=%s/%s",
	       dirname((char *)filter), linkpath);
  }
  else
    snprintf(processPath, sizeof(processPath), "CFProcessPath=%s", filter);

  envp[0] = processPath;		/* Replace <CFProcessPath> string */
#endif	/* __APPLE__ */

  if ((pid = fork()) == 0)
  {
   /*
    * Child process goes here...
    *
    * Update stdin/stdout/stderr as needed...
    */

    if (infd != 0)
    {
      if (infd < 0)
        infd = open("/dev/null", O_RDONLY);

      if (infd > 0)
      {
        dup2(infd, 0);
	close(infd);
      }
    }

    if (outfd != 1)
    {
      if (outfd < 0)
        outfd = open("/dev/null", O_WRONLY);

      if (outfd > 1)
      {
	dup2(outfd, 1);
	close(outfd);
      }
    }

    if ((fd = open("/dev/null", O_RDWR)) > 3)
    {
      dup2(fd, 3);
      close(fd);
    }
    fcntl(3, F_SETFL, O_NDELAY);

    if ((fd = open("/dev/null", O_RDWR)) > 4)
    {
      dup2(fd, 4);
      close(fd);
    }
    fcntl(4, F_SETFL, O_NDELAY);

   /*
    * Execute command...
    */

    execve(filter, argv, envp);

    perror(filter);

    exit(errno);
  }

  return (pid);
}


/*
 * 'exec_filters()' - Execute filters for the given file and options.
 */

static int				/* O - 0 on success, 1 on error */
exec_filters(mime_type_t   *srctype,	/* I - Source type */
             cups_array_t  *filters,	/* I - Array of filters to run */
             const char    *infile,	/* I - File to filter */
	     const char    *outfile,	/* I - File to create */
	     const char    *ppdfile,	/* I - PPD file, if any */
	     const char    *printer,	/* I - Printer name */
	     const char    *user,	/* I - Username */
	     const char    *title,	/* I - Job title */
             int           num_options,	/* I - Number of filter options */
	     cups_option_t *options)	/* I - Filter options */
{
  int		i;			/* Looping var */
  const char	*argv[8],		/* Command-line arguments */
		*envp[17],		/* Environment variables */
		*temp;			/* Temporary string */
  char		*optstr,		/* Filter options */
		content_type[1024],	/* CONTENT_TYPE */
		cups_datadir[1024],	/* CUPS_DATADIR */
		cups_fontpath[1024],	/* CUPS_FONTPATH */
		cups_serverbin[1024],	/* CUPS_SERVERBIN */
		cups_serverroot[1024],	/* CUPS_SERVERROOT */
		final_content_type[1024] = "",
					/* FINAL_CONTENT_TYPE */
		lang[1024],		/* LANG */
		path[1024],		/* PATH */
		ppd[1024],		/* PPD */
		printer_info[255],	/* PRINTER_INFO env variable */
		printer_location[255],	/* PRINTER_LOCATION env variable */
		printer_name[255],	/* PRINTER env variable */
		rip_max_cache[1024],	/* RIP_MAX_CACHE */
		userenv[1024],		/* USER */
		program[1024];		/* Program to run */
  mime_filter_t	*filter,		/* Current filter */
		*next;			/* Next filter */
  int		current,		/* Current filter */
		filterfds[2][2],	/* Pipes for filters */
		pid,			/* Process ID of filter */
		status,			/* Exit status */
		retval;			/* Return value */
  cups_array_t	*pids;			/* Executed filters array */
  mime_filter_t	key;			/* Search key for filters */
  cups_lang_t	*language;		/* Current language */
  cups_dest_t	*dest;			/* Destination information */


 /*
  * Figure out the final content type...
  */

  for (filter = (mime_filter_t *)cupsArrayLast(filters);
       filter && filter->dst;
       filter = (mime_filter_t *)cupsArrayPrev(filters))
    if (strcmp(filter->dst->super, "printer"))
      break;

  if (filter && filter->dst)
  {
    const char *ptr;			/* Pointer in type name */

    if ((ptr = strchr(filter->dst->type, '/')) != NULL)
      snprintf(final_content_type, sizeof(final_content_type),
	       "FINAL_CONTENT_TYPE=%s", ptr + 1);
    else
      snprintf(final_content_type, sizeof(final_content_type),
	       "FINAL_CONTENT_TYPE=%s/%s", filter->dst->super,
	       filter->dst->type);
  }

 /*
  * Remove NULL ("-") filters...
  */

  for (filter = (mime_filter_t *)cupsArrayFirst(filters);
       filter;
       filter = (mime_filter_t *)cupsArrayNext(filters))
    if (!strcmp(filter->filter, "-"))
      cupsArrayRemove(filters, filter);

 /*
  * Setup the filter environment and command-line...
  */

  optstr = escape_options(num_options, options);

  snprintf(content_type, sizeof(content_type), "CONTENT_TYPE=%s/%s",
           srctype->super, srctype->type);
  snprintf(cups_datadir, sizeof(cups_datadir), "CUPS_DATADIR=%s", DataDir);
  snprintf(cups_fontpath, sizeof(cups_fontpath), "CUPS_FONTPATH=%s", FontPath);
  snprintf(cups_serverbin, sizeof(cups_serverbin), "CUPS_SERVERBIN=%s",
           ServerBin);
  snprintf(cups_serverroot, sizeof(cups_serverroot), "CUPS_SERVERROOT=%s",
           ServerRoot);
  language = cupsLangDefault();
  snprintf(lang, sizeof(lang), "LANG=%s.UTF8", language->language);
  snprintf(path, sizeof(path), "PATH=%s", Path);
  if (ppdfile)
    snprintf(ppd, sizeof(ppd), "PPD=%s", ppdfile);
  else if ((temp = getenv("PPD")) != NULL)
    snprintf(ppd, sizeof(ppd), "PPD=%s", temp);
  else
#ifdef __APPLE__
  if (!access("/System/Library/Frameworks/ApplicationServices.framework/"
	      "Versions/A/Frameworks/PrintCore.framework/Versions/A/"
	      "Resources/English.lproj/Generic.ppd", 0))
    strlcpy(ppd, "PPD=/System/Library/Frameworks/ApplicationServices.framework/"
                 "Versions/A/Frameworks/PrintCore.framework/Versions/A/"
		 "Resources/English.lproj/Generic.ppd", sizeof(ppd));
  else
    strlcpy(ppd, "PPD=/System/Library/Frameworks/ApplicationServices.framework/"
                 "Versions/A/Frameworks/PrintCore.framework/Versions/A/"
		 "Resources/Generic.ppd", sizeof(ppd));
#else
    snprintf(ppd, sizeof(ppd), "PPD=%s/model/laserjet.ppd", DataDir);
#endif /* __APPLE__ */
  snprintf(rip_max_cache, sizeof(rip_max_cache), "RIP_MAX_CACHE=%s", RIPCache);
  snprintf(userenv, sizeof(userenv), "USER=%s", user);

  if (printer &&
      (dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, printer, NULL)) != NULL)
  {
    if ((temp = cupsGetOption("printer-info", dest->num_options,
                              dest->options)) != NULL)
      snprintf(printer_info, sizeof(printer_info), "PRINTER_INFO=%s", temp);
    else
      snprintf(printer_info, sizeof(printer_info), "PRINTER_INFO=%s", printer);

    if ((temp = cupsGetOption("printer-location", dest->num_options,
                              dest->options)) != NULL)
      snprintf(printer_location, sizeof(printer_location),
               "PRINTER_LOCATION=%s", temp);
    else
      strlcpy(printer_location, "PRINTER_LOCATION=Unknown",
              sizeof(printer_location));
  }
  else
  {
    snprintf(printer_info, sizeof(printer_info), "PRINTER_INFO=%s",
             printer ? printer : "Unknown");
    strlcpy(printer_location, "PRINTER_LOCATION=Unknown",
            sizeof(printer_location));
  }

  snprintf(printer_name, sizeof(printer_name), "PRINTER=%s",
	   printer ? printer : "Unknown");

  argv[0] = (char *)printer;
  argv[1] = "1";
  argv[2] = user;
  argv[3] = title;
  argv[4] = cupsGetOption("copies", num_options, options);
  argv[5] = optstr;
  argv[6] = infile;
  argv[7] = NULL;

  if (!argv[4])
    argv[4] = "1";

  envp[0]  = "<CFProcessPath>";
  envp[1]  = content_type;
  envp[2]  = cups_datadir;
  envp[3]  = cups_fontpath;
  envp[4]  = cups_serverbin;
  envp[5]  = cups_serverroot;
  envp[6]  = lang;
  envp[7]  = path;
  envp[8]  = ppd;
  envp[9]  = printer_info;
  envp[10] = printer_location;
  envp[11] = printer_name;
  envp[12] = rip_max_cache;
  envp[13] = userenv;
  envp[14] = "CHARSET=utf-8";
  if (final_content_type[0])
  {
    envp[15] = final_content_type;
    envp[16] = NULL;
  }
  else
    envp[15] = NULL;

  for (i = 0; argv[i]; i ++)
    fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]);

  for (i = 0; envp[i]; i ++)
    fprintf(stderr, "DEBUG: envp[%d]=\"%s\"\n", i, envp[i]);

 /*
  * Execute all of the filters...
  */

  pids            = cupsArrayNew((cups_array_func_t)compare_pids, NULL);
  current         = 0;
  filterfds[0][0] = -1;
  filterfds[0][1] = -1;
  filterfds[1][0] = -1;
  filterfds[1][1] = -1;

  if (!infile)
    filterfds[0][0] = 0;

  for (filter = (mime_filter_t *)cupsArrayFirst(filters);
       filter;
       filter = next, current = 1 - current)
  {
    next = (mime_filter_t *)cupsArrayNext(filters);

    if (filter->filter[0] == '/')
      strlcpy(program, filter->filter, sizeof(program));
    else
      snprintf(program, sizeof(program), "%s/filter/%s", ServerBin,
	       filter->filter);

    if (filterfds[!current][1] > 1)
    {
      close(filterfds[1 - current][0]);
      close(filterfds[1 - current][1]);

      filterfds[1 - current][0] = -1;
      filterfds[1 - current][0] = -1;
    }

    if (next)
      open_pipe(filterfds[1 - current]);
    else if (outfile)
    {
      filterfds[1 - current][1] = open(outfile, O_CREAT | O_TRUNC | O_WRONLY,
                                       0666);

      if (filterfds[1 - current][1] < 0)
        fprintf(stderr, "ERROR: Unable to create \"%s\" - %s\n", outfile,
	        strerror(errno));
    }
    else
      filterfds[1 - current][1] = 1;

    pid = exec_filter(program, (char **)argv, (char **)envp,
                      filterfds[current][0], filterfds[1 - current][1]);

    if (pid > 0)
    {
      fprintf(stderr, "INFO: %s (PID %d) started.\n", filter->filter, pid);

      filter->cost = pid;
      cupsArrayAdd(pids, filter);
    }
    else
      break;

    argv[6] = NULL;
  }

 /*
  * Close remaining pipes...
  */

  if (filterfds[0][1] > 1)
  {
    close(filterfds[0][0]);
    close(filterfds[0][1]);
  }

  if (filterfds[1][1] > 1)
  {
    close(filterfds[1][0]);
    close(filterfds[1][1]);
  }

 /*
  * Wait for the children to exit...
  */

  retval = 0;

  while (cupsArrayCount(pids) > 0)
  {
    if ((pid = wait(&status)) < 0)
      continue;

    key.cost = pid;
    if ((filter = (mime_filter_t *)cupsArrayFind(pids, &key)) != NULL)
    {
      cupsArrayRemove(pids, filter);

      if (status)
      {
	if (WIFEXITED(status))
	  fprintf(stderr, "ERROR: %s (PID %d) stopped with status %d\n",
		  filter->filter, pid, WEXITSTATUS(status));
	else
	  fprintf(stderr, "ERROR: %s (PID %d) crashed on signal %d\n",
		  filter->filter, pid, WTERMSIG(status));

        retval = 1;
      }
      else
        fprintf(stderr, "INFO: %s (PID %d) exited with no errors.\n",
	        filter->filter, pid);
    }
  }

  cupsArrayDelete(pids);

  return (retval);
}


/*
 * 'get_job_file()' - Get the specified job file.
 */

static void
get_job_file(const char *job)		/* I - Job ID */
{
  long		jobid,			/* Job ID */
		docnum;			/* Document number */
  const char	*jobptr;		/* Pointer into job ID string */
  char		uri[1024];		/* job-uri */
  http_t	*http;			/* Connection to server */
  ipp_t		*request;		/* Request data */
  int		tempfd;			/* Temporary file */


 /*
  * Get the job ID and document number, if any...
  */

  if ((jobptr = strrchr(job, '-')) != NULL)
    jobptr ++;
  else
    jobptr = job;

  jobid = strtol(jobptr, (char **)&jobptr, 10);

  if (*jobptr == ',')
    docnum = strtol(jobptr + 1, NULL, 10);
  else
    docnum = 1;

  if (jobid < 1 || jobid > INT_MAX)
  {
    _cupsLangPrintf(stderr, _("cupsfilter: Invalid job ID %d."), (int)jobid);
    exit(1);
  }

  if (docnum < 1 || docnum > INT_MAX)
  {
    _cupsLangPrintf(stderr, _("cupsfilter: Invalid document number %d."),
                    (int)docnum);
    exit(1);
  }

 /*
  * Ask the server for the document file...
  */

  if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
                                 cupsEncryption())) == NULL)
  {
    _cupsLangPrintf(stderr, _("%s: Unable to connect to server."),
                    "cupsfilter");
    exit(1);
  }

  request = ippNewRequest(CUPS_GET_DOCUMENT);

  snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", (int)jobid);

  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
  ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "document-number",
                (int)docnum);

  if ((tempfd = cupsTempFd(TempFile, sizeof(TempFile))) == -1)
  {
    _cupsLangPrintError("ERROR", _("Unable to create temporary file"));
    httpClose(http);
    exit(1);
  }

  signal(SIGTERM, sighandler);

  ippDelete(cupsDoIORequest(http, request, "/", -1, tempfd));

  close(tempfd);

  httpClose(http);

  if (cupsLastError() != IPP_OK)
  {
    _cupsLangPrintf(stderr, _("cupsfilter: Unable to get job file - %s"),
                    cupsLastErrorString());
    unlink(TempFile);
    exit(1);
  }
}


/*
 * 'open_pipe()' - Create a pipe which is closed on exec.
 */

static int				/* O - 0 on success, -1 on error */
open_pipe(int *fds)			/* O - Pipe file descriptors (2) */
{
 /*
  * Create the pipe...
  */

  if (pipe(fds))
  {
    fds[0] = -1;
    fds[1] = -1;

    return (-1);
  }

 /*
  * Set the "close on exec" flag on each end of the pipe...
  */

  if (fcntl(fds[0], F_SETFD, fcntl(fds[0], F_GETFD) | FD_CLOEXEC))
  {
    close(fds[0]);
    close(fds[1]);

    fds[0] = -1;
    fds[1] = -1;

    return (-1);
  }

  if (fcntl(fds[1], F_SETFD, fcntl(fds[1], F_GETFD) | FD_CLOEXEC))
  {
    close(fds[0]);
    close(fds[1]);

    fds[0] = -1;
    fds[1] = -1;

    return (-1);
  }

 /*
  * Return 0 indicating success...
  */

  return (0);
}


/*
 * 'read_cups_files_conf()' - Read the cups-files.conf file to get the filter settings.
 */

static int				/* O - 0 on success, 1 on error */
read_cups_files_conf(
    const char *filename)		/* I - File to read */
{
  cups_file_t	*fp;			/* cups-files.conf file */
  const char	*temp;			/* Temporary string */
  char		line[1024],		/* Line from file */
		*ptr;			/* Pointer into line */
  int		linenum;		/* Current line number */


  if ((temp = getenv("CUPS_DATADIR")) != NULL)
    set_string(&DataDir, temp);
  else
    set_string(&DataDir, CUPS_DATADIR);

  if ((temp = getenv("CUPS_FONTPATH")) != NULL)
    set_string(&FontPath, temp);
  else
    set_string(&FontPath, CUPS_FONTPATH);

  set_string(&RIPCache, "128m");

  if ((temp = getenv("CUPS_SERVERBIN")) != NULL)
    set_string(&ServerBin, temp);
  else
    set_string(&ServerBin, CUPS_SERVERBIN);

  strlcpy(line, filename, sizeof(line));
  if ((ptr = strrchr(line, '/')) != NULL)
    *ptr = '\0';
  else
    getcwd(line, sizeof(line));

  set_string(&ServerRoot, line);

  if ((fp = cupsFileOpen(filename, "r")) != NULL)
  {
    linenum = 0;

    while (cupsFileGetConf(fp, line, sizeof(line), &ptr, &linenum))
    {
      if (!_cups_strcasecmp(line, "DataDir"))
        set_string(&DataDir, ptr);
      else if (!_cups_strcasecmp(line, "FontPath"))
        set_string(&FontPath, ptr);
      else if (!_cups_strcasecmp(line, "RIPCache"))
        set_string(&RIPCache, ptr);
      else if (!_cups_strcasecmp(line, "ServerBin"))
        set_string(&ServerBin, ptr);
      else if (!_cups_strcasecmp(line, "ServerRoot"))
        set_string(&ServerRoot, ptr);
    }

    cupsFileClose(fp);
  }

  snprintf(line, sizeof(line), "%s/filter:" CUPS_BINDIR ":" CUPS_SBINDIR ":/bin:/usr/bin", ServerBin);
  set_string(&Path, line);

  return (0);
}


/*
 * 'set_string()' - Copy and set a string.
 */

static void
set_string(char       **s,		/* O - Copy of string */
           const char *val)		/* I - String to copy */
{
  if (*s)
    free(*s);

  *s = strdup(val);
}


/*
 * 'sighandler()' - Signal catcher for when we print from stdin...
 */

static void
sighandler(int s)			/* I - Signal number */
{
 /*
  * Remove the temporary file we're using to print a job file...
  */

  if (TempFile[0])
    unlink(TempFile);

 /*
  * Exit...
  */

  exit(s);
}


/*
 * 'usage()' - Show program usage...
 */

static void
usage(const char *opt)			/* I - Incorrect option, if any */
{
  if (opt)
    _cupsLangPrintf(stderr, _("%s: Unknown option \"%c\"."), "cupsfilter", *opt);

  _cupsLangPuts(stdout, _("Usage: cupsfilter [ options ] [ -- ] filename"));
  _cupsLangPuts(stdout, _("Options:"));
  _cupsLangPuts(stdout, _("  --list-filters          List filters that will be used."));
  _cupsLangPuts(stdout, _("  -D                      Remove the input file when finished."));
  _cupsLangPuts(stdout, _("  -P filename.ppd         Set PPD file."));
  _cupsLangPuts(stdout, _("  -U username             Specify username."));
  _cupsLangPuts(stdout, _("  -c cups-files.conf      Set cups-files.conf file to use."));
  _cupsLangPuts(stdout, _("  -d printer              Use the named printer."));
  _cupsLangPuts(stdout, _("  -e                      Use every filter from the PPD file."));
  _cupsLangPuts(stdout, _("  -i mime/type            Set input MIME type (otherwise auto-typed)."));
  _cupsLangPuts(stdout, _("  -j job-id[,N]           Filter file N from the specified job (default is file 1)."));
  _cupsLangPuts(stdout, _("  -m mime/type            Set output MIME type (otherwise application/pdf)."));
  _cupsLangPuts(stdout, _("  -n copies               Set number of copies."));
  _cupsLangPuts(stdout, _("  -o name=value           Set option(s)."));
  _cupsLangPuts(stdout, _("  -p filename.ppd         Set PPD file."));
  _cupsLangPuts(stdout, _("  -t title                Set title."));
  _cupsLangPuts(stdout, _("  -u                      Remove the PPD file when finished."));

  exit(1);
}
