Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cups-deviced and cups-driverd should set CFProcessPath #2837

Closed
michaelrsweet opened this issue May 28, 2008 · 5 comments
Closed

cups-deviced and cups-driverd should set CFProcessPath #2837

michaelrsweet opened this issue May 28, 2008 · 5 comments
Milestone

Comments

@michaelrsweet
Copy link
Collaborator

Version: 1.3.6
CUPS.org User: dsharov

Apple Mac OS X system specific.

While launching driver programs, cups-driverd does not update CFProcessPath environment variable accordingly to point to the actual executable of a driver program.
This make it impossible to use CFBundle API for accessing bundle resources from inside of the driver program in case driver program packaged as a bundle and symbolic link to the bundle's executable is placed at /usr/libexec/cups/driver.

This issue should also affect cups-1.4 currently being developed.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Reassigning priority...

This will take a little work...

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

We also need to do this in cups-deviced...

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Fixed in Subversion repository.

@michaelrsweet
Copy link
Collaborator Author

"str2837-1.4.patch":

Index: scheduler/util.c

--- scheduler/util.c (revision 7617)
+++ scheduler/util.c (working copy)
@@ -3,7 +3,7 @@
*

  • Mini-daemon utility functions for the Common UNIX Printing System (CUPS).
  • * Copyright 2007 by Apple Inc.
  • * Copyright 2007-2008 by Apple Inc.
  • Copyright 1997-2005 by Easy Software Products.
  • These coded instructions, statements, and computer programs are the
    @@ -15,6 +15,8 @@
  • Contents:
    *
  • cupsdCompareNames() - Compare two names.
  • * cupsdExec() - Run a program with the correct environment.
  • * cupsdPipeCommand() - Read output from a command.
  • cupsdSendIPPGroup() - Send a group tag.
  • cupsdSendIPPHeader() - Send the IPP response header.
  • cupsdSendIPPInteger() - Send an integer attribute.
    @@ -27,6 +29,13 @@
    */

#include "util.h"
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef APPLE
+# include <libgen.h>
+extern char *environ;
+#endif /
APPLE */

/*
@@ -144,6 +153,174 @@

/*

  • * 'cupsdExec()' - Run a program with the correct environment.
  • * On Mac OS X, we need to update the CFProcessPath environment variable that
  • * is passed in the environment so the child can access its bundled resources.
  • /
    +
    +int /
    O - exec() status /
    +cupsdExec(const char *command, /
    I - Full path to program */
  •      char       *_argv)       /_ I - Command-line arguments */
    
    +{
    +#ifdef APPLE
  • int i, j; /* Looping vars */
  • char envp[500], / Array of environment variables */
  • cfprocesspath[1024], /* CFProcessPath environment variable */
  • linkpath[1024]; /* Link path for symlinks... */
  • int linkbytes; /* Bytes for link path */
    +
    +
  • /*
  • * Some Mac OS X programs are bundled and need the CFProcessPath environment
  • * variable defined. If the command is a symlink, resolve the link and point
  • * to the resolved location, otherwise, use the command path itself.
  • */
    +
  • if ((linkbytes = readlink(command, 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(cfprocesspath, sizeof(cfprocesspath), "CFProcessPath=%s",
    
  •      linkpath);
    
  • else
  •  snprintf(cfprocesspath, sizeof(cfprocesspath), "CFProcessPath=%s/%s",
    
  •      dirname((char *)command), linkpath);
    
  • }
  • else
  • snprintf(cfprocesspath, sizeof(cfprocesspath), "CFProcessPath=%s", command);
    +
  • envp[0] = cfprocesspath;
    +
  • /*
  • * Copy the rest of the environment except for any CFProcessPath that may
  • * already be there...
  • */
    +
  • for (i = 1, j = 0;
  •   environ[j] && i < (int)(sizeof(envp) / sizeof(envp[0]) - 1);
    
  •   j ++)
    
  • if (strncmp(environ[j], "CFProcessPath=", 14))
  •  envp[i ++] = environ[j];
    
  • envp[i] = NULL;
    +
  • /*
  • * Use execve() to run the program...
  • */
    +
  • return (execve(command, argv, envp));
    +
    +#else
  • /*
  • * On other operating systems, just call execv() to use the same environment
  • * variables as the parent...
  • */
    +
  • return (execv(command, argv));
    +#endif /* APPLE /
    +}
    +
    +
    +/
  • * 'cupsdPipeCommand()' - Read output from a command.
  • /
    +
    +cups_file_t * /
    O - CUPS file or NULL on error /
    +cupsdPipeCommand(int *pid, /
    O - Process ID or 0 on error */
  •             const char _command,  /_ I - Command to run */
    
  •             char       *_argv,    /_ I - Arguments to pass to command */
    
  •    int        user)   /\* I - User to run as or 0 for current */
    
    +{
  • int fds[2]; /* Pipe file descriptors */
    +
    +
  • /*
  • * First create the pipe...
  • */
    +
  • if (pipe(fds))
  • {
  • *pid = 0;
  • return (NULL);
  • }
    +
  • /*
  • * 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]);
    +
  • *pid = 0;
    +
  • return (NULL);
  • }
    +
  • if (fcntl(fds[1], F_SETFD, fcntl(fds[1], F_GETFD) | FD_CLOEXEC))
  • {
  • close(fds[0]);
  • close(fds[1]);
    +
  • *pid = 0;
    +
  • return (NULL);
  • }
    +
  • /*
  • * Then run the command...
  • */
    +
  • if ((*pid = fork()) < 0)
  • {
  • /*
  • * Unable to fork!
  • */
    +
  • *pid = 0;
  • close(fds[0]);
  • close(fds[1]);
    +
  • return (NULL);
  • }
  • else if (!*pid)
  • {
  • /*
  • * Child comes here...
  • */
    +
  • if (!getuid() && user)
  •  setuid(user);            /\* Run as restricted user */
    
  • close(0); /* </dev/null */
  • open("/dev/null", O_RDONLY);
    +
  • close(1); /* >pipe */
  • dup(fds[1]);
    +
  • cupsdExec(command, argv);
  • exit(errno);
  • }
    +
  • /*
  • * Parent comes here, open the input side of the pipe...
  • */
    +
  • close(fds[1]);
    +
  • return (cupsFileOpenFd(fds[0], "r"));
    +}
    +
    +
    +/*
  • 'cupsdSendIPPGroup()' - Send a group tag.
    */

Index: scheduler/util.h

--- scheduler/util.h (revision 7617)
+++ scheduler/util.h (working copy)
@@ -3,7 +3,7 @@
*

  • Mini-daemon utility definitions for the Common UNIX Printing System (CUPS).
  • * Copyright 2007 by Apple Inc.
  • * Copyright 2007-2008 by Apple Inc.
  • Copyright 1997-2005 by Easy Software Products.
  • These coded instructions, statements, and computer programs are the
    @@ -33,14 +33,18 @@
  • Prototypes...
    */

-extern int cupsdCompareNames(const char *s, const char *t);
-extern void cupsdSendIPPGroup(ipp_tag_t group_tag);
-extern void cupsdSendIPPHeader(ipp_status_t status_code, int request_id);
-extern void cupsdSendIPPInteger(ipp_tag_t value_tag, const char *name,

  •                       int value);
    

    -extern void cupsdSendIPPString(ipp_tag_t value_tag, const char *name,

  •                      const char _value);
    

    -extern void cupsdSendIPPTrailer(void);
    +extern int cupsdCompareNames(const char *s, const char *t);
    +extern int cupsdExec(const char *command, char *_argv);
    +extern cups_file_t *cupsdPipeCommand(int *pid, const char *command,

  •                         char **argv, int user);
    

    +extern void cupsdSendIPPGroup(ipp_tag_t group_tag);
    +extern void cupsdSendIPPHeader(ipp_status_t status_code,

  •                          int request_id);
    

    +extern void cupsdSendIPPInteger(ipp_tag_t value_tag,

  •                           const char *name, int value);
    

    +extern void cupsdSendIPPString(ipp_tag_t value_tag,

  •                          const char *name, const char *value);
    

    +extern void cupsdSendIPPTrailer(void);

    #endif /* !CUPSD_UTIL_H */

    Index: scheduler/cups-driverd.c

    --- scheduler/cups-driverd.c (revision 7617)
    +++ scheduler/cups-driverd.c (working copy)
    @@ -294,6 +294,7 @@
    */

    const char serverbin; / CUPS_SERVERBIN env var */

  • char argv[4]; / Arguments for program */

if ((serverbin = getenv("CUPS_SERVERBIN")) == NULL)
@@ -340,7 +341,12 @@
cupsdSendIPPTrailer();
}

  • if (execl(line, scheme, "cat", name, (char *)NULL))
  • argv[0] = scheme;
  • argv[1] = (char *)"cat";
  • argv[2] = (char *)name;
  • argv[3] = NULL;
  • if (cupsdExec(line, argv))
    {
    /*

  • Unable to execute driver...
    @@ -1535,10 +1541,12 @@
    ptr; / Pointer into string /
    const char *server_bin; /
    CUPS_SERVERBIN env variable /
    char drivers[1024]; /
    Location of driver programs */

  • FILE fp; / Pipe to driver program */

  • int pid; /* Process ID for driver program */

  • cups_file_t fp; / Pipe to driver program /
    cups_dir_t *dir; /
    Directory pointer /
    cups_dentry_t *dent; /
    Directory entry */

  • char filename[1024], /* Name of driver */

  • char argv[3], / Arguments for command */

  •   filename[1024],     /* Name of driver */
    line[2048],     /* Line from driver */
    name[512],      /* ppd-name */
    make[128],      /* ppd-make */
    

    @@ -1573,6 +1581,9 @@

    • Loop through all of the device drivers...
      */
  • argv[1] = (char *)"list";

  • argv[2] = NULL;

while ((dent = cupsDirRead(dir)) != NULL)
{
/*
@@ -1586,10 +1597,12 @@

  • Run the driver with no arguments and collect the output...
    */
  • snprintf(filename, sizeof(filename), "%s/%s list", drivers, dent->filename);
  • if ((fp = popen(filename, "r")) != NULL)
  • argv[0] = dent->filename;
  • snprintf(filename, sizeof(filename), "%s/%s", drivers, dent->filename);
  • if ((fp = cupsdPipeCommand(&pid, filename, argv, 0)) != NULL)
    {

  •  while (fgets(line, sizeof(line), fp) != NULL)
    
  •  while (cupsFileGets(fp, line, sizeof(line)))
    

    {
    /*
    * Each line is of the form:
    @@ -1638,7 +1651,8 @@

    if (type >= (int)(sizeof(ppd_types) / sizeof(ppd_types[0])))
    {

  •   fprintf(stderr, "ERROR: [cups-driverd] Bad ppd-type \"%s\" ignored!\n",
    
  •   fprintf(stderr,
    
  •           "ERROR: [cups-driverd] Bad ppd-type \"%s\" ignored!\n",
            type_str);
    type = PPD_TYPE_UNKNOWN;
    

    }
    @@ -1649,7 +1663,7 @@
    if (!ppd)
    {
    cupsDirClose(dir);

  •   pclose(fp);
    
  •   cupsFileClose(fp);
    return (0);
    

    }

@@ -1674,7 +1688,7 @@
}
}

  •  pclose(fp);
    
  •  cupsFileClose(fp);
    

    }
    else
    fprintf(stderr, "WARNING: [cups-driverd] Unable to execute "%s": %s\n",
    Index: scheduler/cups-deviced.c

    --- scheduler/cups-deviced.c (revision 7617)
    +++ scheduler/cups-deviced.c (working copy)
    @@ -671,6 +671,7 @@
    char program[1024]; /* Full path to backend /
    int fds[2]; /
    Pipe file descriptors /
    cupsd_backend_t *backend; /
    Current backend */
  • char argv[2]; / Command-line arguments */

if (num_backends >= MAX_BACKENDS)
@@ -679,13 +680,6 @@
return (-1);
}

  • if (pipe(fds))
  • {
  • fprintf(stderr, "ERROR: Unable to create a pipe for "%s" - %s\n",
  •        name, strerror(errno));
    
  • return (-1);

- }

if ((server_bin = getenv("CUPS_SERVERBIN")) == NULL)
server_bin = CUPS_SERVERBIN;

@@ -693,58 +687,29 @@

backend = backends + num_backends;

  • if ((backend->pid = fork()) < 0)
  • {
  • /*
  • * Error!
  • */
  • argv[0] = (char *)name;
  • argv[1] = NULL;
  • fprintf(stderr, "ERROR: [cups-deviced] Unable to fork for "%s" - %s\n",
  •        program, strerror(errno));
    
  • close(fds[0]);
  • close(fds[1]);
  • return (-1);
  • }
  • else if (!backend->pid)
  • if ((backend->pipe = cupsdPipeCommand(&(backend->pid), program, argv,
  •                                    root ? 0 : normal_user)) == NULL)
    
    {
  • /*
  • * Child comes here...

- */

  • if (!getuid() && !root)

- setuid(normal_user); /* Run as restricted user */

  • close(0); /* </dev/null */

- open("/dev/null", O_RDONLY);

  • close(1); /* >pipe */

- dup(fds[1]);

  • close(fds[0]); /* Close copies of pipes */

- close(fds[1]);

  • execl(program, name, (char )0); / Run it! */
    fprintf(stderr, "ERROR: [cups-deviced] Unable to execute "%s" - %s\n",
    program, strerror(errno));
  • exit(1);
  • return (-1);
    }

/*

  • * Parent comes here, allocate a backend and open the input side of the

  • * pipe...

    • Fill in the rest of the backend information...
      */

    fprintf(stderr, "DEBUG: [cups-deviced] Started backend %s (PID %d)\n",
    program, backend->pid);

- close(fds[1]);

  • backend_fds[num_backends].fd = fds[0];
  • backend_fds[num_backends].fd = cupsFileNumber(backend->pipe);
    backend_fds[num_backends].events = POLLIN;

backend->name = strdup(name);
backend->status = 0;

  • backend->pipe = cupsFileOpenFd(fds[0], "r");
    backend->count = 0;

active_backends ++;

@michaelrsweet
Copy link
Collaborator Author

"str2837-1.3.patch":

Index: scheduler/util.c

--- scheduler/util.c (revision 7617)
+++ scheduler/util.c (working copy)
@@ -3,7 +3,7 @@
*

  • Mini-daemon utility functions for the Common UNIX Printing System (CUPS).
  • * Copyright 2007 by Apple Inc.
  • * Copyright 2007-2008 by Apple Inc.
  • Copyright 1997-2005 by Easy Software Products.
  • These coded instructions, statements, and computer programs are the
    @@ -15,6 +15,8 @@
  • Contents:
    *
  • cupsdCompareNames() - Compare two names.
  • * cupsdExec() - Run a program with the correct environment.
  • * cupsdPipeCommand() - Read output from a command.
  • cupsdSendIPPGroup() - Send a group tag.
  • cupsdSendIPPHeader() - Send the IPP response header.
  • cupsdSendIPPInteger() - Send an integer attribute.
    @@ -27,6 +29,13 @@
    */

#include "util.h"
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef APPLE
+# include <libgen.h>
+extern char *environ;
+#endif /
APPLE */

/*
@@ -144,6 +153,174 @@

/*

  • * 'cupsdExec()' - Run a program with the correct environment.
  • * On Mac OS X, we need to update the CFProcessPath environment variable that
  • * is passed in the environment so the child can access its bundled resources.
  • /
    +
    +int /
    O - exec() status /
    +cupsdExec(const char *command, /
    I - Full path to program */
  •      char       *_argv)       /_ I - Command-line arguments */
    
    +{
    +#ifdef APPLE
  • int i, j; /* Looping vars */
  • char envp[500], / Array of environment variables */
  • cfprocesspath[1024], /* CFProcessPath environment variable */
  • linkpath[1024]; /* Link path for symlinks... */
  • int linkbytes; /* Bytes for link path */
    +
    +
  • /*
  • * Some Mac OS X programs are bundled and need the CFProcessPath environment
  • * variable defined. If the command is a symlink, resolve the link and point
  • * to the resolved location, otherwise, use the command path itself.
  • */
    +
  • if ((linkbytes = readlink(command, 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(cfprocesspath, sizeof(cfprocesspath), "CFProcessPath=%s",
    
  •      linkpath);
    
  • else
  •  snprintf(cfprocesspath, sizeof(cfprocesspath), "CFProcessPath=%s/%s",
    
  •      dirname((char *)command), linkpath);
    
  • }
  • else
  • snprintf(cfprocesspath, sizeof(cfprocesspath), "CFProcessPath=%s", command);
    +
  • envp[0] = cfprocesspath;
    +
  • /*
  • * Copy the rest of the environment except for any CFProcessPath that may
  • * already be there...
  • */
    +
  • for (i = 1, j = 0;
  •   environ[j] && i < (int)(sizeof(envp) / sizeof(envp[0]) - 1);
    
  •   j ++)
    
  • if (strncmp(environ[j], "CFProcessPath=", 14))
  •  envp[i ++] = environ[j];
    
  • envp[i] = NULL;
    +
  • /*
  • * Use execve() to run the program...
  • */
    +
  • return (execve(command, argv, envp));
    +
    +#else
  • /*
  • * On other operating systems, just call execv() to use the same environment
  • * variables as the parent...
  • */
    +
  • return (execv(command, argv));
    +#endif /* APPLE /
    +}
    +
    +
    +/
  • * 'cupsdPipeCommand()' - Read output from a command.
  • /
    +
    +cups_file_t * /
    O - CUPS file or NULL on error /
    +cupsdPipeCommand(int *pid, /
    O - Process ID or 0 on error */
  •             const char _command,  /_ I - Command to run */
    
  •             char       *_argv,    /_ I - Arguments to pass to command */
    
  •    int        user)   /\* I - User to run as or 0 for current */
    
    +{
  • int fds[2]; /* Pipe file descriptors */
    +
    +
  • /*
  • * First create the pipe...
  • */
    +
  • if (pipe(fds))
  • {
  • *pid = 0;
  • return (NULL);
  • }
    +
  • /*
  • * 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]);
    +
  • *pid = 0;
    +
  • return (NULL);
  • }
    +
  • if (fcntl(fds[1], F_SETFD, fcntl(fds[1], F_GETFD) | FD_CLOEXEC))
  • {
  • close(fds[0]);
  • close(fds[1]);
    +
  • *pid = 0;
    +
  • return (NULL);
  • }
    +
  • /*
  • * Then run the command...
  • */
    +
  • if ((*pid = fork()) < 0)
  • {
  • /*
  • * Unable to fork!
  • */
    +
  • *pid = 0;
  • close(fds[0]);
  • close(fds[1]);
    +
  • return (NULL);
  • }
  • else if (!*pid)
  • {
  • /*
  • * Child comes here...
  • */
    +
  • if (!getuid() && user)
  •  setuid(user);            /\* Run as restricted user */
    
  • close(0); /* </dev/null */
  • open("/dev/null", O_RDONLY);
    +
  • close(1); /* >pipe */
  • dup(fds[1]);
    +
  • cupsdExec(command, argv);
  • exit(errno);
  • }
    +
  • /*
  • * Parent comes here, open the input side of the pipe...
  • */
    +
  • close(fds[1]);
    +
  • return (cupsFileOpenFd(fds[0], "r"));
    +}
    +
    +
    +/*
  • 'cupsdSendIPPGroup()' - Send a group tag.
    */

Index: scheduler/util.h

--- scheduler/util.h (revision 7617)
+++ scheduler/util.h (working copy)
@@ -3,7 +3,7 @@
*

  • Mini-daemon utility definitions for the Common UNIX Printing System (CUPS).
  • * Copyright 2007 by Apple Inc.
  • * Copyright 2007-2008 by Apple Inc.
  • Copyright 1997-2005 by Easy Software Products.
  • These coded instructions, statements, and computer programs are the
    @@ -33,14 +33,18 @@
  • Prototypes...
    */

-extern int cupsdCompareNames(const char *s, const char *t);
-extern void cupsdSendIPPGroup(ipp_tag_t group_tag);
-extern void cupsdSendIPPHeader(ipp_status_t status_code, int request_id);
-extern void cupsdSendIPPInteger(ipp_tag_t value_tag, const char *name,

  •                       int value);
    

    -extern void cupsdSendIPPString(ipp_tag_t value_tag, const char *name,

  •                      const char _value);
    

    -extern void cupsdSendIPPTrailer(void);
    +extern int cupsdCompareNames(const char *s, const char *t);
    +extern int cupsdExec(const char *command, char *_argv);
    +extern cups_file_t *cupsdPipeCommand(int *pid, const char *command,

  •                         char **argv, int user);
    

    +extern void cupsdSendIPPGroup(ipp_tag_t group_tag);
    +extern void cupsdSendIPPHeader(ipp_status_t status_code,

  •                          int request_id);
    

    +extern void cupsdSendIPPInteger(ipp_tag_t value_tag,

  •                           const char *name, int value);
    

    +extern void cupsdSendIPPString(ipp_tag_t value_tag,

  •                          const char *name, const char *value);
    

    +extern void cupsdSendIPPTrailer(void);

    #endif /* !CUPSD_UTIL_H */

    Index: scheduler/cups-driverd.c

    --- scheduler/cups-driverd.c (revision 7617)
    +++ scheduler/cups-driverd.c (working copy)
    @@ -300,6 +300,7 @@
    */

    const char serverbin; / CUPS_SERVERBIN env var */

  • char argv[4]; / Arguments for program */

if ((serverbin = getenv("CUPS_SERVERBIN")) == NULL)
@@ -346,7 +347,12 @@
cupsdSendIPPTrailer();
}

  • if (execl(line, scheme, "cat", name, (char *)NULL))
  • argv[0] = scheme;
  • argv[1] = (char *)"cat";
  • argv[2] = (char *)name;
  • argv[3] = NULL;
  • if (cupsdExec(line, argv))
    {
    /*

  • Unable to execute driver...
    @@ -1552,10 +1558,12 @@
    ptr; / Pointer into string /
    const char *server_bin; /
    CUPS_SERVERBIN env variable /
    char drivers[1024]; /
    Location of driver programs */

  • FILE fp; / Pipe to driver program */

  • int pid; /* Process ID for driver program */

  • cups_file_t fp; / Pipe to driver program /
    cups_dir_t *dir; /
    Directory pointer /
    cups_dentry_t *dent; /
    Directory entry */

  • char filename[1024], /* Name of driver */

  • char argv[3], / Arguments for command */

  •   filename[1024],     /* Name of driver */
    line[2048],     /* Line from driver */
    name[512],      /* ppd-name */
    make[128],      /* ppd-make */
    

    @@ -1590,6 +1598,9 @@

    • Loop through all of the device drivers...
      */
  • argv[1] = (char *)"list";

  • argv[2] = NULL;

while ((dent = cupsDirRead(dir)) != NULL)
{
/*
@@ -1603,10 +1614,12 @@

  • Run the driver with no arguments and collect the output...
    */
  • snprintf(filename, sizeof(filename), "%s/%s list", drivers, dent->filename);
  • if ((fp = popen(filename, "r")) != NULL)
  • argv[0] = dent->filename;
  • snprintf(filename, sizeof(filename), "%s/%s", drivers, dent->filename);
  • if ((fp = cupsdPipeCommand(&pid, filename, argv, 0)) != NULL)
    {

  •  while (fgets(line, sizeof(line), fp) != NULL)
    
  •  while (cupsFileGets(fp, line, sizeof(line)))
    

    {
    /*
    * Each line is of the form:
    @@ -1655,7 +1668,8 @@

    if (type >= (int)(sizeof(ppd_types) / sizeof(ppd_types[0])))
    {

  •   fprintf(stderr, "ERROR: [cups-driverd] Bad ppd-type \"%s\" ignored!\n",
    
  •   fprintf(stderr,
    
  •           "ERROR: [cups-driverd] Bad ppd-type \"%s\" ignored!\n",
            type_str);
    type = PPD_TYPE_UNKNOWN;
    

    }
    @@ -1666,7 +1680,7 @@
    if (!ppd)
    {
    cupsDirClose(dir);

  •   pclose(fp);
    
  •   cupsFileClose(fp);
    return (0);
    

    }

@@ -1691,7 +1705,7 @@
}
}

  •  pclose(fp);
    
  •  cupsFileClose(fp);
    

    }
    else
    fprintf(stderr, "WARNING: [cups-driverd] Unable to execute "%s": %s\n",
    Index: scheduler/cups-deviced.c

    --- scheduler/cups-deviced.c (revision 7617)
    +++ scheduler/cups-deviced.c (working copy)
    @@ -17,7 +17,6 @@
    • main() - Scan for devices and return an IPP response.
    • add_dev() - Add a new device to the list.
    • compare_devs() - Compare device names for sorting.
  • * run_backend() - Run a backend to gather the available devices.
    • sigalrm_handler() - Handle alarm signals for backends that get hung
      */

@@ -64,7 +63,6 @@
const char *device_uri,
const char *device_id);
static int compare_devs(dev_info_t *p0, dev_info_t *p1);
-static FILE *run_backend(const char *backend, int uid, int *pid);
static void sigalrm_handler(int sig);

@@ -85,7 +83,8 @@
int request_id; /* Request ID /
int count; /
Number of devices from backend /
int compat; /
Compatibility device? */

  • FILE fp; / Pipe to device backend */

  • char backend_argv[2]; / Arguments for backend */

  • cups_file_t fp; / Pipe to device backend /
    int pid; /
    Process ID of backend /
    cups_dir_t *dir; /
    Directory pointer /
    cups_dentry_t *dent; /
    Directory entry */
    @@ -211,11 +210,13 @@

  • all others run as the unprivileged user...
    */

  • fp = run_backend(filename,

  •                 (dent->fileinfo.st_mode & (S_IRWXG | S_IRWXO))
    
  •            ? normal_user : 0,
    
  •        &pid);
    
  • backend_argv[0] = dent->filename;

  • backend_argv[1] = NULL;

  • fp = cupsdPipeCommand(&pid, filename, backend_argv,

  •                      (dent->fileinfo.st_mode & (S_IRWXG | S_IRWXO))
    
  •                 ? normal_user : 0);
    

    /*

    • Collect the output from the backend...
      */
      @@ -246,7 +247,7 @@

      alarm(30);

  •  while (fgets(line, sizeof(line), fp) != NULL)
    
  •  while (cupsFileGets(fp, line, sizeof(line)))
    

    {
    /*
    * Reset the alarm clock...
    @@ -291,7 +292,7 @@
    if (!dev)
    {
    cupsDirClose(dir);

  •   fclose(fp);
    
  •   cupsFileClose(fp);
         kill(pid, SIGTERM);
    return (1);
    

    }
    @@ -312,7 +313,7 @@
    fprintf(stderr, "WARNING: [cups-deviced] Backend "%s" did not "
    "respond within 30 seconds!\n", dent->filename);

  •  fclose(fp);
    
  •  cupsFileClose(fp);
    

    kill(pid, SIGTERM);

    /*
    @@ -482,71 +483,6 @@

    /*

  • * 'run_backend()' - Run a backend to gather the available devices.

- */

-static FILE * /* O - stdout of backend /
-run_backend(const char *backend, /
I - Backend to run */

  •        int        uid,        /\* I - User ID to run as */
    
  •   int        _pid)        /_ O - Process ID of backend */
    
    -{

- int fds[2]; /* Pipe file descriptors */

  • if (pipe(fds))
  • {
  • fprintf(stderr, "ERROR: Unable to create a pipe for "%s" - %s\n",
  •        backend, strerror(errno));
    
  • return (NULL);

- }

  • if ((*pid = fork()) < 0)
  • {
  • /*
  • * Error!

- */

  • fprintf(stderr, "ERROR: Unable to fork for "%s" - %s\n", backend,
  •        strerror(errno));
    
  • close(fds[0]);
  • close(fds[1]);
  • return (NULL);
  • }
  • else if (!*pid)
  • {
  • /*
  • * Child comes here...

- */

  • if (!getuid() && uid)

- setuid(uid); /* Run as restricted user */

  • close(0); /* </dev/null */

- open("/dev/null", O_RDONLY);

  • close(1); /* >pipe */

- dup(fds[1]);

  • close(fds[0]); /* Close copies of pipes */

- close(fds[1]);

  • execl(backend, backend, (char )0); / Run it! */
  • fprintf(stderr, "ERROR: Unable to execute "%s" - %s\n", backend,
  •        strerror(errno));
    
  • exit(1);

- }

  • /*
  • * Parent comes here, make a FILE * from the input side of the pipe...

- */

- close(fds[1]);

  • return (fdopen(fds[0], "r"));
    -}

-/*

  • 'sigalrm_handler()' - Handle alarm signals for backends that get hung
  •                   trying to list the available devices...
    
    */

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant