Ejemplo n.º 1
0
static void
usage(FILE *fp)		/* I - File to send usage to */
{
  if (getuid())
    _cupsLangPuts(fp, _("Usage: lppasswd [-g groupname]\n"));
  else
    _cupsLangPuts(fp, 
                  _("Usage: lppasswd [-g groupname] [username]\n"
		    "       lppasswd [-g groupname] -a [username]\n"
		    "       lppasswd [-g groupname] -x [username]\n"));

  exit(1);
}
static void
usage(void)
{
  _cupsLangPuts(stdout, _("Usage: ippdiscover [options] -a\n"
                          "       ippdiscover [options] \"service name\"\n"
                          "\n"
                          "Options:"));
  _cupsLangPuts(stdout, _("  -a                      Browse for all services."));
  _cupsLangPuts(stdout, _("  -d domain               Browse/resolve in specified domain."));
  _cupsLangPuts(stdout, _("  -p program              Run specified program for each service."));
  _cupsLangPuts(stdout, _("  -t type                 Browse/resolve with specified type."));

  exit(0);
}
Ejemplo n.º 3
0
static void
usage(const char *opt)			/* I - Option character/string */
{
  if (opt)
  {
    if (*opt == '-')
      _cupsLangPrintf(stderr, _("cupsctl: Unknown option \"%s\"!\n"), opt);
    else
      _cupsLangPrintf(stderr, _("cupsctl: Unknown option \"-%c\"!\n"), *opt);
  }

  _cupsLangPuts(stdout,
                _("Usage: cupsctl [options] [param=value ... paramN=valueN]\n"
		  "\n"
		  "Options:\n"
		  "\n"
		  "    -E                      Enable encryption\n"
		  "    -U username             Specify username\n"
		  "    -h server[:port]        Specify server address\n"
		  "\n"
		  "    --[no-]debug-logging    Turn debug logging on/off\n"
		  "    --[no-]remote-admin     Turn remote administration "
		  "on/off\n"
		  "    --[no-]remote-any       Allow/prevent access from the "
		  "Internet\n"
		  "    --[no-]remote-printers  Show/hide remote printers\n"
		  "    --[no-]share-printers   Turn printer sharing on/off\n"
		  "    --[no-]user-cancel-any  Allow/prevent users to cancel "
		  "any job\n"));

  exit(1);
}
Ejemplo n.º 4
0
static void
usage(void)
{
  _cupsLangPuts(stderr,
                _("Usage: lpq [-P dest] [-U username] [-h hostname[:port]] "
		  "[-l] [+interval]"));
  exit(1);
}
Ejemplo n.º 5
0
void
usage(void)
{
  _cupsLangPuts(stdout, _("Usage: cupsaddsmb [options] printer1 ... printerN"));
  _cupsLangPuts(stdout, _("       cupsaddsmb [options] -a"));
  _cupsLangPuts(stdout, "");
  _cupsLangPuts(stdout, _("Options:"));
  _cupsLangPuts(stdout, _("  -E                      Encrypt the connection."));
  _cupsLangPuts(stdout, _("  -H samba-server         Use the named SAMBA "
                          "server."));
  _cupsLangPuts(stdout, _("  -U username             Specify username."));
  _cupsLangPuts(stdout, _("  -a                      Export all printers."));
  _cupsLangPuts(stdout, _("  -h server[:port]        Specify server address."));
  _cupsLangPuts(stdout, _("  -v                      Be verbose."));

  exit(1);
}
Ejemplo n.º 6
0
static void
usage(void)
{
  _cupsLangPuts(stdout, _("Usage: lpoptions [options] -d destination\n"
                          "       lpoptions [options] [-p destination] [-l]\n"
                          "       lpoptions [options] [-p destination] -o option[=value]\n"
                          "       lpoptions [options] -x destination"));
  _cupsLangPuts(stdout, _("Options:"));
  _cupsLangPuts(stdout, _("-d destination          Set default destination"));
  _cupsLangPuts(stdout, _("-E                      Encrypt the connection to the server"));
  _cupsLangPuts(stdout, _("-h server[:port]        Connect to the named server and port"));
  _cupsLangPuts(stdout, _("-l                      Show supported options and values"));
  _cupsLangPuts(stdout, _("-o name[=value]         Set default option and value"));
  _cupsLangPuts(stdout, _("-p destination          Specify a destination"));
  _cupsLangPuts(stdout, _("-U username             Specify the username to use for authentication"));
  _cupsLangPuts(stdout, _("-x destination          Remove default options for destination"));

  exit(1);
}
Ejemplo n.º 7
0
static void
usage(void)
{
  _cupsLangPuts(stdout,
                _("Usage: lpoptions [-h server] [-E] -d printer\n"
		  "       lpoptions [-h server] [-E] [-p printer] -l\n"
		  "       lpoptions [-h server] [-E] -p printer -o "
		  "option[=value] ...\n"
		  "       lpoptions [-h server] [-E] -x printer"));

  exit(1);
}
Ejemplo n.º 8
0
static void
usage(const char *command,		/* I - Command name */
      const char *opt)			/* I - Incorrect option, if any */
{
  if (opt)
    _cupsLangPrintf(stderr, _("%s: Unknown option '%c'!\n"), command, *opt);

  if (!strcmp(command, "cupsfilter"))
    _cupsLangPuts(stdout,
		  _("Usage: cupsfilter -m mime/type [ options ] filename\n"
		    "\n"
		    "Options:\n"
		    "\n"
		    "  -c cupsd.conf    Set cupsd.conf file to use\n"
		    "  -n copies        Set number of copies\n"
		    "  -o name=value    Set option(s)\n"
		    "  -p filename.ppd  Set PPD file\n"
		    "  -t title         Set title\n"));
  else
    _cupsLangPuts(stdout,
		  _("Usage: convert [ options ]\n"
		    "\n"
		    "Options:\n"
		    "\n"
		    "  -f filename          Set file to be converted (otherwise stdin)\n"
		    "  -o filename          Set file to be generated (otherwise stdout)\n"
		    "  -i mime/type         Set input MIME type (otherwise auto-typed)\n"
		    "  -j mime/type         Set output MIME type (otherwise application/pdf)\n"
		    "  -P filename.ppd      Set PPD file\n"
		    "  -a 'name=value ...'  Set option(s)\n"
		    "  -U username          Set username for job\n"
		    "  -J title             Set title\n"
		    "  -c copies            Set number of copies\n"
		    "  -u                   Remove the PPD file when finished\n"
		    "  -D                   Remove the input file when finished\n"));

  exit(1);
}
Ejemplo n.º 9
0
static void
usage(void)
{
  _cupsLangPuts(stdout, _("Usage: cupstestdsc [options] filename.ps [... "
                          "filename.ps]"));
  _cupsLangPuts(stdout, _("       cupstestdsc [options] -"));
  _cupsLangPuts(stdout, "");
  _cupsLangPuts(stdout, _("Options:"));
  _cupsLangPuts(stdout, "");
  _cupsLangPuts(stdout, _("    -h       Show program usage"));
  _cupsLangPuts(stdout, "");
  _cupsLangPuts(stdout, _("Note: this program only validates the DSC comments, "
		          "not the PostScript itself."));

  exit(1);
}
Ejemplo n.º 10
0
Archivo: main.c Proyecto: apple/cups
static void
usage(int status)			/* O - Exit status */
{
  FILE	*fp = status ? stderr : stdout;	/* Output file */


  _cupsLangPuts(fp, _("Usage: cupsd [options]"));
  _cupsLangPuts(fp, _("Options:"));
  _cupsLangPuts(fp, _("  -c cupsd.conf           Set cupsd.conf file to use."));
  _cupsLangPuts(fp, _("  -f                      Run in the foreground."));
  _cupsLangPuts(fp, _("  -F                      Run in the foreground but detach from console."));
  _cupsLangPuts(fp, _("  -h                      Show this usage message."));
#ifdef HAVE_ONDEMAND
  _cupsLangPuts(fp, _("  -l                      Run cupsd on demand."));
#endif /* HAVE_ONDEMAND */
  _cupsLangPuts(fp, _("  -s cups-files.conf      Set cups-files.conf file to use."));
  _cupsLangPuts(fp, _("  -t                      Test the configuration file."));

  exit(status);
}
Ejemplo n.º 11
0
static void
usage(const char *opt)			/* I - Option character/string */
{
  if (opt)
  {
    if (*opt == '-')
      _cupsLangPrintf(stderr, _("cupsctl: Unknown option \"%s\""), opt);
    else
      _cupsLangPrintf(stderr, _("cupsctl: Unknown option \"-%c\""), *opt);
  }

  _cupsLangPuts(stdout, _("Usage: cupsctl [options] [param=value ... paramN=valueN]"));
  _cupsLangPuts(stdout, _("Options:"));
  _cupsLangPuts(stdout, _("-E                      Encrypt the connection to the server"));
  _cupsLangPuts(stdout, _("-h server[:port]        Connect to the named server and port"));
  _cupsLangPuts(stdout, _("-U username             Specify username to use for authentication"));
  _cupsLangPuts(stdout, _("--[no-]debug-logging    Turn debug logging on/off"));
  _cupsLangPuts(stdout, _("--[no-]remote-admin     Turn remote administration on/off"));
  _cupsLangPuts(stdout, _("--[no-]remote-any       Allow/prevent access from the Internet"));
  _cupsLangPuts(stdout, _("--[no-]share-printers   Turn printer sharing on/off"));
  _cupsLangPuts(stdout, _("--[no-]user-cancel-any  Allow/prevent users to cancel any job"));

  exit(1);
}
Ejemplo n.º 12
0
static void
usage(int status)			/* O - Exit status */
{
  FILE	*fp = status ? stderr : stdout;	/* Output file */


  _cupsLangPuts(fp, _("Usage: cupsd [options]"));
  _cupsLangPuts(fp, _("Options:"));
  _cupsLangPuts(fp, _("  -c cupsd.conf           Set cupsd.conf file to use."));
  _cupsLangPuts(fp, _("  -f                      Run in the foreground."));
  _cupsLangPuts(fp, _("  -F                      Run in the foreground but "
                      "detach from console."));
  _cupsLangPuts(fp, _("  -h                      Show this usage message."));
  _cupsLangPuts(fp, _("  -l                      Run cupsd from launchd(8)."));
  _cupsLangPuts(fp, _("  -t                      Test the configuration "
                      "file."));

  exit(status);
}
Ejemplo n.º 13
0
static void
usage(const char *command)		/* I - Command name */
{
  _cupsLangPrintf(stdout, _("Usage: %s [options] destination(s)"), command);
  _cupsLangPuts(stdout, _("Options:"));
  _cupsLangPuts(stdout, _("-E                      Encrypt the connection to the server"));
  _cupsLangPuts(stdout, _("-h server[:port]        Connect to the named server and port"));
  _cupsLangPuts(stdout, _("-r reason               Specify a reason message that others can see"));
  _cupsLangPuts(stdout, _("-U username             Specify the username to use for authentication"));
  if (!strcmp(command, "cupsdisable"))
    _cupsLangPuts(stdout, _("--hold                  Hold new jobs"));
  if (!strcmp(command, "cupsenable"))
    _cupsLangPuts(stdout, _("--release               Release previously held jobs"));

  exit(1);
}
Ejemplo n.º 14
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line args */
     char *argv[]			/* I - Command-line arguments */
#ifdef PRINT_AUXV
     ,
     char* envp[]
#endif
     )
{
  int			i;		/* Looping var */
  char			*opt;		/* Option character */
  int			fg;		/* Run in the foreground */
  int			fds;		/* Number of ready descriptors */
  cupsd_client_t	*con;		/* Current client */
  cupsd_job_t		*job;		/* Current job */
  cupsd_listener_t	*lis;		/* Current listener */
  time_t		current_time,	/* Current time */
			activity,	/* Client activity timer */
			browse_time,	/* Next browse send time */
			senddoc_time,	/* Send-Document time */
			expire_time,	/* Subscription expire time */
			report_time,	/* Malloc/client/job report time */
			event_time;	/* Last time an event notification was done */
  long			timeout;	/* Timeout for cupsdDoSelect() */
  struct rlimit		limit;		/* Runtime limit */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
  struct sigaction	action;		/* Actions for POSIX signals */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
#ifdef __sgi
  cups_file_t		*fp;		/* Fake lpsched lock file */
  struct stat		statbuf;	/* Needed for checking lpsched FIFO */
#endif /* __sgi */
#ifdef __APPLE__
  int			run_as_child = 0;
					/* Needed for Mac OS X fork/exec */
#else
  time_t		netif_time = 0;	/* Time since last network update */
#endif /* __APPLE__ */
#if HAVE_LAUNCHD
  int			launchd_idle_exit;
					/* Idle exit on select timeout? */
#endif	/* HAVE_LAUNCHD */
    

#ifdef PRINT_AUXV
  Elf32_auxv_t *auxv;
  while(*envp++ != NULL);

  for (auxv = (Elf32_auxv_t *)envp; auxv->a_type != AT_NULL; auxv++)
    {
      if (auxv->a_type == AT_SYSINFO)
	{
	  printf("AT_RANDOM is 0x%x\n", auxv->a_un.a_val);
	}
      
    }
#endif
 
#if UNDERSTAND_CUPS
  printf("[main.c::main()] cups has just started in main()\n");
#endif
  
  int count = 0;
  int loops_desired = -1; // loop forever unless this is set

#ifdef HAVE_GETEUID
  /*
  * Check for setuid invocation, which we do not support!
  */
  if (getuid() != geteuid())
  {
    fputs("cupsd: Cannot run as a setuid program!\n", stderr);
    return (1);
  }
#if UNDERSTAND_CUPS
  printf("[main.c::main()] uid = %d, euid = %d\n", getuid(), geteuid());
#endif
#endif /* HAVE_GETEUID */
  
 /*
  * Check for command-line arguments...
  */
#if UNDERSTAND_CUPS
  printf("[main.c::main()] parsing command line arguments \n");
#endif
  
  fg = 0;

#ifdef HAVE_LAUNCHD
  if (getenv("CUPSD_LAUNCHD"))
  {
    Launchd = 1;
    fg      = 1;
  }
#endif /* HAVE_LAUNCHD */

  for (i = 1; i < argc; i ++)
    if (argv[i][0] == '-')
      for (opt = argv[i] + 1; *opt != '\0'; opt ++)
        switch (*opt)
	{
#ifdef __APPLE__
	  case 'C' : /* Run as child with config file */
              run_as_child = 1;
	      fg           = -1;
#endif /* __APPLE__ */

	  case 'c' : /* Configuration file */
	      i ++;
	      if (i >= argc)
	      {
	        _cupsLangPuts(stderr, _("cupsd: Expected config filename "
		                        "after \"-c\" option!\n"));
	        usage(1);
	      }

              if (argv[i][0] == '/')
	      {
	       /*
	        * Absolute directory...
		*/

		cupsdSetString(&ConfigurationFile, argv[i]);
              }
	      else
	      {
	       /*
	        * Relative directory...
		*/

                char *current;		/* Current directory */


	       /*
	        * Allocate a buffer for the current working directory to
		* reduce run-time stack usage; this approximates the
		* behavior of some implementations of getcwd() when they
		* are passed a NULL pointer.
	        */

                if ((current = malloc(1024)) == NULL)
		{
		  _cupsLangPuts(stderr,
		                _("cupsd: Unable to get current directory!\n"));
                  return (1);
		}

		if (!getcwd(current, 1024))
		{
		  _cupsLangPuts(stderr,
		                _("cupsd: Unable to get current directory!\n"));
                  free(current);
		  return (1);
		}

		cupsdSetStringf(&ConfigurationFile, "%s/%s", current, argv[i]);
		free(current);
              }
	      break;

          case 'f' : /* Run in foreground... */
	    fg = 1;
	    break;
	    
          case 'F' : /* Run in foreground, but disconnect from terminal... */
	    fg = -1;
	    break;
	    
          case 'h' : /* Show usage/help */
	    usage(0);
	    break;
	    
          case 'l' : /* Started by launchd... */
#ifdef HAVE_LAUNCHD
	    Launchd = 1;
	    fg      = 1;
#else
	    _cupsLangPuts(stderr, _("cupsd: launchd(8) support not compiled "
				    "in, running in normal mode.\n"));
	    fg = 0;
#endif /* HAVE_LAUNCHD */
	      break;
	      
	case 'p' : /* Stop immediately for profiling */
	  puts("Warning: -p option is for internal testing use only!");
	  stop_scheduler = 1;
	  fg             = 1;
	  break;
	  
	/// XXX RAZA
	case 'x' : /* Number of Iterations to Perform */
	  i ++;
	  loops_desired = atoi(argv[i]);
	  break;
	  
	default : /* Unknown option */
	  _cupsLangPrintf(stderr, _("cupsd: Unknown option \"%c\" - "
				    "aborting!\n"), *opt);
	  usage(1);
	  break;
	}
    else
      {
	_cupsLangPrintf(stderr, _("cupsd: Unknown argument \"%s\" - aborting!\n"),
			argv[i]);
	usage(1);
      }

#if UNDERSTAND_CUPS
  printf("[main.c::main()] done parsing command line arguments \n");
  printf("[main.c::main()] num_loops = %d, foreground = %d\n", loops_desired, fg);
#endif

  if (!ConfigurationFile)
    cupsdSetString(&ConfigurationFile, CUPS_SERVERROOT "/cupsd.conf");

  printf("[main.c::main()] configuration file = %s\n", ConfigurationFile);
  
  /*
   * If the user hasn't specified "-f", run in the background...
  */

  if (!fg)
  {
   /*
    * Setup signal handlers for the parent...
    */

#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
    sigset(SIGUSR1, parent_handler);
    sigset(SIGCHLD, parent_handler);

    sigset(SIGHUP, SIG_IGN);
#elif defined(HAVE_SIGACTION)
    memset(&action, 0, sizeof(action));
    sigemptyset(&action.sa_mask);
    sigaddset(&action.sa_mask, SIGUSR1);
    action.sa_handler = parent_handler;
    sigaction(SIGUSR1, &action, NULL);
    sigaction(SIGCHLD, &action, NULL);

    sigemptyset(&action.sa_mask);
    action.sa_handler = SIG_IGN;
    sigaction(SIGHUP, &action, NULL);
#else
    signal(SIGUSR1, parent_handler);
    signal(SIGCLD, parent_handler);

    signal(SIGHUP, SIG_IGN);
#endif /* HAVE_SIGSET */

    if (fork() > 0)
    {
     /*
      * OK, wait for the child to startup and send us SIGUSR1 or to crash
      * and the OS send us SIGCHLD...  We also need to ignore SIGHUP which
      * might be sent by the init script to restart the scheduler...
      */

      for (; parent_signal == 0;)
        sleep(1);

      if (parent_signal == SIGUSR1)
        return (0);

      if (wait(&i) < 0)
      {
        perror("cupsd");
	return (1);
      }
      else if (WIFEXITED(i))
      {
        fprintf(stderr, "cupsd: Child exited with status %d!\n",
	        WEXITSTATUS(i));
	return (2);
      }
      else
      {
        fprintf(stderr, "cupsd: Child exited on signal %d!\n", WTERMSIG(i));
	return (3);
      }
    }

#ifdef __APPLE__
   /*
    * Since CoreFoundation has an overly-agressive check for whether a
    * process has forked but not exec'd (whether CF has been called or
    * not...), we now have to exec ourselves with the "-f" option to
    * eliminate their bogus warning messages.
    */

    execlp(argv[0], argv[0], "-C", ConfigurationFile, (char *)0);
    exit(errno);
#endif /* __APPLE__ */
  }

  if (fg < 1)
  {
   /*
    * Make sure we aren't tying up any filesystems...
    */

    chdir("/");

#ifndef DEBUG
   /*
    * Disable core dumps...
    */

    getrlimit(RLIMIT_CORE, &limit);
    limit.rlim_cur = 0;
    setrlimit(RLIMIT_CORE, &limit);

   /*
    * Disconnect from the controlling terminal...
    */

    setsid();

   /*
    * Close all open files...
    */

    getrlimit(RLIMIT_NOFILE, &limit);

    for (i = 0; i < limit.rlim_cur && i < 1024; i ++)
      close(i);
#endif /* DEBUG */
  }

 /*
  * Set the timezone info...
  */
#if UNDERSTAND_CUPS
  printf("[main.c::main()] setting timezone info, tzset()\n");
#endif

  tzset();

#ifdef LC_TIME
  setlocale(LC_TIME, "");
#if UNDERSTAND_CUPS
  printf("[main.c::main()] setting locale info, setlocale()\n");
#endif
#endif /* LC_TIME */

 /*
  * Set the maximum number of files...
  */
  getrlimit(RLIMIT_NOFILE, &limit);

#if !defined(HAVE_POLL) && !defined(HAVE_EPOLL) && !defined(HAVE_KQUEUE)
  if (limit.rlim_max > FD_SETSIZE)
    MaxFDs = FD_SETSIZE;
  else
#endif /* !HAVE_POLL && !HAVE_EPOLL && !HAVE_KQUEUE */
#ifdef RLIM_INFINITY
  if (limit.rlim_max == RLIM_INFINITY)
    MaxFDs = 16384;
  else
#endif /* RLIM_INFINITY */
    MaxFDs = limit.rlim_max;

  limit.rlim_cur = MaxFDs;

  setrlimit(RLIMIT_NOFILE, &limit);

#if UNDERSTAND_CUPS
  printf("[main.c::main()] set the maximum nuber of files = %d\n", MaxFDs);
#endif

  cupsdStartSelect();

#if UNDERSTAND_CUPS
  printf("[main.c::main()] done with cupsdStartSelect() i.e. polling engine\n");
#endif

 /*
  * Read configuration...
  */

  if (!cupsdReadConfiguration())
  {
    syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting!",
           ConfigurationFile);
    return (1);
  }

  printf("[main.c::main()] done with cupsdReadConfiguration\n");
  
  if (!strncmp(TempDir, RequestRoot, strlen(RequestRoot)))
  {
   /*
    * Clean out the temporary directory...
    */

    cups_dir_t		*dir;		/* Temporary directory */
    cups_dentry_t	*dent;		/* Directory entry */
    char		tempfile[1024];	/* Temporary filename */

    printf("[main.c::main()] cleaning temp dir = %s\n", TempDir);

    if ((dir = cupsDirOpen(TempDir)) != NULL)
    {
      cupsdLogMessage(CUPSD_LOG_INFO,
                      "Cleaning out old temporary files in \"%s\"...", TempDir);

      while ((dent = cupsDirRead(dir)) != NULL)
      {
        snprintf(tempfile, sizeof(tempfile), "%s/%s", TempDir, dent->filename);
	printf("[main.c::main()] deleting temp file = %s\n", tempfile);

	if (cupsdRemoveFile(tempfile)) {
	  cupsdLogMessage(CUPSD_LOG_ERROR,
	                  "Unable to remove temporary file \"%s\" - %s",
	                  tempfile, strerror(errno));
	  printf("[main.c::main()] failed in deleting temp file = %s\n", tempfile);
	} 
	else {
	  cupsdLogMessage(CUPSD_LOG_DEBUG, "Removed temporary file \"%s\"...",
			              tempfile);
	  printf("[main.c::main()] deleted temp file = %s\n", tempfile);
	}
      }

      cupsDirClose(dir);
    }
    else {
      cupsdLogMessage(CUPSD_LOG_ERROR,
                      "Unable to open temporary directory \"%s\" - %s",
		                  TempDir, strerror(errno));
      printf("[main.c::main()] couldn't open temp dir = %s\n", TempDir);
    }

    printf("[main.c::main()] DONE cleaning temp dir = %s\n", TempDir);
  }

#if HAVE_LAUNCHD
  if (Launchd)
  {
   /*
    * If we were started by launchd get the listen sockets file descriptors...
    */
    printf("[main.c::main()] launchd check in \n");
    launchd_checkin();
  }
#endif /* HAVE_LAUNCHD */

#if defined(__APPLE__) && defined(HAVE_DLFCN_H)
 /*
  * Load Print Service quota enforcement library (X Server only)
  */

  PSQLibRef = dlopen(PSQLibPath, RTLD_LAZY);

  if (PSQLibRef)
    PSQUpdateQuotaProc = dlsym(PSQLibRef, PSQLibFuncName);
#endif /* __APPLE__ && HAVE_DLFCN_H */

#ifdef HAVE_GSSAPI
#  ifdef __APPLE__
 /*
  * If the weak-linked GSSAPI/Kerberos library is not present, don't try
  * to use it...
  */

  if (krb5_init_context != NULL)
#  endif /* __APPLE__ */

 /*
  * Setup a Kerberos context for the scheduler to use...
  */
  if (krb5_init_context(&KerberosContext))
  {
    KerberosContext = NULL;

    printf("[main.c::main()] unable to use krb5_init_context() \n");

    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to initialize Kerberos context");
  }
  else
    {
      printf("[main.c::main()] used krb5_init_context() \n");
    }
#endif /* HAVE_GSSAPI */

 /*
  * Startup the server...
  */

  cupsdStartServer();

 /*
  * Catch hangup and child signals and ignore broken pipes...
  */

#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
  sigset(SIGCHLD, sigchld_handler);
  sigset(SIGHUP, sighup_handler);
  sigset(SIGPIPE, SIG_IGN);
  sigset(SIGTERM, sigterm_handler);
  printf("[main.c::main()] used system V signals over POSIX\n");
#elif defined(HAVE_SIGACTION)
  printf("[main.c::main()] used HAVE_SIGACTION\n");

  memset(&action, 0, sizeof(action));
  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGTERM);
  sigaddset(&action.sa_mask, SIGCHLD);
  action.sa_handler = sigchld_handler;
  sigaction(SIGCHLD, &action, NULL);

  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGHUP);
  action.sa_handler = sighup_handler;
  sigaction(SIGHUP, &action, NULL);

  sigemptyset(&action.sa_mask);
  action.sa_handler = SIG_IGN;
  sigaction(SIGPIPE, &action, NULL);

  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGTERM);
  sigaddset(&action.sa_mask, SIGCHLD);
  action.sa_handler = sigterm_handler;
  sigaction(SIGTERM, &action, NULL);
#else
  printf("[main.c::main()]last signal options\n");
  signal(SIGCLD, sigchld_handler);	/* No, SIGCLD isn't a typo... */
  signal(SIGHUP, sighup_handler);
  signal(SIGPIPE, SIG_IGN);
  signal(SIGTERM, sigterm_handler);
  
#endif /* HAVE_SIGSET */

#ifdef __sgi
 /*
  * Try to create a fake lpsched lock file if one is not already there.
  * Some Adobe applications need it under IRIX in order to enable
  * printing...
  */
  printf("[main.c::main()] creating fake lpsched lock file \n");
  if ((fp = cupsFileOpen("/var/spool/lp/SCHEDLOCK", "w")) == NULL)
  {
    syslog(LOG_LPR, "Unable to create fake lpsched lock file "
                    "\"/var/spool/lp/SCHEDLOCK\"\' - %s!",
           strerror(errno));
  }
  else
  {
    fchmod(cupsFileNumber(fp), 0644);
    fchown(cupsFileNumber(fp), User, Group);

    cupsFileClose(fp);
  }
#endif /* __sgi */

 /*
  * Initialize authentication certificates...
  */

  cupsdInitCerts();

 /*
  * If we are running in the background, signal the parent process that
  * we are up and running...
  */

#ifdef __APPLE__
  if (!fg || run_as_child)
#else
  if (!fg)
#endif /* __APPLE__ */
  {
   /*
    * Send a signal to the parent process, but only if the parent is
    * not PID 1 (init).  This avoids accidentally shutting down the
    * system on OpenBSD if you CTRL-C the server before it is up...
    */

    i = getppid();	/* Save parent PID to avoid race condition */

    if (i != 1)
      kill(i, SIGUSR1);
  }

#ifdef __APPLE__
 /*
  * Start power management framework...
  */
  printf("[main.c::main()] starting system monitor (power management) \n");
  cupsdStartSystemMonitor();
#endif /* __APPLE__ */

 /*
  * Start any pending print jobs...
  */

  printf("[main.c::main()] starting any pending print jobs \n");
  cupsdCheckJobs();

 /*
  * Loop forever...
  */

  current_time  = time(NULL);
  browse_time   = current_time;
  event_time    = current_time;
  expire_time   = current_time;
  fds           = 1;
  report_time   = 0;
  senddoc_time  = current_time;

  
  while (!stop_scheduler)
   {
    
    // XXX RAZA
    printf("[main.c::main()] scheduler loop # %d\n", count);
    if (count++ == loops_desired)
      {
	printf("[main.c::main()] stopping scheduler loop\n");
   	stop_scheduler = 1;
	continue;
      } 
    
    printf("[main.c::main()]  Top of loop, dead_children=%d, NeedReload=%d\n",
	   dead_children, NeedReload);    
    
#ifdef DEBUG
    cupsdLogMessage(CUPSD_LOG_DEBUG2,
                    "main: Top of loop, dead_children=%d, NeedReload=%d",
                    dead_children, NeedReload);
#endif /* DEBUG */

    

   /*
    * Check if there are dead children to handle...
    */

    if (dead_children)
      process_children();

   /*
    * Check if we need to load the server configuration file...
    */

    if (NeedReload)
    {
     /*
      * Close any idle clients...
      */

      if (cupsArrayCount(Clients) > 0)
      {
	for (con = (cupsd_client_t *)cupsArrayFirst(Clients);
	     con;
	     con = (cupsd_client_t *)cupsArrayNext(Clients))
	  if (con->http.state == HTTP_WAITING)
	    cupsdCloseClient(con);
	  else
	    con->http.keep_alive = HTTP_KEEPALIVE_OFF;

        cupsdPauseListening();
      }

     /*
      * Check for any active jobs...
      */

      for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs);
	   job;
	   job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
        if (job->state_value == IPP_JOB_PROCESSING)
	  break;

     /*
      * Restart if all clients are closed and all jobs finished, or
      * if the reload timeout has elapsed...
      */

      if ((cupsArrayCount(Clients) == 0 &&
           (!job || NeedReload != RELOAD_ALL)) ||
          (time(NULL) - ReloadTime) >= ReloadTimeout)
      {
       /*
	* Shutdown the server...
	*/

	cupsdStopServer();

       /*
	* Read configuration...
	*/

        if (!cupsdReadConfiguration())
        {
          syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting!",
		 ConfigurationFile);
          break;
	}

#if HAVE_LAUNCHD
	if (Launchd)
	{
	 /*
	  * If we were started by launchd get the listen sockets file descriptors...
	  */

	  launchd_checkin();
	}
#endif /* HAVE_LAUNCHD */

       /*
        * Startup the server...
        */

        cupsdStartServer();
      }
    }

   /*
    * Check for available input or ready output.  If cupsdDoSelect()
    * returns 0 or -1, something bad happened and we should exit
    * immediately.
    *
    * Note that we at least have one listening socket open at all
    * times.
    */

    if ((timeout = select_timeout(fds)) > 1 && LastEvent)
      timeout = 1;

#if HAVE_LAUNCHD
   /*
    * If no other work is scheduled and we're being controlled by
    * launchd then timeout after 'LaunchdTimeout' seconds of
    * inactivity...
    */

    if (timeout == 86400 && Launchd && LaunchdTimeout && !NumPolled &&
        !cupsArrayCount(ActiveJobs) &&
	(!Browsing || 
	 (!BrowseRemoteProtocols && 
	  (!NumBrowsers || !BrowseLocalProtocols ||
	   cupsArrayCount(Printers) == 0))))
    {
      timeout		= LaunchdTimeout;
      launchd_idle_exit = 1;
    }
    else
      launchd_idle_exit = 0;
#endif	/* HAVE_LAUNCHD */

    if ((fds = cupsdDoSelect(timeout)) < 0)
    {
     /*
      * Got an error from select!
      */

#ifdef HAVE_DNSSD
      cupsd_printer_t	*p;		/* Current printer */
#endif /* HAVE_DNSSD */


      if (errno == EINTR)		/* Just interrupted by a signal */
        continue;

     /*
      * Log all sorts of debug info to help track down the problem.
      */

      cupsdLogMessage(CUPSD_LOG_EMERG, "cupsdDoSelect() failed - %s!",
                      strerror(errno));

      for (i = 0, con = (cupsd_client_t *)cupsArrayFirst(Clients);
	   con;
	   i ++, con = (cupsd_client_t *)cupsArrayNext(Clients))
        cupsdLogMessage(CUPSD_LOG_EMERG,
	                "Clients[%d] = %d, file = %d, state = %d",
	                i, con->http.fd, con->file, con->http.state);

      for (i = 0, lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
           lis;
	   i ++, lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
        cupsdLogMessage(CUPSD_LOG_EMERG, "Listeners[%d] = %d", i, lis->fd);

      cupsdLogMessage(CUPSD_LOG_EMERG, "BrowseSocket = %d", BrowseSocket);

      cupsdLogMessage(CUPSD_LOG_EMERG, "CGIPipes[0] = %d", CGIPipes[0]);

#ifdef __APPLE__
      cupsdLogMessage(CUPSD_LOG_EMERG, "SysEventPipes[0] = %d",
                      SysEventPipes[0]);
#endif /* __APPLE__ */

      for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs);
	   job;
	   job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
        cupsdLogMessage(CUPSD_LOG_EMERG, "Jobs[%d] = %d < [%d %d] > [%d %d]",
	        	job->id,
			job->status_buffer ? job->status_buffer->fd : -1,
			job->print_pipes[0], job->print_pipes[1],
			job->back_pipes[0], job->back_pipes[1]);

#ifdef HAVE_DNSSD
      for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
	   p;
	   p = (cupsd_printer_t *)cupsArrayNext(Printers))
        cupsdLogMessage(CUPSD_LOG_EMERG, "printer[%s] %d", p->name,
	                p->dnssd_ipp_fd);
#endif /* HAVE_DNSSD */

      break;
    }

    current_time = time(NULL);

#ifndef __APPLE__
   /*
    * Update the network interfaces once a minute...
    */

    if ((current_time - netif_time) >= 60)
    {
      netif_time  = current_time;
      NetIFUpdate = 1;
    }
#endif /* !__APPLE__ */

#if HAVE_LAUNCHD
   /*
    * If no other work was scheduled and we're being controlled by launchd
    * then timeout after 'LaunchdTimeout' seconds of inactivity...
    */

    if (!fds && launchd_idle_exit)
    {
      cupsdLogMessage(CUPSD_LOG_INFO,
                      "Printer sharing is off and there are no jobs pending, "
		      "will restart on demand.");
      stop_scheduler = 1;
      break;
    }
#endif /* HAVE_LAUNCHD */

   /*
    * Resume listening for new connections as needed...
    */

    if (ListeningPaused && ListeningPaused <= current_time &&
        cupsArrayCount(Clients) < MaxClients)
      cupsdResumeListening();

   /*
    * Expire subscriptions and unload completed jobs as needed...
    */

    if (current_time > expire_time)
    {
      if (cupsArrayCount(Subscriptions) > 0)
        cupsdExpireSubscriptions(NULL, NULL);

      cupsdUnloadCompletedJobs();

      expire_time = current_time;
    }

   /*
    * Update the browse list as needed...
    */

    if (Browsing)
    {
#ifdef HAVE_LIBSLP
      if ((BrowseRemoteProtocols & BROWSE_SLP) &&
          BrowseSLPRefresh <= current_time)
        cupsdUpdateSLPBrowse();
#endif /* HAVE_LIBSLP */

#ifdef HAVE_LDAP
      if ((BrowseRemoteProtocols & BROWSE_LDAP) &&
          BrowseLDAPRefresh <= current_time)
        cupsdUpdateLDAPBrowse();
#endif /* HAVE_LDAP */
    }

    if (Browsing && current_time > browse_time)
    {
      cupsdSendBrowseList();
      browse_time = current_time;
    }

   /*
    * Update the root certificate once every 5 minutes if we have client
    * connections...
    */

    if ((current_time - RootCertTime) >= RootCertDuration && RootCertDuration &&
        !RunUser && cupsArrayCount(Clients))
    {
     /*
      * Update the root certificate...
      */

      cupsdDeleteCert(0);
      cupsdAddCert(0, "root", NULL);
    }

   /*
    * Check for new data on the client sockets...
    */

    for (con = (cupsd_client_t *)cupsArrayFirst(Clients);
	 con;
	 con = (cupsd_client_t *)cupsArrayNext(Clients))
    {
     /*
      * Process pending data in the input buffer...
      */

      if (con->http.used)
      {
        cupsdReadClient(con);
	continue;
      }

     /*
      * Check the activity and close old clients...
      */

      activity = current_time - Timeout;
      if (con->http.activity < activity && !con->pipe_pid)
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG,
	                "Closing client %d after %d seconds of inactivity...",
	                con->http.fd, Timeout);

        cupsdCloseClient(con);
        continue;
      }
    }

   /*
    * Update any pending multi-file documents...
    */

    if ((current_time - senddoc_time) >= 10)
    {
      cupsdCheckJobs();
      senddoc_time = current_time;
    }

   /*
    * Log statistics at most once a minute when in debug mode...
    */

    if ((current_time - report_time) >= 60 && LogLevel >= CUPSD_LOG_DEBUG)
    {
      size_t		string_count,	/* String count */
			alloc_bytes,	/* Allocated string bytes */
			total_bytes;	/* Total string bytes */
#ifdef HAVE_MALLINFO
      struct mallinfo	mem;		/* Malloc information */


      mem = mallinfo();
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: malloc-arena=%lu", mem.arena);
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: malloc-used=%lu",
                      mem.usmblks + mem.uordblks);
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: malloc-free=%lu",
		      mem.fsmblks + mem.fordblks);
#endif /* HAVE_MALLINFO */

      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: clients=%d",
                      cupsArrayCount(Clients));
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: jobs=%d",
                      cupsArrayCount(Jobs));
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: jobs-active=%d",
                      cupsArrayCount(ActiveJobs));
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: printers=%d",
                      cupsArrayCount(Printers));
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: printers-implicit=%d",
                      cupsArrayCount(ImplicitPrinters));

      string_count = _cupsStrStatistics(&alloc_bytes, &total_bytes);
      cupsdLogMessage(CUPSD_LOG_DEBUG,
                      "Report: stringpool-string-count=" CUPS_LLFMT,
		      CUPS_LLCAST string_count);
      cupsdLogMessage(CUPSD_LOG_DEBUG,
                      "Report: stringpool-alloc-bytes=" CUPS_LLFMT,
		      CUPS_LLCAST alloc_bytes);
      cupsdLogMessage(CUPSD_LOG_DEBUG,
                      "Report: stringpool-total-bytes=" CUPS_LLFMT,
		      CUPS_LLCAST total_bytes);

      report_time = current_time;
    }

   /*
    * Handle OS-specific event notification for any events that have
    * accumulated.  Don't send these more than once a second...
    */

    if (LastEvent && (current_time - event_time) >= 1)
    {
#ifdef HAVE_NOTIFY_POST
      if (LastEvent & (CUPSD_EVENT_PRINTER_ADDED |
                       CUPSD_EVENT_PRINTER_DELETED |
                       CUPSD_EVENT_PRINTER_MODIFIED))
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG2,
	                "notify_post(\"com.apple.printerListChange\")");
	notify_post("com.apple.printerListChange");
      }

      if (LastEvent & CUPSD_EVENT_PRINTER_STATE_CHANGED)
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG2,
	                "notify_post(\"com.apple.printerHistoryChange\")");
	notify_post("com.apple.printerHistoryChange");
      }

      if (LastEvent & (CUPSD_EVENT_JOB_STATE_CHANGED |
                       CUPSD_EVENT_JOB_CONFIG_CHANGED |
                       CUPSD_EVENT_JOB_PROGRESS))
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG2,
	                "notify_post(\"com.apple.jobChange\")");
	notify_post("com.apple.jobChange");
      }
#endif /* HAVE_NOTIFY_POST */

     /*
      * Reset the accumulated events...
      */

      LastEvent  = CUPSD_EVENT_NONE;
      event_time = current_time;
    }
   }

 /*
  * Log a message based on what happened...
  */

  if (stop_scheduler)
    cupsdLogMessage(CUPSD_LOG_INFO, "Scheduler shutting down normally.");
  else
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "Scheduler shutting down due to program error.");

 /*
  * Close all network clients...
  */

  cupsdStopServer();

#ifdef HAVE_LAUNCHD
 /*
  * Update the launchd KeepAlive file as needed...
  */

  if (Launchd)
    launchd_checkout();
#endif /* HAVE_LAUNCHD */

 /*
  * Stop all jobs...
  */

  cupsdFreeAllJobs();

#ifdef __APPLE__
 /*
  * Stop monitoring system event monitoring...
  */

  cupsdStopSystemMonitor();
#endif /* __APPLE__ */

#ifdef HAVE_GSSAPI
 /*
  * Free the scheduler's Kerberos context...
  */

#  ifdef __APPLE__
 /*
  * If the weak-linked GSSAPI/Kerberos library is not present, don't try
  * to use it...
  */

  if (krb5_init_context != NULL)
#  endif /* __APPLE__ */
  if (KerberosContext)
    krb5_free_context(KerberosContext);
#endif /* HAVE_GSSAPI */

#ifdef __APPLE__
#ifdef HAVE_DLFCN_H
 /* 
  * Unload Print Service quota enforcement library (X Server only) 
  */

  PSQUpdateQuotaProc = NULL;
  if (PSQLibRef)
  {
    dlclose(PSQLibRef);
    PSQLibRef = NULL;
  }
#endif /* HAVE_DLFCN_H */
#endif	/* __APPLE__ */

#ifdef __sgi
 /*
  * Remove the fake IRIX lpsched lock file, but only if the existing
  * file is not a FIFO which indicates that the real IRIX lpsched is
  * running...
  */

  if (!stat("/var/spool/lp/FIFO", &statbuf))
    if (!S_ISFIFO(statbuf.st_mode))
      unlink("/var/spool/lp/SCHEDLOCK");
#endif /* __sgi */

  cupsdStopSelect();

  return (!stop_scheduler);
}
Ejemplo n.º 15
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line args */
     char *argv[])			/* I - Command-line arguments */
{
  int			i;		/* Looping var */
  char			*opt;		/* Option character */
  int			fg;		/* Run in the foreground */
  int			fds;		/* Number of ready descriptors */
  cupsd_client_t	*con;		/* Current client */
  cupsd_job_t		*job;		/* Current job */
  cupsd_listener_t	*lis;		/* Current listener */
  time_t		current_time,	/* Current time */
			activity,	/* Client activity timer */
			senddoc_time,	/* Send-Document time */
			expire_time,	/* Subscription expire time */
			report_time,	/* Malloc/client/job report time */
			event_time;	/* Last event notification time */
  long			timeout;	/* Timeout for cupsdDoSelect() */
  struct rlimit		limit;		/* Runtime limit */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
  struct sigaction	action;		/* Actions for POSIX signals */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
#ifdef __sgi
  cups_file_t		*fp;		/* Fake lpsched lock file */
  struct stat		statbuf;	/* Needed for checking lpsched FIFO */
#endif /* __sgi */
  int			run_as_child = 0;
					/* Needed for background fork/exec */
#ifdef __APPLE__
  int			use_sysman = !getuid();
					/* Use system management functions? */
#else
  time_t		netif_time = 0;	/* Time since last network update */
#endif /* __APPLE__ */
#if HAVE_LAUNCHD
  int			launchd_idle_exit;
					/* Idle exit on select timeout? */
#endif	/* HAVE_LAUNCHD */


#ifdef HAVE_GETEUID
 /*
  * Check for setuid invocation, which we do not support!
  */

  if (getuid() != geteuid())
  {
    fputs("cupsd: Cannot run as a setuid program\n", stderr);
    return (1);
  }
#endif /* HAVE_GETEUID */

 /*
  * Check for command-line arguments...
  */

  fg = 0;

#ifdef HAVE_LAUNCHD
  if (getenv("CUPSD_LAUNCHD"))
  {
    Launchd = 1;
    fg      = 1;
  }
#endif /* HAVE_LAUNCHD */

  for (i = 1; i < argc; i ++)
    if (argv[i][0] == '-')
      for (opt = argv[i] + 1; *opt != '\0'; opt ++)
        switch (*opt)
	{
	  case 'C' : /* Run as child with config file */
              run_as_child = 1;
	      fg           = -1;

	  case 'c' : /* Configuration file */
	      i ++;
	      if (i >= argc)
	      {
	        _cupsLangPuts(stderr, _("cupsd: Expected config filename "
		                        "after \"-c\" option."));
	        usage(1);
	      }

              if (argv[i][0] == '/')
	      {
	       /*
	        * Absolute directory...
		*/

		cupsdSetString(&ConfigurationFile, argv[i]);
              }
	      else
	      {
	       /*
	        * Relative directory...
		*/

                char *current;		/* Current directory */


	       /*
	        * Allocate a buffer for the current working directory to
		* reduce run-time stack usage; this approximates the
		* behavior of some implementations of getcwd() when they
		* are passed a NULL pointer.
	        */

                if ((current = malloc(1024)) == NULL)
		{
		  _cupsLangPuts(stderr,
		                _("cupsd: Unable to get current directory."));
                  return (1);
		}

		if (!getcwd(current, 1024))
		{
		  _cupsLangPuts(stderr,
		                _("cupsd: Unable to get current directory."));
                  free(current);
		  return (1);
		}

		cupsdSetStringf(&ConfigurationFile, "%s/%s", current, argv[i]);
		free(current);
              }
	      break;

          case 'f' : /* Run in foreground... */
	      fg = 1;
	      break;

          case 'F' : /* Run in foreground, but disconnect from terminal... */
	      fg = -1;
	      break;

          case 'h' : /* Show usage/help */
	      usage(0);
	      break;

          case 'l' : /* Started by launchd... */
#ifdef HAVE_LAUNCHD
	      Launchd = 1;
	      fg      = 1;
#else
	      _cupsLangPuts(stderr, _("cupsd: launchd(8) support not compiled "
	                              "in, running in normal mode."));
              fg = 0;
#endif /* HAVE_LAUNCHD */
	      break;

          case 'p' : /* Stop immediately for profiling */
              fputs("cupsd: -p (startup profiling) is for internal testing "
                    "use only!\n", stderr);
	      stop_scheduler = 1;
	      fg             = 1;
	      break;

          case 'P' : /* Disable security profiles */
              fputs("cupsd: -P (disable security profiles) is for internal "
                    "testing use only!\n", stderr);
	      UseProfiles = 0;
	      break;

#ifdef __APPLE__
          case 'S' : /* Disable system management functions */
              fputs("cupsd: -S (disable system management) for internal "
                    "testing use only!\n", stderr);
	      use_sysman = 0;
	      break;
#endif /* __APPLE__ */

          case 't' : /* Test the cupsd.conf file... */
	      TestConfigFile = 1;
	      fg             = 1;
	      break;

	  default : /* Unknown option */
              _cupsLangPrintf(stderr, _("cupsd: Unknown option \"%c\" - "
	                                "aborting."), *opt);
	      usage(1);
	      break;
	}
    else
    {
      _cupsLangPrintf(stderr, _("cupsd: Unknown argument \"%s\" - aborting."),
                      argv[i]);
      usage(1);
    }

  if (!ConfigurationFile)
    cupsdSetString(&ConfigurationFile, CUPS_SERVERROOT "/cupsd.conf");

 /*
  * If the user hasn't specified "-f", run in the background...
  */

  if (!fg)
  {
   /*
    * Setup signal handlers for the parent...
    */

#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
    sigset(SIGUSR1, parent_handler);
    sigset(SIGCHLD, parent_handler);

    sigset(SIGHUP, SIG_IGN);
#elif defined(HAVE_SIGACTION)
    memset(&action, 0, sizeof(action));
    sigemptyset(&action.sa_mask);
    sigaddset(&action.sa_mask, SIGUSR1);
    action.sa_handler = parent_handler;
    sigaction(SIGUSR1, &action, NULL);
    sigaction(SIGCHLD, &action, NULL);

    sigemptyset(&action.sa_mask);
    action.sa_handler = SIG_IGN;
    sigaction(SIGHUP, &action, NULL);
#else
    signal(SIGUSR1, parent_handler);
    signal(SIGCLD, parent_handler);

    signal(SIGHUP, SIG_IGN);
#endif /* HAVE_SIGSET */

    if (fork() > 0)
    {
     /*
      * OK, wait for the child to startup and send us SIGUSR1 or to crash
      * and the OS send us SIGCHLD...  We also need to ignore SIGHUP which
      * might be sent by the init script to restart the scheduler...
      */

      for (; parent_signal == 0;)
        sleep(1);

      if (parent_signal == SIGUSR1)
        return (0);

      if (wait(&i) < 0)
      {
        perror("cupsd");
	return (1);
      }
      else if (WIFEXITED(i))
      {
        fprintf(stderr, "cupsd: Child exited with status %d\n",
	        WEXITSTATUS(i));
	return (2);
      }
      else
      {
        fprintf(stderr, "cupsd: Child exited on signal %d\n", WTERMSIG(i));
	return (3);
      }
    }

#ifdef __OpenBSD__
   /*
    * Call _thread_sys_closefrom() so the child process doesn't reset the
    * parent's file descriptors to be blocking.  This is a workaround for a
    * limitation of userland libpthread on OpenBSD.
    */

    _thread_sys_closefrom(0);
#endif /* __OpenBSD__ */

   /*
    * Since CoreFoundation and DBUS both create fork-unsafe data on execution of
    * a program, and since this kind of really unfriendly behavior seems to be
    * more common these days in system libraries, we need to re-execute the
    * background cupsd with the "-C" option to avoid problems.  Unfortunately,
    * we also have to assume that argv[0] contains the name of the cupsd
    * executable - there is no portable way to get the real pathname...
    */

    execlp(argv[0], argv[0], "-C", ConfigurationFile, (char *)0);
    exit(errno);
  }

  if (fg < 1)
  {
   /*
    * Make sure we aren't tying up any filesystems...
    */

    chdir("/");

#ifndef DEBUG
   /*
    * Disable core dumps...
    */

    getrlimit(RLIMIT_CORE, &limit);
    limit.rlim_cur = 0;
    setrlimit(RLIMIT_CORE, &limit);

   /*
    * Disconnect from the controlling terminal...
    */

    setsid();

   /*
    * Close all open files...
    */

    getrlimit(RLIMIT_NOFILE, &limit);

    for (i = 0; i < limit.rlim_cur && i < 1024; i ++)
      close(i);

   /*
    * Redirect stdin/out/err to /dev/null...
    */

    if ((i = open("/dev/null", O_RDONLY)) != 0)
    {
      dup2(i, 0);
      close(i);
    }

    if ((i = open("/dev/null", O_WRONLY)) != 1)
    {
      dup2(i, 1);
      close(i);
    }

    if ((i = open("/dev/null", O_WRONLY)) != 2)
    {
      dup2(i, 2);
      close(i);
    }
#endif /* DEBUG */
  }

 /*
  * Set the timezone info...
  */

  tzset();

#ifdef LC_TIME
  setlocale(LC_TIME, "");
#endif /* LC_TIME */

 /*
  * Set the maximum number of files...
  */

  getrlimit(RLIMIT_NOFILE, &limit);

#if !defined(HAVE_POLL) && !defined(HAVE_EPOLL) && !defined(HAVE_KQUEUE)
  if (limit.rlim_max > FD_SETSIZE)
    MaxFDs = FD_SETSIZE;
  else
#endif /* !HAVE_POLL && !HAVE_EPOLL && !HAVE_KQUEUE */
#ifdef RLIM_INFINITY
  if (limit.rlim_max == RLIM_INFINITY)
    MaxFDs = 16384;
  else
#endif /* RLIM_INFINITY */
    MaxFDs = limit.rlim_max;

  limit.rlim_cur = MaxFDs;

  setrlimit(RLIMIT_NOFILE, &limit);

  cupsdStartSelect();

 /*
  * Read configuration...
  */

  if (!cupsdReadConfiguration())
  {
    if (TestConfigFile)
      printf("%s contains errors\n", ConfigurationFile);
    else
      syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting!",
	     ConfigurationFile);
    return (1);
  }
  else if (TestConfigFile)
  {
    printf("%s is OK\n", ConfigurationFile);
    return (0);
  }

 /*
  * Clean out old temp files and printer cache data.
  */

  if (!strncmp(TempDir, RequestRoot, strlen(RequestRoot)))
    cupsdCleanFiles(TempDir, NULL);

  cupsdCleanFiles(CacheDir, "*.ipp");

#if HAVE_LAUNCHD
  if (Launchd)
  {
   /*
    * If we were started by launchd get the listen sockets file descriptors...
    */

    launchd_checkin();
    launchd_checkout();
  }
#endif /* HAVE_LAUNCHD */

 /*
  * Startup the server...
  */

  httpInitialize();

  cupsdStartServer();

 /*
  * Catch hangup and child signals and ignore broken pipes...
  */

#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
  sigset(SIGCHLD, sigchld_handler);
  sigset(SIGHUP, sighup_handler);
  sigset(SIGPIPE, SIG_IGN);
  sigset(SIGTERM, sigterm_handler);
#elif defined(HAVE_SIGACTION)
  memset(&action, 0, sizeof(action));

  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGTERM);
  sigaddset(&action.sa_mask, SIGCHLD);
  action.sa_handler = sigchld_handler;
  sigaction(SIGCHLD, &action, NULL);

  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGHUP);
  action.sa_handler = sighup_handler;
  sigaction(SIGHUP, &action, NULL);

  sigemptyset(&action.sa_mask);
  action.sa_handler = SIG_IGN;
  sigaction(SIGPIPE, &action, NULL);

  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGTERM);
  sigaddset(&action.sa_mask, SIGCHLD);
  action.sa_handler = sigterm_handler;
  sigaction(SIGTERM, &action, NULL);
#else
  signal(SIGCLD, sigchld_handler);	/* No, SIGCLD isn't a typo... */
  signal(SIGHUP, sighup_handler);
  signal(SIGPIPE, SIG_IGN);
  signal(SIGTERM, sigterm_handler);
#endif /* HAVE_SIGSET */

#ifdef __sgi
 /*
  * Try to create a fake lpsched lock file if one is not already there.
  * Some Adobe applications need it under IRIX in order to enable
  * printing...
  */

  if ((fp = cupsFileOpen("/var/spool/lp/SCHEDLOCK", "w")) == NULL)
  {
    syslog(LOG_LPR, "Unable to create fake lpsched lock file "
                    "\"/var/spool/lp/SCHEDLOCK\"\' - %s!",
           strerror(errno));
  }
  else
  {
    fchmod(cupsFileNumber(fp), 0644);
    fchown(cupsFileNumber(fp), User, Group);

    cupsFileClose(fp);
  }
#endif /* __sgi */

 /*
  * Initialize authentication certificates...
  */

  cupsdInitCerts();

 /*
  * If we are running in the background, signal the parent process that
  * we are up and running...
  */

  if (!fg || run_as_child)
  {
   /*
    * Send a signal to the parent process, but only if the parent is
    * not PID 1 (init).  This avoids accidentally shutting down the
    * system on OpenBSD if you CTRL-C the server before it is up...
    */

    i = getppid();	/* Save parent PID to avoid race condition */

    if (i != 1)
      kill(i, SIGUSR1);
  }

#ifdef __APPLE__
 /*
  * Start power management framework...
  */

  if (use_sysman)
    cupsdStartSystemMonitor();
#endif /* __APPLE__ */

 /*
  * Send server-started event...
  */

#ifdef HAVE_LAUNCHD
  if (Launchd)
    cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL,
                  "Scheduler started via launchd.");
  else
#endif /* HAVE_LAUNCHD */
  if (fg)
    cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL,
                  "Scheduler started in foreground.");
  else
    cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL,
                  "Scheduler started in background.");

 /*
  * Start any pending print jobs...
  */

  cupsdCheckJobs();

 /*
  * Loop forever...
  */

  current_time  = time(NULL);
  event_time    = current_time;
  expire_time   = current_time;
  fds           = 1;
  report_time   = 0;
  senddoc_time  = current_time;

  while (!stop_scheduler)
  {
   /*
    * Check if there are dead children to handle...
    */

    if (dead_children)
      process_children();

   /*
    * Check if we need to load the server configuration file...
    */

    if (NeedReload)
    {
     /*
      * Close any idle clients...
      */

      if (cupsArrayCount(Clients) > 0)
      {
	for (con = (cupsd_client_t *)cupsArrayFirst(Clients);
	     con;
	     con = (cupsd_client_t *)cupsArrayNext(Clients))
	  if (con->http.state == HTTP_WAITING)
	    cupsdCloseClient(con);
	  else
	    con->http.keep_alive = HTTP_KEEPALIVE_OFF;

        cupsdPauseListening();
      }

     /*
      * Restart if all clients are closed and all jobs finished, or
      * if the reload timeout has elapsed...
      */

      if ((cupsArrayCount(Clients) == 0 &&
           (cupsArrayCount(PrintingJobs) == 0 || NeedReload != RELOAD_ALL)) ||
          (time(NULL) - ReloadTime) >= ReloadTimeout)
      {
       /*
	* Shutdown the server...
	*/

        DoingShutdown = 1;

	cupsdStopServer();

       /*
	* Read configuration...
	*/

        if (!cupsdReadConfiguration())
        {
          syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting!",
		 ConfigurationFile);
          break;
	}

#if HAVE_LAUNCHD
	if (Launchd)
	{
	 /*
	  * If we were started by launchd, get the listen socket file
	  * descriptors...
	  */

	  launchd_checkin();
	  launchd_checkout();
	}
#endif /* HAVE_LAUNCHD */

       /*
        * Startup the server...
        */

        DoingShutdown = 0;

        cupsdStartServer();

       /*
        * Send a server-restarted event...
	*/

        cupsdAddEvent(CUPSD_EVENT_SERVER_RESTARTED, NULL, NULL,
                      "Scheduler restarted.");
      }
    }

   /*
    * Check for available input or ready output.  If cupsdDoSelect()
    * returns 0 or -1, something bad happened and we should exit
    * immediately.
    *
    * Note that we at least have one listening socket open at all
    * times.
    */

    if ((timeout = select_timeout(fds)) > 1 && LastEvent)
      timeout = 1;

#if HAVE_LAUNCHD
   /*
    * If no other work is scheduled and we're being controlled by
    * launchd then timeout after 'LaunchdTimeout' seconds of
    * inactivity...
    */

    if (timeout == 86400 && Launchd && LaunchdTimeout &&
        !cupsArrayCount(ActiveJobs) &&
	(!Browsing || !BrowseLocalProtocols || !cupsArrayCount(Printers)))
    {
      timeout		= LaunchdTimeout;
      launchd_idle_exit = 1;
    }
    else
      launchd_idle_exit = 0;
#endif	/* HAVE_LAUNCHD */

    if ((fds = cupsdDoSelect(timeout)) < 0)
    {
     /*
      * Got an error from select!
      */

#ifdef HAVE_DNSSD
      cupsd_printer_t	*p;		/* Current printer */
#endif /* HAVE_DNSSD */


      if (errno == EINTR)		/* Just interrupted by a signal */
        continue;

     /*
      * Log all sorts of debug info to help track down the problem.
      */

      cupsdLogMessage(CUPSD_LOG_EMERG, "cupsdDoSelect() failed - %s!",
                      strerror(errno));

      for (i = 0, con = (cupsd_client_t *)cupsArrayFirst(Clients);
	   con;
	   i ++, con = (cupsd_client_t *)cupsArrayNext(Clients))
        cupsdLogMessage(CUPSD_LOG_EMERG,
	                "Clients[%d] = %d, file = %d, state = %d",
	                i, con->http.fd, con->file, con->http.state);

      for (i = 0, lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
           lis;
	   i ++, lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
        cupsdLogMessage(CUPSD_LOG_EMERG, "Listeners[%d] = %d", i, lis->fd);

      cupsdLogMessage(CUPSD_LOG_EMERG, "CGIPipes[0] = %d", CGIPipes[0]);

#ifdef __APPLE__
      cupsdLogMessage(CUPSD_LOG_EMERG, "SysEventPipes[0] = %d",
                      SysEventPipes[0]);
#endif /* __APPLE__ */

      for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs);
	   job;
	   job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
        cupsdLogMessage(CUPSD_LOG_EMERG, "Jobs[%d] = %d < [%d %d] > [%d %d]",
	        	job->id,
			job->status_buffer ? job->status_buffer->fd : -1,
			job->print_pipes[0], job->print_pipes[1],
			job->back_pipes[0], job->back_pipes[1]);

#ifdef HAVE_DNSSD
      for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
	   p;
	   p = (cupsd_printer_t *)cupsArrayNext(Printers))
        cupsdLogMessage(CUPSD_LOG_EMERG, "printer[%s] reg_name=\"%s\"", p->name,
	                p->reg_name ? p->reg_name : "(null)");
#endif /* HAVE_DNSSD */

      break;
    }

    current_time = time(NULL);

   /*
    * Write dirty config/state files...
    */

    if (DirtyCleanTime && current_time >= DirtyCleanTime)
      cupsdCleanDirty();

#ifdef __APPLE__
   /*
    * If we are going to sleep and still have pending jobs, stop them after
    * a period of time...
    */

    if (SleepJobs > 0 && current_time >= SleepJobs &&
        cupsArrayCount(PrintingJobs) > 0)
    {
      SleepJobs = 0;
      cupsdStopAllJobs(CUPSD_JOB_DEFAULT, 5);
    }
#endif /* __APPLE__ */

#ifndef __APPLE__
   /*
    * Update the network interfaces once a minute...
    */

    if ((current_time - netif_time) >= 60)
    {
      netif_time  = current_time;
      NetIFUpdate = 1;
    }
#endif /* !__APPLE__ */

#if HAVE_LAUNCHD
   /*
    * If no other work was scheduled and we're being controlled by launchd
    * then timeout after 'LaunchdTimeout' seconds of inactivity...
    */

    if (!fds && launchd_idle_exit)
    {
      cupsdLogMessage(CUPSD_LOG_INFO,
                      "Printer sharing is off and there are no jobs pending, "
		      "will restart on demand.");
      stop_scheduler = 1;
      break;
    }
#endif /* HAVE_LAUNCHD */

   /*
    * Resume listening for new connections as needed...
    */

    if (ListeningPaused && ListeningPaused <= current_time &&
        cupsArrayCount(Clients) < MaxClients)
      cupsdResumeListening();

   /*
    * Expire subscriptions and unload completed jobs as needed...
    */

    if (current_time > expire_time)
    {
      if (cupsArrayCount(Subscriptions) > 0)
        cupsdExpireSubscriptions(NULL, NULL);

      cupsdUnloadCompletedJobs();

      expire_time = current_time;
    }

#ifndef HAVE_AUTHORIZATION_H
   /*
    * Update the root certificate once every 5 minutes if we have client
    * connections...
    */

    if ((current_time - RootCertTime) >= RootCertDuration && RootCertDuration &&
        !RunUser && cupsArrayCount(Clients))
    {
     /*
      * Update the root certificate...
      */

      cupsdDeleteCert(0);
      cupsdAddCert(0, "root", NULL);
    }
#endif /* !HAVE_AUTHORIZATION_H */

   /*
    * Check for new data on the client sockets...
    */

    for (con = (cupsd_client_t *)cupsArrayFirst(Clients);
	 con;
	 con = (cupsd_client_t *)cupsArrayNext(Clients))
    {
     /*
      * Process pending data in the input buffer...
      */

      if (con->http.used)
      {
        cupsdReadClient(con);
	continue;
      }

     /*
      * Check the activity and close old clients...
      */

      activity = current_time - Timeout;
      if (con->http.activity < activity && !con->pipe_pid)
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG,
	                "Closing client %d after %d seconds of inactivity...",
	                con->http.fd, Timeout);

        cupsdCloseClient(con);
        continue;
      }
    }

   /*
    * Update any pending multi-file documents...
    */

    if ((current_time - senddoc_time) >= 10)
    {
      cupsdCheckJobs();
      senddoc_time = current_time;
    }

   /*
    * Clean job history...
    */

    if (JobHistoryUpdate && current_time >= JobHistoryUpdate)
      cupsdCleanJobs();

   /*
    * Log statistics at most once a minute when in debug mode...
    */

    if ((current_time - report_time) >= 60 && LogLevel >= CUPSD_LOG_DEBUG)
    {
      size_t		string_count,	/* String count */
			alloc_bytes,	/* Allocated string bytes */
			total_bytes;	/* Total string bytes */
#ifdef HAVE_MALLINFO
      struct mallinfo	mem;		/* Malloc information */


      mem = mallinfo();
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: malloc-arena=%lu", mem.arena);
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: malloc-used=%lu",
                      mem.usmblks + mem.uordblks);
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: malloc-free=%lu",
		      mem.fsmblks + mem.fordblks);
#endif /* HAVE_MALLINFO */

      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: clients=%d",
                      cupsArrayCount(Clients));
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: jobs=%d",
                      cupsArrayCount(Jobs));
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: jobs-active=%d",
                      cupsArrayCount(ActiveJobs));
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: printers=%d",
                      cupsArrayCount(Printers));

      string_count = _cupsStrStatistics(&alloc_bytes, &total_bytes);
      cupsdLogMessage(CUPSD_LOG_DEBUG,
                      "Report: stringpool-string-count=" CUPS_LLFMT,
		      CUPS_LLCAST string_count);
      cupsdLogMessage(CUPSD_LOG_DEBUG,
                      "Report: stringpool-alloc-bytes=" CUPS_LLFMT,
		      CUPS_LLCAST alloc_bytes);
      cupsdLogMessage(CUPSD_LOG_DEBUG,
                      "Report: stringpool-total-bytes=" CUPS_LLFMT,
		      CUPS_LLCAST total_bytes);

      report_time = current_time;
    }

   /*
    * Handle OS-specific event notification for any events that have
    * accumulated.  Don't send these more than once a second...
    */

    if (LastEvent && (current_time - event_time) >= 1)
    {
#ifdef HAVE_NOTIFY_POST
      if (LastEvent & (CUPSD_EVENT_PRINTER_ADDED |
                       CUPSD_EVENT_PRINTER_DELETED |
                       CUPSD_EVENT_PRINTER_MODIFIED))
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG2,
	                "notify_post(\"com.apple.printerListChange\")");
	notify_post("com.apple.printerListChange");
      }

      if (LastEvent & CUPSD_EVENT_PRINTER_STATE_CHANGED)
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG2,
	                "notify_post(\"com.apple.printerHistoryChange\")");
	notify_post("com.apple.printerHistoryChange");
      }

      if (LastEvent & (CUPSD_EVENT_JOB_STATE_CHANGED |
                       CUPSD_EVENT_JOB_CONFIG_CHANGED |
                       CUPSD_EVENT_JOB_PROGRESS))
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG2,
	                "notify_post(\"com.apple.jobChange\")");
	notify_post("com.apple.jobChange");
      }
#endif /* HAVE_NOTIFY_POST */

     /*
      * Reset the accumulated events...
      */

      LastEvent  = CUPSD_EVENT_NONE;
      event_time = current_time;
    }
  }

 /*
  * Log a message based on what happened...
  */

  if (stop_scheduler)
  {
    cupsdLogMessage(CUPSD_LOG_INFO, "Scheduler shutting down normally.");
    cupsdAddEvent(CUPSD_EVENT_SERVER_STOPPED, NULL, NULL,
                  "Scheduler shutting down normally.");
  }
  else
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "Scheduler shutting down due to program error.");
    cupsdAddEvent(CUPSD_EVENT_SERVER_STOPPED, NULL, NULL,
                  "Scheduler shutting down due to program error.");
  }

 /*
  * Close all network clients...
  */

  DoingShutdown = 1;

  cupsdStopServer();

#ifdef HAVE_LAUNCHD
 /*
  * Update the launchd KeepAlive file as needed...
  */

  if (Launchd)
    launchd_checkout();
#endif /* HAVE_LAUNCHD */

 /*
  * Stop all jobs...
  */

  cupsdFreeAllJobs();

#ifdef __APPLE__
 /*
  * Stop monitoring system event monitoring...
  */

  if (use_sysman)
    cupsdStopSystemMonitor();
#endif /* __APPLE__ */

#ifdef HAVE_GSSAPI
 /*
  * Free the scheduler's Kerberos context...
  */

#  ifdef __APPLE__
 /*
  * If the weak-linked GSSAPI/Kerberos library is not present, don't try
  * to use it...
  */

  if (krb5_init_context != NULL)
#  endif /* __APPLE__ */
  if (KerberosContext)
    krb5_free_context(KerberosContext);
#endif /* HAVE_GSSAPI */

#ifdef __sgi
 /*
  * Remove the fake IRIX lpsched lock file, but only if the existing
  * file is not a FIFO which indicates that the real IRIX lpsched is
  * running...
  */

  if (!stat("/var/spool/lp/FIFO", &statbuf))
    if (!S_ISFIFO(statbuf.st_mode))
      unlink("/var/spool/lp/SCHEDLOCK");
#endif /* __sgi */

  cupsdStopSelect();

  return (!stop_scheduler);
}
Ejemplo n.º 16
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments (6 or 7) */
     char *argv[])			/* I - Command-line arguments */
{
  int		ipv4,			/* SNMP IPv4 socket */
		ipv6;			/* SNMP IPv6 socket */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
  struct sigaction action;		/* Actions for POSIX signals */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */


 /*
  * Check command-line options...
  */

  if (argc > 2)
  {
    _cupsLangPuts(stderr, _("Usage: snmp [host-or-ip-address]"));
    return (1);
  }

 /*
  * Set the password callback for IPP operations...
  */

  cupsSetPasswordCB(password_cb);

 /*
  * Catch SIGALRM signals...
  */

#ifdef HAVE_SIGSET
  sigset(SIGALRM, alarm_handler);
#elif defined(HAVE_SIGACTION)
  memset(&action, 0, sizeof(action));

  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGALRM);
  action.sa_handler = alarm_handler;
  sigaction(SIGALRM, &action, NULL);
#else
  signal(SIGALRM, alarm_handler);
#endif /* HAVE_SIGSET */

 /*
  * Open the SNMP socket...
  */

  if ((ipv4 = _cupsSNMPOpen(AF_INET)) < 0)
    return (1);

#ifdef AF_INET6
  if ((ipv6 = _cupsSNMPOpen(AF_INET6)) < 0)
    perror("DEBUG: Unable to create IPv6 socket");
#else
  ipv6 = -1;
#endif /* AF_INET6 */

 /*
  * Read the configuration file and any cache data...
  */

  read_snmp_conf(argv[1]);

  _cupsSNMPSetDebug(DebugLevel);

  Devices = cupsArrayNew((cups_array_func_t)compare_cache, NULL);

 /*
  * Scan for devices...
  */

  scan_devices(ipv4, ipv6);

 /*
  * Close, free, and return with no errors...
  */

  _cupsSNMPClose(ipv4);
  if (ipv6 >= 0)
    _cupsSNMPClose(ipv6);

  free_array(Addresses);
  free_array(Communities);
  free_cache();

  return (0);
}
Ejemplo n.º 17
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line args */
     char *argv[])			/* I - Command-line arguments */
{
  int		i;			/* Looping vars */
  const char	*command,		/* Command name */
		*opt;			/* Current option */
  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		*infile,		/* File to filter */
		*outfile;		/* File to create */
  char		cupsdconf[1024];	/* cupsd.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		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];

  mime         = NULL;
  srctype      = NULL;
  compression  = 0;
  dsttype      = "application/pdf";
  infile       = NULL;
  outfile      = NULL;
  num_options  = 0;
  options      = NULL;
  ppdfile      = NULL;
  title        = NULL;
  user         = cupsUser();
  removeppd    = 0;
  removeinfile = 0;

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

  snprintf(cupsdconf, sizeof(cupsdconf), "%s/cupsd.conf", server_root);

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

  _cupsSetLocale(argv);

  for (i = 1; i < argc; i ++)
    if (argv[i][0] == '-')
    {
      for (opt = argv[i] + 1; *opt; opt ++)
        switch (*opt)
	{
	  case '-' : /* Next argument is a filename... */
	      i ++;
	      if (i < argc && !infile)
	        infile = argv[i];
	      else
	        usage(command, opt);
	      break;

          case 'a' : /* Specify option... */
	      i ++;
	      if (i < argc)
	        num_options = cupsParseOptions(argv[i], num_options, &options);
	      else
	        usage(command, opt);
	      break;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 /*
  * Load the cupsd.conf file and create the MIME database...
  */

  if (read_cupsd_conf(cupsdconf))
    return (1);

  if ((mime = mimeLoad(ServerRoot, Path)) == NULL)
  {
    _cupsLangPrintf(stderr,
                    _("%s: Unable to read MIME database from \"%s\"!\n"),
		    command, ServerRoot);
    return (1);
  }

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

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

  sscanf(dsttype, "%15[^/]/%255s", super, type);
  if ((dst = mimeType(mime, super, type)) == NULL)
  {
    _cupsLangPrintf(stderr,
                    _("%s: Unknown destination MIME type %s/%s!\n"),
		    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);
  }
  else if ((filters = mimeFilter(mime, src, dst, &cost)) == NULL)
  {
    _cupsLangPrintf(stderr,
                    _("%s: No filter to convert from %s/%s to %s/%s!\n"),
		    command, src->super, src->type, dst->super, dst->type);
    return (1);
  }
  else if (compression)
    cupsArrayInsert(filters, &GZIPFilter);

 /*
  * Do it!
  */

  status = exec_filters(filters, infile, outfile, ppdfile,
                        !strcmp(command, "convert") ? "tofile" : "cupsfilter",
			user, title, num_options, options);

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

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

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

  return (status);
}
Ejemplo n.º 18
0
Archivo: lpc.c Proyecto: lanceit/cups
static void
show_status(http_t     *http,		/* I - HTTP connection to server */
            const char *dests)		/* I - Destinations */
{
  ipp_t		*request,		/* IPP Request */
		*response;		/* IPP Response */
  ipp_attribute_t *attr;		/* Current attribute */
  char		*printer,		/* Printer name */
		*device,		/* Device URI */
                *delimiter;		/* Char search result */
  ipp_pstate_t	pstate;			/* Printer state */
  int		accepting;		/* Is printer accepting jobs? */
  int		jobcount;		/* Count of current jobs */
  const char	*dptr,			/* Pointer into destination list */
		*ptr;			/* Pointer into printer name */
  int		match;			/* Non-zero if this job matches */
  static const char *requested[] =	/* Requested attributes */
		{
		  "device-uri",
		  "printer-is-accepting-jobs",
		  "printer-name",
		  "printer-state",
		  "queued-job-count"
		};


  DEBUG_printf(("show_status(http=%p, dests=\"%s\")\n", http, dests));

  if (http == NULL)
    return;

 /*
  * Build a CUPS_GET_PRINTERS request, which requires the following
  * attributes:
  *
  *    attributes-charset
  *    attributes-natural-language
  */

  request = ippNewRequest(CUPS_GET_PRINTERS);

  ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
                "requested-attributes", sizeof(requested) / sizeof(requested[0]),
		NULL, requested);

 /*
  * Do the request and get back a response...
  */

  if ((response = cupsDoRequest(http, request, "/")) != NULL)
  {
    DEBUG_puts("show_status: request succeeded...");

   /*
    * Loop through the printers returned in the list and display
    * their status...
    */

    for (attr = response->attrs; attr != NULL; attr = attr->next)
    {
     /*
      * Skip leading attributes until we hit a job...
      */

      while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
        attr = attr->next;

      if (attr == NULL)
        break;

     /*
      * Pull the needed attributes from this job...
      */

      printer   = NULL;
      device    = "file:/dev/null";
      pstate    = IPP_PRINTER_IDLE;
      jobcount  = 0;
      accepting = 1;

      while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
      {
        if (!strcmp(attr->name, "device-uri") &&
	    attr->value_tag == IPP_TAG_URI)
	  device = attr->values[0].string.text;
        else if (!strcmp(attr->name, "printer-is-accepting-jobs") &&
	         attr->value_tag == IPP_TAG_BOOLEAN)
	  accepting = attr->values[0].boolean;
        else if (!strcmp(attr->name, "printer-name") &&
	         attr->value_tag == IPP_TAG_NAME)
	  printer = attr->values[0].string.text;
        else if (!strcmp(attr->name, "printer-state") &&
	         attr->value_tag == IPP_TAG_ENUM)
	  pstate = (ipp_pstate_t)attr->values[0].integer;
        else if (!strcmp(attr->name, "queued-job-count") &&
	         attr->value_tag == IPP_TAG_INTEGER)
	  jobcount = attr->values[0].integer;

        attr = attr->next;
      }

     /*
      * See if we have everything needed...
      */

      if (printer == NULL)
      {
        if (attr == NULL)
	  break;
	else
          continue;
      }

     /*
      * A single 'all' printer name is special, meaning all printers.
      */

      if (dests != NULL && !strcmp(dests, "all"))
        dests = NULL;

     /*
      * See if this is a printer we're interested in...
      */

      match = dests == NULL;

      if (dests != NULL)
      {
        for (dptr = dests; *dptr != '\0';)
	{
	 /*
	  * Skip leading whitespace and commas...
	  */

	  while (isspace(*dptr & 255) || *dptr == ',')
	    dptr ++;

	  if (*dptr == '\0')
	    break;

         /*
	  * Compare names...
	  */

	  for (ptr = printer;
	       *ptr != '\0' && *dptr != '\0' && *ptr == *dptr;
	       ptr ++, dptr ++)
	    /* do nothing */;

          if (*ptr == '\0' && (*dptr == '\0' || *dptr == ',' ||
	                       isspace(*dptr & 255)))
	  {
	    match = 1;
	    break;
	  }

         /*
	  * Skip trailing junk...
	  */

          while (!isspace(*dptr & 255) && *dptr != '\0')
	    dptr ++;
	  while (isspace(*dptr & 255) || *dptr == ',')
	    dptr ++;

	  if (*dptr == '\0')
	    break;
        }
      }

     /*
      * Display the printer entry if needed...
      */

      if (match)
      {
       /*
        * Display it...
	*/

        printf("%s:\n", printer);
	if (!strncmp(device, "file:", 5))
	  _cupsLangPrintf(stdout,
	                  _("\tprinter is on device \'%s\' speed -1"),
			  device + 5);
	else
	{
	 /*
	  * Just show the scheme...
	  */

	  if ((delimiter = strchr(device, ':')) != NULL )
	  {
	    *delimiter = '\0';
	    _cupsLangPrintf(stdout,
	                    _("\tprinter is on device \'%s\' speed -1"),
			    device);
	  }
	}

        if (accepting)
	  _cupsLangPuts(stdout, _("\tqueuing is enabled"));
	else
	  _cupsLangPuts(stdout, _("\tqueuing is disabled"));

        if (pstate != IPP_PRINTER_STOPPED)
	  _cupsLangPuts(stdout, _("\tprinting is enabled"));
	else
	  _cupsLangPuts(stdout, _("\tprinting is disabled"));

	if (jobcount == 0)
	  _cupsLangPuts(stdout, _("\tno entries"));
	else
	  _cupsLangPrintf(stdout, _("\t%d entries"), jobcount);

	_cupsLangPuts(stdout, _("\tdaemon present"));
      }

      if (attr == NULL)
        break;
    }

    ippDelete(response);
  }
}
Ejemplo n.º 19
0
static int				/* O - 0 on success, 1 on failure */
check_file(const char *filename)	/* I - File to read from */
{
  int		i;			/* Looping var */
  cups_file_t	*fp;			/* File */
  char		line[1024];		/* Line from file */
  int		ch;			/* Current character */
  size_t	bytes;			/* Length of line */
  int		status;			/* Status of test */
  int		linenum;		/* Line number */
  int		binary;			/* File contains binary data? */
  float		version;		/* DSC version */
  int		lbrt[4];		/* Bounding box */
  char		page_label[256];	/* Page label string */
  int		page_number;		/* Page number */
  int		last_page_number;	/* Last page number seen */
  int		level;			/* Embedded document level */
  int		saw_bounding_box,	/* %%BoundingBox seen? */
		saw_pages,		/* %%Pages seen? */
		saw_end_comments,	/* %%EndComments seen? */
		saw_begin_prolog,	/* %%BeginProlog seen? */
		saw_end_prolog,		/* %%EndProlog seen? */
		saw_begin_setup,	/* %%BeginSetup seen? */
		saw_end_setup,		/* %%EndSetup seen? */
		saw_page,		/* %%Page seen? */
		saw_trailer,		/* %%Trailer seen? */
		saw_long_line;		/* Saw long lines? */


 /*
  * Open the file...
  */

  if (!strcmp(filename, "(stdin)"))
    fp = cupsFileStdin();
  else
    fp = cupsFileOpen(filename, "r");

  if (!fp)
  {
    perror(filename);
    return (1);
  }

 /*
  * Scan the file...
  */

  binary           = 0;
  last_page_number = 0;
  level            = 0;
  linenum          = 0;
  saw_begin_prolog = 0;
  saw_begin_setup  = 0;
  saw_bounding_box = 0;
  saw_end_comments = 0;
  saw_end_prolog   = 0;
  saw_end_setup    = 0;
  saw_long_line    = 0;
  saw_page         = 0;
  saw_pages        = 0;
  saw_trailer      = 0;
  status           = 0;
  version          = 0.0f;

  /* TODO: Fixme */
  printf("%s: ", filename);
  fflush(stdout);

  while ((bytes = cupsFileGetLine(fp, line, sizeof(line))) > 0)
  {
    linenum ++;

    if (bytes > 255)
    {
      if (!saw_long_line)
      {
	if (!status)
          _cupsLangPuts(stdout, _("FAIL"));

	status ++;
	_cupsLangPrintf(stdout,
                	_("    Line %d is longer than 255 characters (%d).\n"
		          "        REF: Page 25, Line Length"),
			linenum, (int)bytes);
      }

      saw_long_line ++;
    }

    if (linenum == 1)
    {
      if (strncmp(line, "%!PS-Adobe-", 11))
      {
	if (!status)
          _cupsLangPuts(stdout, _("FAIL"));

	_cupsLangPuts(stdout,
	              _("    Missing %!PS-Adobe-3.0 on first line.\n"
		        "        REF: Page 17, 3.1 Conforming Documents"));
	cupsFileClose(fp);
	return (1);
      }
      else
        version = atof(line + 11);
    }
    else if (level > 0)
    {
      if (!strncmp(line, "%%BeginDocument:", 16))
        level ++;
      else if (!strncmp(line, "%%EndDocument", 13))
        level --;
    }
    else if (saw_trailer)
    {
      if (!strncmp(line, "%%Pages:", 8))
      {
        if (atoi(line + 8) <= 0)
	{
	  if (!status)
            _cupsLangPuts(stdout, _("FAIL"));

	  status ++;
	  _cupsLangPrintf(stdout,
	                  _("    Bad %%%%Pages: on line %d.\n"
		            "        REF: Page 43, %%%%Pages:"),
			  linenum);
	}
	else
          saw_pages = 1;
      }
      else if (!strncmp(line, "%%BoundingBox:", 14))
      {
	if (sscanf(line + 14, "%d%d%d%d", lbrt + 0, lbrt + 1, lbrt + 2,
	           lbrt + 3) != 4)
        {
	  if (!status)
            _cupsLangPuts(stdout, _("FAIL"));

	  status ++;
	  _cupsLangPrintf(stdout, _("    Bad %%%%BoundingBox: on line %d.\n"
		        	    "        REF: Page 39, %%%%BoundingBox:"),
			  linenum);
	}
	else
          saw_bounding_box = 1;
      }
    }
    else if (!saw_end_comments)
    {
      if (!strncmp(line, "%%EndComments", 13))
        saw_end_comments = 1;
      else if (line[0] != '%')
        saw_end_comments = -1;
      else if (!strncmp(line, "%%Pages:", 8))
      {
        if (strstr(line + 8, "(atend)"))
	  saw_pages = -1;
	else if (atoi(line + 8) <= 0)
	{
	  if (!status)
            _cupsLangPuts(stdout, _("FAIL"));

	  status ++;
	  _cupsLangPrintf(stdout, _("    Bad %%%%Pages: on line %d.\n"
		        	    "        REF: Page 43, %%%%Pages:"),
			  linenum);
	}
	else
          saw_pages = 1;
      }
      else if (!strncmp(line, "%%BoundingBox:", 14))
      {
        if (strstr(line, "(atend)"))
	  saw_bounding_box = -1;
	else if (sscanf(line + 14, "%d%d%d%d", lbrt + 0, lbrt + 1, lbrt + 2,
	                lbrt + 3) != 4)
        {
	  if (!status)
            _cupsLangPuts(stdout, _("FAIL"));

	  status ++;
	  _cupsLangPrintf(stdout, _("    Bad %%%%BoundingBox: on line %d.\n"
		        	    "        REF: Page 39, %%%%BoundingBox:"),
			  linenum);
	}
	else
          saw_bounding_box = 1;
      }
    }
    else if (saw_begin_prolog && !saw_end_prolog)
    {
      if (!strncmp(line, "%%EndProlog", 11))
        saw_end_prolog = 1;
    }
    else if (saw_begin_setup && !saw_end_setup)
    {
      if (!strncmp(line, "%%EndSetup", 10))
        saw_end_setup = 1;
    }
    else if (saw_end_comments)
    {
      if (!strncmp(line, "%%Page:", 7))
      {
        if (sscanf(line + 7, "%255s%d", page_label, &page_number) != 2 ||
	    page_number != (last_page_number + 1) || page_number < 1)
	{
	  if (!status)
            _cupsLangPuts(stdout, _("FAIL"));

	  status ++;
	  _cupsLangPrintf(stdout, _("    Bad %%%%Page: on line %d.\n"
		        	    "        REF: Page 53, %%%%Page:"),
		          linenum);
	}
	else
	{
	  last_page_number = page_number;
	  saw_page         = 1;
	}
      }
      else if (!strncmp(line, "%%BeginProlog", 13))
        saw_begin_prolog = 1;
      else if (!strncmp(line, "%%BeginSetup", 12))
        saw_begin_setup = 1;
      else if (!strncmp(line, "%%BeginDocument:", 16))
        level ++;
      else if (!strncmp(line, "%%EndDocument", 13))
        level --;
      else if (!strncmp(line, "%%Trailer", 9))
        saw_trailer = 1;
    }

    for (i = 0; !binary && i < bytes; i ++)
    {
      ch = line[i];

      if ((ch < ' ' || (ch & 0x80)) && ch != '\n' && ch != '\r' && ch != '\t')
        binary = 1;
    }
  }

  if (saw_bounding_box <= 0)
  {
    if (!status)
      _cupsLangPuts(stdout, _("FAIL"));

    status ++;
    _cupsLangPuts(stdout, _("    Missing or bad %%BoundingBox: comment.\n"
		            "        REF: Page 39, %%BoundingBox:"));
  }

  if (saw_pages <= 0)
  {
    if (!status)
      _cupsLangPuts(stdout, _("FAIL"));

    status ++;
    _cupsLangPuts(stdout, _("    Missing or bad %%Pages: comment.\n"
		            "        REF: Page 43, %%Pages:"));
  }

  if (!saw_end_comments)
  {
    if (!status)
      _cupsLangPuts(stdout, _("FAIL"));

    status ++;
    _cupsLangPuts(stdout, _("    Missing %%EndComments comment."
		            "        REF: Page 41, %%EndComments"));
  }

  if (!saw_page)
  {
    if (!status)
      _cupsLangPuts(stdout, _("FAIL"));

    status ++;
    _cupsLangPuts(stdout, _("    Missing or bad %%Page: comments.\n"
		            "        REF: Page 53, %%Page:"));
  }

  if (level < 0)
  {
    if (!status)
      _cupsLangPuts(stdout, _("FAIL"));

    status ++;
    _cupsLangPuts(stdout, _("    Too many %%EndDocument comments."));
  }
  else if (level > 0)
  {
    if (!status)
      _cupsLangPuts(stdout, _("FAIL"));

    status ++;
    _cupsLangPuts(stdout, _("    Too many %%BeginDocument comments."));
  }

  if (saw_long_line > 1)
    _cupsLangPrintf(stderr,
                    _("    Saw %d lines that exceeded 255 characters."),
                    saw_long_line);

  if (!status)
    _cupsLangPuts(stdout, _("PASS"));

  if (binary)
    _cupsLangPuts(stdout, _("    Warning: file contains binary data."));

  if (version < 3.0f)
    _cupsLangPrintf(stdout,
                    _("    Warning: obsolete DSC version %.1f in file."),
		    version);

  if (saw_end_comments < 0)
    _cupsLangPuts(stdout, _("    Warning: no %%EndComments comment in file."));

  cupsFileClose(fp);

  return (status);
}
Ejemplo n.º 20
0
static int				/* O - Number of jobs in queue */
show_jobs(const char *command,		/* I - Command name */
          http_t     *http,		/* I - HTTP connection to server */
          const char *dest,		/* I - Destination */
	  const char *user,		/* I - User */
	  const int  id,		/* I - Job ID */
	  const int  longstatus)	/* I - 1 if long report desired */
{
  ipp_t		*request,		/* IPP Request */
		*response;		/* IPP Response */
  ipp_attribute_t *attr;		/* Current attribute */
  const char	*jobdest,		/* Pointer into job-printer-uri */
		*jobuser,		/* Pointer to job-originating-user-name */
		*jobname;		/* Pointer to job-name */
  ipp_jstate_t	jobstate;		/* job-state */
  int		jobid,			/* job-id */
		jobsize,		/* job-k-octets */
#ifdef __osf__
		jobpriority,		/* job-priority */
#endif /* __osf__ */
		jobcount,		/* Number of jobs */
		jobcopies,		/* Number of copies */
		rank;			/* Rank of job */
  char		resource[1024];		/* Resource string */
  char		rankstr[255];		/* Rank string */
  char		namestr[1024];		/* Job name string */
  static const char * const jobattrs[] =/* Job attributes we want to see */
		{
		  "copies",
		  "job-id",
		  "job-k-octets",
		  "job-name",
		  "job-originating-user-name",
		  "job-printer-uri",
		  "job-priority",
		  "job-state"
		};
  static const char * const ranks[10] =	/* Ranking strings */
		{
		  "th",
		  "st",
		  "nd",
		  "rd",
		  "th",
		  "th",
		  "th",
		  "th",
		  "th",
		  "th"
		};


  DEBUG_printf(("show_jobs(http=%p, dest=%p, user=%p, id=%d, longstatus%d)\n",
                http, dest, user, id, longstatus));

  if (http == NULL)
    return (0);

 /*
  * Build an IPP_GET_JOBS or IPP_GET_JOB_ATTRIBUTES request, which requires
  * the following attributes:
  *
  *    attributes-charset
  *    attributes-natural-language
  *    job-uri or printer-uri
  *    requested-attributes
  *    requesting-user-name
  */

  request = ippNewRequest(id ? IPP_GET_JOB_ATTRIBUTES : IPP_GET_JOBS);

  if (id)
  {
    snprintf(resource, sizeof(resource), "ipp://localhost/jobs/%d", id);
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
                 NULL, resource);
  }
  else if (dest)
  {
    httpAssembleURIf(HTTP_URI_CODING_ALL, resource, sizeof(resource), "ipp",
                     NULL, "localhost", 0, "/printers/%s", dest);

    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
                 NULL, resource);
  }
  else
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
                 NULL, "ipp://localhost/");

  if (user)
  {
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
                 "requesting-user-name", NULL, user);
    ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1);
  }
  else
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
                 "requesting-user-name", NULL, cupsUser());

  ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
                "requested-attributes",
                (int)(sizeof(jobattrs) / sizeof(jobattrs[0])), NULL, jobattrs);

 /*
  * Do the request and get back a response...
  */

  jobcount = 0;

  if ((response = cupsDoRequest(http, request, "/")) != NULL)
  {
    if (response->request.status.status_code > IPP_OK_CONFLICT)
    {
      _cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString());
      ippDelete(response);
      return (0);
    }

    rank = 1;

   /*
    * Loop through the job list and display them...
    */

    for (attr = response->attrs; attr != NULL; attr = attr->next)
    {
     /*
      * Skip leading attributes until we hit a job...
      */

      while (attr != NULL && attr->group_tag != IPP_TAG_JOB)
        attr = attr->next;

      if (attr == NULL)
        break;

     /*
      * Pull the needed attributes from this job...
      */

      jobid       = 0;
      jobsize     = 0;
#ifdef __osf__
      jobpriority = 50;
#endif /* __osf__ */
      jobstate    = IPP_JOB_PENDING;
      jobname     = "unknown";
      jobuser     = "******";
      jobdest     = NULL;
      jobcopies   = 1;

      while (attr != NULL && attr->group_tag == IPP_TAG_JOB)
      {
        if (!strcmp(attr->name, "job-id") &&
	    attr->value_tag == IPP_TAG_INTEGER)
	  jobid = attr->values[0].integer;

        if (!strcmp(attr->name, "job-k-octets") &&
	    attr->value_tag == IPP_TAG_INTEGER)
	  jobsize = attr->values[0].integer;

#ifdef __osf__
        if (!strcmp(attr->name, "job-priority") &&
	    attr->value_tag == IPP_TAG_INTEGER)
	  jobpriority = attr->values[0].integer;
#endif /* __osf__ */

        if (!strcmp(attr->name, "job-state") &&
	    attr->value_tag == IPP_TAG_ENUM)
	  jobstate = (ipp_jstate_t)attr->values[0].integer;

        if (!strcmp(attr->name, "job-printer-uri") &&
	    attr->value_tag == IPP_TAG_URI)
	  if ((jobdest = strrchr(attr->values[0].string.text, '/')) != NULL)
	    jobdest ++;

        if (!strcmp(attr->name, "job-originating-user-name") &&
	    attr->value_tag == IPP_TAG_NAME)
	  jobuser = attr->values[0].string.text;

        if (!strcmp(attr->name, "job-name") &&
	    attr->value_tag == IPP_TAG_NAME)
	  jobname = attr->values[0].string.text;

        if (!strcmp(attr->name, "copies") &&
	    attr->value_tag == IPP_TAG_INTEGER)
	  jobcopies = attr->values[0].integer;

        attr = attr->next;
      }

     /*
      * See if we have everything needed...
      */

      if (jobdest == NULL || jobid == 0)
      {
        if (attr == NULL)
	  break;
	else
          continue;
      }

      if (!longstatus && jobcount == 0)
#ifdef __osf__
	_cupsLangPuts(stdout,
	              /* TRANSLATORS: Pri is job priority. */
	              _("Rank   Owner      Pri  Job        Files"
		        "                       Total Size"));
#else
	_cupsLangPuts(stdout,
	              _("Rank    Owner   Job     File(s)"
		        "                         Total Size"));
#endif /* __osf__ */

      jobcount ++;

     /*
      * Display the job...
      */

      if (jobstate == IPP_JOB_PROCESSING)
	strlcpy(rankstr, "active", sizeof(rankstr));
      else
      {
       /*
        * Make the rank show the "correct" suffix for each number
	* (11-13 are the only special cases, for English anyways...)
	*/

	if ((rank % 100) >= 11 && (rank % 100) <= 13)
	  snprintf(rankstr, sizeof(rankstr), "%dth", rank);
	else
	  snprintf(rankstr, sizeof(rankstr), "%d%s", rank, ranks[rank % 10]);

	rank ++;
      }

      if (longstatus)
      {
        _cupsLangPuts(stdout, "\n");

        if (jobcopies > 1)
	  snprintf(namestr, sizeof(namestr), "%d copies of %s", jobcopies,
	           jobname);
	else
	  strlcpy(namestr, jobname, sizeof(namestr));

        _cupsLangPrintf(stdout, _("%s: %-33.33s [job %d localhost]"),
	                jobuser, rankstr, jobid);
        _cupsLangPrintf(stdout, _("        %-39.39s %.0f bytes"),
	                namestr, 1024.0 * jobsize);
      }
      else
#ifdef __osf__
        _cupsLangPrintf(stdout,
	                _("%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes"),
			rankstr, jobuser, jobpriority, jobid, jobname,
			1024.0 * jobsize);
#else
        _cupsLangPrintf(stdout,
	                _("%-7s %-7.7s %-7d %-31.31s %.0f bytes"),
			rankstr, jobuser, jobid, jobname, 1024.0 * jobsize);
#endif /* __osf */

      if (attr == NULL)
        break;
    }

    ippDelete(response);
  }
  else
  {
    _cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString());
    return (0);
  }

  if (jobcount == 0)
    _cupsLangPuts(stdout, _("no entries"));

  return (jobcount);
}
Ejemplo n.º 21
0
Archivo: lpc.c Proyecto: lanceit/cups
int
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  http_t	*http;			/* Connection to server */
  char		line[1024],		/* Input line from user */
		*params;		/* Pointer to parameters */


  _cupsSetLocale(argv);

 /*
  * Connect to the scheduler...
  */

  http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());

  if (argc > 1)
  {
   /*
    * Process a single command on the command-line...
    */

    do_command(http, argv[1], argv[2]);
  }
  else
  {
   /*
    * Do the command prompt thing...
    */

    _cupsLangPuts(stdout, _("lpc> ")); /* TODO: Need no-newline version */
    while (fgets(line, sizeof(line), stdin) != NULL)
    {
     /*
      * Strip trailing whitespace...
      */

      for (params = line + strlen(line) - 1; params >= line;)
        if (!isspace(*params & 255))
	  break;
	else
	  *params-- = '\0';

     /*
      * Strip leading whitespace...
      */

      for (params = line; isspace(*params & 255); params ++);

      if (params > line)
        _cups_strcpy(line, params);

      if (!line[0])
      {
       /*
        * Nothing left, just show a prompt...
	*/

	_cupsLangPuts(stdout, _("lpc> ")); /* TODO: Need no newline version */
	continue;
      }

     /*
      * Find any options in the string...
      */

      for (params = line; *params != '\0'; params ++)
        if (isspace(*params & 255))
	  break;

     /*
      * Remove whitespace between the command and parameters...
      */

      while (isspace(*params & 255))
        *params++ = '\0';

     /*
      * The "quit" and "exit" commands exit; otherwise, process as needed...
      */

      if (!compare_strings(line, "quit", 1) ||
          !compare_strings(line, "exit", 2))
        break;

      if (*params == '\0')
        do_command(http, line, NULL);
      else
        do_command(http, line, params);

     /*
      * Put another prompt out to the user...
      */

      _cupsLangPuts(stdout, _("lpc> ")); /* TODO: Need no newline version */
    }
  }

 /*
  * Close the connection to the server and return...
  */

  httpClose(http);

  return (0);
}
Ejemplo n.º 22
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  int		i;			/* Looping var */
  char		*opt;			/* Option pointer */
  const char	*username;		/* Pointer to username */
  const char	*groupname;		/* Pointer to group name */
  int		op;			/* Operation (add, change, delete) */
  const char	*passwd;		/* Password string */
  FILE		*infile,		/* Input file */
		*outfile;		/* Output file */
  char		line[256],		/* Line from file */
		userline[17],		/* User from line */
		groupline[17],		/* Group from line */
		md5line[33],		/* MD5-sum from line */
		md5new[33];		/* New MD5 sum */
  char		passwdmd5[1024],	/* passwd.md5 file */
		passwdold[1024],	/* passwd.old file */
		passwdnew[1024];	/* passwd.tmp file */
  char		*newpass,		/* new password */
  		*oldpass;		/* old password */
  int		flag;			/* Password check flags... */
  int		fd;			/* Password file descriptor */
  int		error;			/* Write error */
  _cups_globals_t *cg = _cupsGlobals();	/* Global data */
  cups_lang_t	*lang;			/* Language info */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
  struct sigaction action;		/* Signal action */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET*/


  _cupsSetLocale(argv);
  lang = cupsLangDefault();

 /*
  * Check to see if stdin, stdout, and stderr are still open...
  */

  if (fcntl(0, F_GETFD, &i) ||
      fcntl(1, F_GETFD, &i) ||
      fcntl(2, F_GETFD, &i))
  {
   /*
    * No, return exit status 2 and don't try to send any output since
    * someone is trying to bypass the security on the server.
    */

    return (2);
  }

 /*
  * Find the server directory...
  */

  snprintf(passwdmd5, sizeof(passwdmd5), "%s/passwd.md5", cg->cups_serverroot);
  snprintf(passwdold, sizeof(passwdold), "%s/passwd.old", cg->cups_serverroot);
  snprintf(passwdnew, sizeof(passwdnew), "%s/passwd.new", cg->cups_serverroot);

 /*
  * Find the default system group...
  */

  if (getgrnam(CUPS_DEFAULT_GROUP))
    groupname = CUPS_DEFAULT_GROUP;
  else
    groupname = "unknown";

  endgrent();

  username = NULL;
  op       = CHANGE;

 /*
  * Parse command-line options...
  */

  for (i = 1; i < argc; i ++)
    if (argv[i][0] == '-')
      for (opt = argv[i] + 1; *opt; opt ++)
        switch (*opt)
	{
	  case 'a' : /* Add */
	      op = ADD;
	      break;
	  case 'x' : /* Delete */
	      op = DELETE;
	      break;
	  case 'g' : /* Group */
	      i ++;
	      if (i >= argc)
	        usage(stderr);

              groupname = argv[i];
	      break;
	  case 'h' : /* Help */
	      usage(stdout);
	      break;
	  default : /* Bad option */
	      usage(stderr);
	      break;
	}
    else if (!username)
      username = argv[i];
    else
      usage(stderr);

 /*
  * See if we are trying to add or delete a password when we aren't logged in
  * as root...
  */

  if (getuid() && getuid() != geteuid() && (op != CHANGE || username))
  {
    _cupsLangPuts(stderr,
                  _("lppasswd: Only root can add or delete passwords!\n"));
    return (1);
  }

 /*
  * Fill in missing info...
  */

  if (!username)
    username = cupsUser();

  oldpass = newpass = NULL;

 /*
  * Obtain old and new password _before_ locking the database
  * to keep users from locking the file indefinitely.
  */

  if (op == CHANGE && getuid())
  {
    if ((passwd = cupsGetPassword(_("Enter old password:"******"lppasswd: Unable to copy password string: %s\n"),
		      strerror(errno));
      return (1);
    }
  }

 /*
  * Now get the new password, if necessary...
  */

  if (op != DELETE)
  {
    if ((passwd = cupsGetPassword(
            _cupsLangString(lang, _("Enter password:"******"lppasswd: Unable to copy password string: %s\n"),
		      strerror(errno));
      return (1);
    }

    if ((passwd = cupsGetPassword(
            _cupsLangString(lang, _("Enter password again:")))) == NULL)
      return (1);

    if (strcmp(passwd, newpass) != 0)
    {
      _cupsLangPuts(stderr,
                    _("lppasswd: Sorry, passwords don't match!\n"));
      return (1);
    }

   /*
    * Check that the password contains at least one letter and number.
    */

    flag = 0;

    for (passwd = newpass; *passwd; passwd ++)
      if (isdigit(*passwd & 255))
	flag |= 1;
      else if (isalpha(*passwd & 255))
	flag |= 2;

   /*
    * Only allow passwords that are at least 6 chars, have a letter and
    * a number, and don't contain the username.
    */

    if (strlen(newpass) < 6 || strstr(newpass, username) != NULL || flag != 3)
    {
      _cupsLangPuts(stderr,
                    _("lppasswd: Sorry, password rejected.\n"
		      "Your password must be at least 6 characters long, "
		      "cannot contain\n"
		      "your username, and must contain at least one letter "
		      "and number.\n"));
      return (1);
    }
  }

 /*
  * Ignore SIGHUP, SIGINT, SIGTERM, and SIGXFSZ (if defined) for the
  * remainder of the time so that we won't end up with bogus password
  * files...
  */

#ifndef WIN32
#  if defined(HAVE_SIGSET)
  sigset(SIGHUP, SIG_IGN);
  sigset(SIGINT, SIG_IGN);
  sigset(SIGTERM, SIG_IGN);
#    ifdef SIGXFSZ
  sigset(SIGXFSZ, SIG_IGN);
#    endif /* SIGXFSZ */
#  elif defined(HAVE_SIGACTION)
  memset(&action, 0, sizeof(action));
  action.sa_handler = SIG_IGN;

  sigaction(SIGHUP, &action, NULL);
  sigaction(SIGINT, &action, NULL);
  sigaction(SIGTERM, &action, NULL);
#    ifdef SIGXFSZ
  sigaction(SIGXFSZ, &action, NULL);
#    endif /* SIGXFSZ */
#  else
  signal(SIGHUP, SIG_IGN);
  signal(SIGINT, SIG_IGN);
  signal(SIGTERM, SIG_IGN);
#    ifdef SIGXFSZ
  signal(SIGXFSZ, SIG_IGN);
#    endif /* SIGXFSZ */
#  endif
#endif /* !WIN32 */

 /*
  * Open the output file.
  */

  if ((fd = open(passwdnew, O_WRONLY | O_CREAT | O_EXCL, 0400)) < 0)
  {
    if (errno == EEXIST)
      _cupsLangPuts(stderr, _("lppasswd: Password file busy!\n"));
    else
      _cupsLangPrintf(stderr,
                      _("lppasswd: Unable to open password file: %s\n"),
		      strerror(errno));

    return (1);
  }

  if ((outfile = fdopen(fd, "w")) == NULL)
  {
    _cupsLangPrintf(stderr,
                    _("lppasswd: Unable to open password file: %s\n"),
		    strerror(errno));

    unlink(passwdnew);

    return (1);
  }

  setbuf(outfile, NULL);

 /*
  * Open the existing password file and create a new one...
  */

  infile = fopen(passwdmd5, "r");
  if (infile == NULL && errno != ENOENT && op != ADD)
  {
    _cupsLangPrintf(stderr,
                    _("lppasswd: Unable to open password file: %s\n"),
		    strerror(errno));

    fclose(outfile);

    unlink(passwdnew);

    return (1);
  }

 /*
  * Read lines from the password file; the format is:
  *
  *   username:group:MD5-sum
  */

  error        = 0;
  userline[0]  = '\0';
  groupline[0] = '\0';
  md5line[0]   = '\0';

  if (infile)
  {
    while (fgets(line, sizeof(line), infile) != NULL)
    {
      if (sscanf(line, "%16[^:]:%16[^:]:%32s", userline, groupline, md5line) != 3)
        continue;

      if (strcmp(username, userline) == 0 &&
          strcmp(groupname, groupline) == 0)
	break;

      if (fputs(line, outfile) == EOF)
      {
	_cupsLangPrintf(stderr,
                	_("lppasswd: Unable to write to password file: %s\n"),
			strerror(errno));
        error = 1;
	break;
      }
    }

    if (!error)
    {
      while (fgets(line, sizeof(line), infile) != NULL)
	if (fputs(line, outfile) == EOF)
	{
	  _cupsLangPrintf(stderr,
                	  _("lppasswd: Unable to write to password file: %s\n"),
			  strerror(errno));
	  error = 1;
	  break;
	}
    }
  }

  if (op == CHANGE &&
      (strcmp(username, userline) || strcmp(groupname, groupline)))
  {
    _cupsLangPrintf(stderr,
                    _("lppasswd: user \"%s\" and group \"%s\" do not exist.\n"),
        	    username, groupname);
    error = 1;
  }
  else if (op != DELETE)
  {
    if (oldpass &&
        strcmp(httpMD5(username, "CUPS", oldpass, md5new), md5line) != 0)
    {
      _cupsLangPuts(stderr,
                    _("lppasswd: Sorry, password doesn't match!\n"));
      error = 1;
    }
    else
    {
      snprintf(line, sizeof(line), "%s:%s:%s\n", username, groupname,
               httpMD5(username, "CUPS", newpass, md5new));
      if (fputs(line, outfile) == EOF)
      {
	_cupsLangPrintf(stderr,
                	_("lppasswd: Unable to write to password file: %s\n"),
			strerror(errno));
        error = 1;
      }
    }
  }

 /*
  * Close the files...
  */

  if (infile)
    fclose(infile);

  if (fclose(outfile) == EOF)
    error = 1;

 /*
  * Error out gracefully as needed...
  */

  if (error)
  {
    _cupsLangPuts(stderr, _("lppasswd: Password file not updated!\n"));
    
    unlink(passwdnew);

    return (1);
  }

 /*
  * Save old passwd file
  */

  unlink(passwdold);
  if (link(passwdmd5, passwdold) && errno != ENOENT)
  {
    _cupsLangPrintf(stderr,
                    _("lppasswd: failed to backup old password file: %s\n"),
		    strerror(errno));
    unlink(passwdnew);
    return (1);
  }

 /*
  * Install new password file
  */

  if (rename(passwdnew, passwdmd5) < 0)
  {
    _cupsLangPrintf(stderr,
                    _("lppasswd: failed to rename password file: %s\n"),
		    strerror(errno));
    unlink(passwdnew);
    return (1);
  }

  return (0);
}
Ejemplo n.º 23
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line args */
     char *argv[])			/* I - Command-line arguments */
{
  int		i,			/* Looping var */
		num_settings;		/* Number of settings */
  cups_option_t	*settings;		/* Settings */
  const char	*opt;			/* Current option character */
  http_t	*http;			/* Connection to server */


 /*
  * Process the command-line...
  */

  _cupsSetLocale(argv);

  num_settings = 0;
  settings     = NULL;

  for (i = 1; i < argc; i ++)
  {
    if (!strcmp(argv[i], "--help"))
      usage(NULL);
    else if (argv[i][0] == '-')
    {
      if (argv[i][1] == '-')
      {
        if (!strcmp(argv[i], "--debug-logging"))
	  num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING, "1",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--no-debug-logging"))
	  num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING, "0",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--remote-admin"))
	  num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN, "1",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--no-remote-admin"))
	  num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN, "0",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--remote-any"))
	  num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY, "1",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--no-remote-any"))
	  num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY, "0",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--share-printers"))
	  num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS, "1",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--no-share-printers"))
	  num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS, "0",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--user-cancel-any"))
	  num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY, "1",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--no-user-cancel-any"))
	  num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY, "0",
	                               num_settings, &settings);
        else
	  usage(argv[i]);
      }
      else
      {
        for (opt = argv[i] + 1; *opt; opt ++)
	  switch (*opt)
	  {
	    case 'E' :
	        cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
	        break;

	    case 'U' :
	        i ++;
		if (i >= argc)
		  usage(NULL);

                cupsSetUser(argv[i]);
	        break;

	    case 'h' :
	        i ++;
		if (i >= argc)
		  usage(NULL);

                cupsSetServer(argv[i]);
	        break;

	    default :
	        usage(opt);
		break;
	  }
      }
    }
    else if (strchr(argv[i], '='))
      num_settings = cupsParseOptions(argv[i], num_settings, &settings);
    else
      usage(argv[i]);
  }

  if (cupsGetOption("Listen", num_settings, settings) ||
      cupsGetOption("Port", num_settings, settings))
  {
    _cupsLangPuts(stderr, _("cupsctl: Cannot set Listen or Port directly."));
    return (1);
  }

 /*
  * Connect to the server using the defaults...
  */

  if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
                                 cupsEncryption())) == NULL)
  {
    _cupsLangPrintf(stderr, _("cupsctl: Unable to connect to server: %s"),
                    strerror(errno));
    return (1);
  }

 /*
  * Set the current configuration if we have anything on the command-line...
  */

  if (num_settings > 0)
  {
    if (!cupsAdminSetServerSettings(http, num_settings, settings))
    {
      _cupsLangPrintf(stderr, "cupsctl: %s", cupsLastErrorString());
      return (1);
    }
  }
  else if (!cupsAdminGetServerSettings(http, &num_settings, &settings))
  {
    _cupsLangPrintf(stderr, "cupsctl: %s", cupsLastErrorString());
    return (1);
  }
  else
  {
    for (i = 0; i < num_settings; i ++)
      _cupsLangPrintf(stdout, "%s=%s", settings[i].name, settings[i].value);
  }

  cupsFreeOptions(num_settings, settings);
  return (0);
}
Ejemplo n.º 24
0
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);
}
Ejemplo n.º 25
0
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);
}
Ejemplo n.º 26
0
static int				/* O - File descriptor or -1 on error */
open_device(const char *uri,		/* I - Device URI */
            int        *use_bc)		/* O - Set to 0 for unidirectional */
{
  int	fd;				/* File descriptor */


 /*
  * The generic implementation just treats the URI as a device filename...
  * Specific operating systems may also support using the device serial
  * number and/or make/model.
  */

  if (!strncmp(uri, "usb:/dev/", 9))
#ifdef __linux
  {
   /*
    * Do not allow direct devices anymore...
    */

    errno = ENODEV;
    return (-1);
  }
  else if (!strncmp(uri, "usb://", 6))
  {
   /*
    * For Linux, try looking up the device serial number or model...
    */

    int		i;			/* Looping var */
    int		busy;			/* Are any ports busy? */
    char	device[255],		/* Device filename */
		device_id[1024],	/* Device ID string */
		make_model[1024],	/* Make and model */
		device_uri[1024];	/* Device URI string */


   /*
    * Find the correct USB device...
    */

    for (;;)
    {
      for (busy = 0, i = 0; i < 16; i ++)
      {
       /*
	* Linux has a long history of changing the standard filenames used
	* for USB printer devices.  We get the honor of trying them all...
	*/

	sprintf(device, "/dev/usblp%d", i);

	if ((fd = open(device, O_RDWR | O_EXCL)) < 0 && errno == ENOENT)
	{
	  sprintf(device, "/dev/usb/lp%d", i);

	  if ((fd = open(device, O_RDWR | O_EXCL)) < 0 && errno == ENOENT)
	  {
	    sprintf(device, "/dev/usb/usblp%d", i);

    	    if ((fd = open(device, O_RDWR | O_EXCL)) < 0 && errno == ENOENT)
	      continue;
	  }
	}

	if (fd >= 0)
	{
	  backendGetDeviceID(fd, device_id, sizeof(device_id),
                             make_model, sizeof(make_model),
			     "usb", device_uri, sizeof(device_uri));
	}
	else
	{
	 /*
	  * If the open failed because it was busy, flag it so we retry
	  * as needed...
	  */

	  if (errno == EBUSY)
	    busy = 1;

	  device_uri[0] = '\0';
        }

        if (!strcmp(uri, device_uri))
	{
	 /*
	  * Yes, return this file descriptor...
	  */

	  fprintf(stderr, "DEBUG: Printer using device file \"%s\"...\n",
		  device);

	  return (fd);
	}

       /*
	* This wasn't the one...
	*/

        if (fd >= 0)
	  close(fd);
      }

     /*
      * If we get here and at least one of the printer ports showed up
      * as "busy", then sleep for a bit and retry...
      */

      if (busy)
	_cupsLangPuts(stderr,
	              _("INFO: Printer busy; will retry in 5 seconds...\n"));

      sleep(5);
    }
  }
#elif defined(__sun) && defined(ECPPIOC_GETDEVID)
  {
   /*
    * Do not allow direct devices anymore...
    */

    errno = ENODEV;
    return (-1);
  }
  else if (!strncmp(uri, "usb://", 6))
Ejemplo n.º 27
0
static int				/* O - 0 on success, 1 on fail */
delete_printer_from_class(
    http_t *http,			/* I - Server connection */
    char   *printer,			/* I - Printer to remove */
    char   *pclass)	  		/* I - Class to remove from */
{
  int		i, j, k;		/* Looping vars */
  ipp_t		*request,		/* IPP Request */
		*response;		/* IPP Response */
  ipp_attribute_t *attr,		/* Current attribute */
		*members;		/* Members in class */
  char		uri[HTTP_MAX_URI];	/* URI for printer/class */


  DEBUG_printf(("delete_printer_from_class(%p, \"%s\", \"%s\")\n", http,
                printer, pclass));

 /*
  * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
  * attributes:
  *
  *    attributes-charset
  *    attributes-natural-language
  *    printer-uri
  *    requesting-user-name
  */

  request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);

  httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
                   "localhost", 0, "/classes/%s", pclass);
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
               "printer-uri", NULL, uri);
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
               NULL, cupsUser());

 /*
  * Do the request and get back a response...
  */

  if ((response = cupsDoRequest(http, request, "/classes/")) == NULL ||
      response->request.status.status_code == IPP_NOT_FOUND)
  {
    _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());

    ippDelete(response);

    return (1);
  }

 /*
  * See if the printer is already in the class...
  */

  if ((members = ippFindAttribute(response, "member-names", IPP_TAG_NAME)) == NULL)
  {
    _cupsLangPuts(stderr, _("lpadmin: No member names were seen."));

    ippDelete(response);

    return (1);
  }

  for (i = 0; i < members->num_values; i ++)
    if (!_cups_strcasecmp(printer, members->values[i].string.text))
      break;

  if (i >= members->num_values)
  {
    _cupsLangPrintf(stderr,
                    _("lpadmin: Printer %s is not a member of class %s."),
	            printer, pclass);

    ippDelete(response);

    return (1);
  }

  if (members->num_values == 1)
  {
   /*
    * Build a CUPS_DELETE_CLASS request, which requires the following
    * attributes:
    *
    *    attributes-charset
    *    attributes-natural-language
    *    printer-uri
    *    requesting-user-name
    */

    request = ippNewRequest(CUPS_DELETE_CLASS);

    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
        	 "printer-uri", NULL, uri);
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
                 "requesting-user-name", NULL, cupsUser());
  }
  else
  {
   /*
    * Build a CUPS_ADD_MODIFY_CLASS request, which requires the following
    * attributes:
    *
    *    attributes-charset
    *    attributes-natural-language
    *    printer-uri
    *    requesting-user-name
    *    member-uris
    */

    request = ippNewRequest(CUPS_ADD_MODIFY_CLASS);

    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
        	 "printer-uri", NULL, uri);
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
                 "requesting-user-name", NULL, cupsUser());

   /*
    * Delete the printer from the class...
    */

    members = ippFindAttribute(response, "member-uris", IPP_TAG_URI);
    attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI,
                         "member-uris", members->num_values - 1, NULL, NULL);

    for (j = 0, k = 0; j < members->num_values; j ++)
      if (j != i)
        attr->values[k ++].string.text =
	    _cupsStrAlloc(members->values[j].string.text);
  }

 /*
  * Then send the request...
  */

  ippDelete(response);

  ippDelete(cupsDoRequest(http, request, "/admin/"));

  if (cupsLastError() > IPP_OK_CONFLICT)
  {
    _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());

    return (1);
  }
  else
    return (0);
}
Ejemplo n.º 28
0
int
main(int  argc,			/* I - Number of command-line arguments */
     char *argv[])		/* I - Command-line arguments */
{
  int		i;		/* Looping var */
  http_t	*http;		/* Connection to server */
  char		*printer,	/* Destination printer */
		*pclass,	/* Printer class name */
		*val;		/* Pointer to allow/deny value */
  int		num_options;	/* Number of options */
  cups_option_t	*options;	/* Options */
  char		*file;		/* New PPD file/interface script */


  _cupsSetLocale(argv);

  http        = NULL;
  printer     = NULL;
  num_options = 0;
  options     = NULL;
  file        = NULL;

  for (i = 1; i < argc; i ++)
    if (argv[i][0] == '-')
      switch (argv[i][1])
      {
        case 'c' : /* Add printer to class */
	    if (!http)
	    {
              http = httpConnectEncrypt(cupsServer(), ippPort(),
	                                cupsEncryption());

	      if (http == NULL)
	      {
		_cupsLangPrintf(stderr,
		                _("lpadmin: Unable to connect to server: %s"),
				strerror(errno));
		return (1);
	      }
            }

	    if (printer == NULL)
	    {
	      _cupsLangPuts(stderr,
	                    _("lpadmin: Unable to add a printer to the class:\n"
			      "         You must specify a printer name "
			      "first."));
	      return (1);
	    }

	    if (argv[i][2])
	      pclass = argv[i] + 2;
	    else
	    {
	      i ++;

	      if (i >= argc)
	      {
		_cupsLangPuts(stderr,
		              _("lpadmin: Expected class name after \"-c\" "
			        "option."));
		return (1);
	      }

	      pclass = argv[i];
	    }

            if (!validate_name(pclass))
	    {
	      _cupsLangPuts(stderr,
	                    _("lpadmin: Class name can only contain printable "
			      "characters."));
	      return (1);
	    }

	    if (add_printer_to_class(http, printer, pclass))
	      return (1);
	    break;

        case 'd' : /* Set as default destination */
	    if (!http)
	    {
              http = httpConnectEncrypt(cupsServer(), ippPort(),
	                                cupsEncryption());

	      if (http == NULL)
	      {
		_cupsLangPrintf(stderr,
		                _("lpadmin: Unable to connect to server: %s"),
				strerror(errno));
		return (1);
	      }
            }

	    if (argv[i][2])
	      printer = argv[i] + 2;
	    else
	    {
	      i ++;

	      if (i >= argc)
	      {
		_cupsLangPuts(stderr,
	                      _("lpadmin: Expected printer name after \"-d\" "
			        "option."));
		return (1);
	      }

	      printer = argv[i];
	    }

            if (!validate_name(printer))
	    {
	      _cupsLangPuts(stderr,
	                    _("lpadmin: Printer name can only contain "
			      "printable characters."));
	      return (1);
	    }

            if (default_printer(http, printer))
	      return (1);

	    i = argc;
	    break;

        case 'h' : /* Connect to host */
	    if (http)
	    {
	      httpClose(http);
	      http = NULL;
	    }

	    if (argv[i][2] != '\0')
	      cupsSetServer(argv[i] + 2);
	    else
	    {
	      i ++;

	      if (i >= argc)
	      {
	        _cupsLangPuts(stderr,
	                      _("lpadmin: Expected hostname after \"-h\" "
			        "option."));
		return (1);
              }

              cupsSetServer(argv[i]);
	    }
	    break;

        case 'i' : /* Use the specified interface script */
	    if (argv[i][2])
	      file = argv[i] + 2;
	    else
	    {
	      i ++;

	      if (i >= argc)
	      {
		_cupsLangPuts(stderr,
	                      _("lpadmin: Expected interface after \"-i\" "
			        "option."));
		return (1);
	      }

	      file = argv[i];
	    }
	    break;

        case 'E' : /* Enable the printer */
	    if (printer == NULL)
	    {
#ifdef HAVE_SSL
	      cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);

	      if (http)
		httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
#else
              _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."),
	                      argv[0]);
#endif /* HAVE_SSL */
	      break;
	    }

	    if (!http)
	    {
              http = httpConnectEncrypt(cupsServer(), ippPort(),
	                                cupsEncryption());

	      if (http == NULL)
	      {
		_cupsLangPrintf(stderr,
		                _("lpadmin: Unable to connect to server: %s"),
				strerror(errno));
		return (1);
	      }
            }

            if (enable_printer(http, printer))
	      return (1);
            break;

        case 'm' : /* Use the specified standard script/PPD file */
	    if (argv[i][2])
	      num_options = cupsAddOption("ppd-name", argv[i] + 2, num_options,
	                                  &options);
	    else
	    {
	      i ++;

	      if (i >= argc)
	      {
		_cupsLangPuts(stderr,
	                      _("lpadmin: Expected model after \"-m\" "
			        "option."));
		return (1);
	      }

	      num_options = cupsAddOption("ppd-name", argv[i], num_options,
	                                  &options);
	    }
	    break;

        case 'o' : /* Set option */
	    if (argv[i][2])
	      num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
	    else
	    {
	      i ++;

	      if (i >= argc)
	      {
		_cupsLangPuts(stderr,
	                      _("lpadmin: Expected name=value after \"-o\" "
			        "option."));
		return (1);
	      }

	      num_options = cupsParseOptions(argv[i], num_options, &options);
	    }
	    break;

        case 'p' : /* Add/modify a printer */
	    if (argv[i][2])
	      printer = argv[i] + 2;
	    else
	    {
	      i ++;

	      if (i >= argc)
	      {
		_cupsLangPuts(stderr,
	                      _("lpadmin: Expected printer after \"-p\" "
			        "option."));
		return (1);
	      }

	      printer = argv[i];
	    }

            if (!validate_name(printer))
	    {
	      _cupsLangPuts(stderr,
	                    _("lpadmin: Printer name can only contain "
			      "printable characters."));
	      return (1);
	    }
	    break;

        case 'r' : /* Remove printer from class */
	    if (!http)
	    {
              http = httpConnectEncrypt(cupsServer(), ippPort(),
	                                cupsEncryption());

	      if (http == NULL)
	      {
		_cupsLangPrintf(stderr,
		                _("lpadmin: Unable to connect to server: %s"),
				strerror(errno));
		return (1);
	      }
            }

	    if (printer == NULL)
	    {
	      _cupsLangPuts(stderr,
	                    _("lpadmin: Unable to remove a printer from the "
			      "class:\n"
			      "         You must specify a printer name "
			      "first."));
	      return (1);
	    }

	    if (argv[i][2])
	      pclass = argv[i] + 2;
	    else
	    {
	      i ++;

	      if (i >= argc)
	      {
		_cupsLangPuts(stderr,
	                      _("lpadmin: Expected class after \"-r\" "
			        "option."));
		return (1);
	      }

	      pclass = argv[i];
	    }

            if (!validate_name(pclass))
	    {
	      _cupsLangPuts(stderr,
	                    _("lpadmin: Class name can only contain printable "
			      "characters."));
	      return (1);
	    }

            if (delete_printer_from_class(http, printer, pclass))
	      return (1);
	    break;

        case 'R' : /* Remove option */
	    if (!http)
	    {
              http = httpConnectEncrypt(cupsServer(), ippPort(),
	                                cupsEncryption());

	      if (http == NULL)
	      {
		_cupsLangPrintf(stderr,
		                _("lpadmin: Unable to connect to server: %s"),
				strerror(errno));
		return (1);
	      }
            }

	    if (printer == NULL)
	    {
	      _cupsLangPuts(stderr,
	                    _("lpadmin: Unable to delete option:\n"
			      "         You must specify a printer name "
			      "first."));
	      return (1);
	    }

	    if (argv[i][2])
	      val = argv[i] + 2;
	    else
	    {
	      i ++;

	      if (i >= argc)
	      {
		_cupsLangPuts(stderr,
	                      _("lpadmin: Expected name after \"-R\" "
			        "option."));
		return (1);
	      }

	      val = argv[i];
	    }

            if (delete_printer_option(http, printer, val))
	      return (1);
	    break;

        case 'U' : /* Username */
	    if (argv[i][2] != '\0')
	      cupsSetUser(argv[i] + 2);
	    else
	    {
	      i ++;
	      if (i >= argc)
	      {
	        _cupsLangPrintf(stderr,
		                _("%s: Error - expected username after "
				  "\"-U\" option."), argv[0]);
	        return (1);
	      }

              cupsSetUser(argv[i]);
	    }
	    break;

        case 'u' : /* Allow/deny users */
	    if (argv[i][2])
	      val = argv[i] + 2;
	    else
	    {
	      i ++;

	      if (i >= argc)
	      {
		_cupsLangPuts(stderr,
	                      _("lpadmin: Expected allow/deny:userlist after "
			        "\"-u\" option."));
		return (1);
	      }

              val = argv[i];
	    }

            if (!_cups_strncasecmp(val, "allow:", 6))
	      num_options = cupsAddOption("requesting-user-name-allowed",
	                                  val + 6, num_options, &options);
            else if (!_cups_strncasecmp(val, "deny:", 5))
	      num_options = cupsAddOption("requesting-user-name-denied",
	                                  val + 5, num_options, &options);
            else
	    {
	      _cupsLangPrintf(stderr,
	                      _("lpadmin: Unknown allow/deny option \"%s\"."),
	                      val);
	      return (1);
	    }
	    break;

        case 'v' : /* Set the device-uri attribute */
	    if (argv[i][2])
	      num_options = cupsAddOption("device-uri", argv[i] + 2,
	                                  num_options, &options);
	    else
	    {
	      i ++;

	      if (i >= argc)
	      {
		_cupsLangPuts(stderr,
	                      _("lpadmin: Expected device URI after \"-v\" "
			        "option."));
		return (1);
	      }

	      num_options = cupsAddOption("device-uri", argv[i],
	                                  num_options, &options);
	    }
	    break;

        case 'x' : /* Delete a printer */
	    if (!http)
	    {
              http = httpConnectEncrypt(cupsServer(), ippPort(),
	                                cupsEncryption());

	      if (http == NULL)
	      {
		_cupsLangPrintf(stderr,
		                _("lpadmin: Unable to connect to server: %s"),
				strerror(errno));
		return (1);
	      }
            }

	    if (argv[i][2])
	      printer = argv[i] + 2;
	    else
	    {
	      i ++;

	      if (i >= argc)
	      {
		_cupsLangPuts(stderr,
	                      _("lpadmin: Expected printer or class after "
			        "\"-x\" option."));
		return (1);
	      }

	      printer = argv[i];
	    }

            if (!validate_name(printer))
	    {
	      _cupsLangPuts(stderr,
	                    _("lpadmin: Printer name can only contain "
			      "printable characters."));
	      return (1);
	    }

            if (delete_printer(http, printer))
	      return (1);

	    i = argc;
	    break;

        case 'D' : /* Set the printer-info attribute */
	    if (argv[i][2])
	      num_options = cupsAddOption("printer-info", argv[i] + 2,
	                                  num_options, &options);
	    else
	    {
	      i ++;

	      if (i >= argc)
	      {
		_cupsLangPuts(stderr,
	                      _("lpadmin: Expected description after "
			        "\"-D\" option."));
		return (1);
	      }

	      num_options = cupsAddOption("printer-info", argv[i],
	                                  num_options, &options);
	    }
	    break;

        case 'I' : /* Set the supported file types (ignored) */
	    i ++;

	    if (i >= argc)
	    {
	      _cupsLangPuts(stderr,
	                    _("lpadmin: Expected file type(s) after \"-I\" "
			      "option."));
	      return (1);
	    }

	    _cupsLangPuts(stderr,
	                  _("lpadmin: Warning - content type list ignored."));
	    break;

        case 'L' : /* Set the printer-location attribute */
	    if (argv[i][2])
	      num_options = cupsAddOption("printer-location", argv[i] + 2,
	                                  num_options, &options);
	    else
	    {
	      i ++;

	      if (i >= argc)
	      {
		_cupsLangPuts(stderr,
	                      _("lpadmin: Expected location after \"-L\" "
			        "option."));
		return (1);
	      }

	      num_options = cupsAddOption("printer-location", argv[i],
	                                  num_options, &options);
	    }
	    break;

        case 'P' : /* Use the specified PPD file */
	    if (argv[i][2])
	      file = argv[i] + 2;
	    else
	    {
	      i ++;

	      if (i >= argc)
	      {
		_cupsLangPuts(stderr,
	                      _("lpadmin: Expected PPD after \"-P\" option."));
		return (1);
	      }

	      file = argv[i];
	    }
	    break;

	default :
	    _cupsLangPrintf(stderr,
	                    _("lpadmin: Unknown option \"%c\"."), argv[i][1]);
	    return (1);
      }
    else
    {
      _cupsLangPrintf(stderr, _("lpadmin: Unknown argument \"%s\"."),
                      argv[i]);
      return (1);
    }

 /*
  * Set options as needed...
  */

  if (num_options || file)
  {
    if (!http)
    {
      http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());

      if (http == NULL)
      {
	_cupsLangPrintf(stderr,
			_("lpadmin: Unable to connect to server: %s"),
			strerror(errno));
	return (1);
      }
    }

    if (printer == NULL)
    {
      _cupsLangPuts(stderr,
                    _("lpadmin: Unable to set the printer options:\n"
		      "         You must specify a printer name first."));
      return (1);
    }

    if (set_printer_options(http, printer, num_options, options, file))
      return (1);
  }

  if (printer == NULL)
  {
    _cupsLangPuts(stdout,
	          _("Usage:\n"
		    "\n"
		    "    lpadmin [-h server] -d destination\n"
		    "    lpadmin [-h server] -x destination\n"
		    "    lpadmin [-h server] -p printer [-c add-class] "
		    "[-i interface] [-m model]\n"
		    "                       [-r remove-class] [-v device] "
		    "[-D description]\n"
		    "                       [-P ppd-file] [-o name=value]\n"
		    "                       [-u allow:user,user] "
		    "[-u deny:user,user]"));
  }

  if (http)
    httpClose(http);

  return (0);
}
Ejemplo n.º 29
0
int					/* O - Exit status */
print_device(const char *uri,		/* I - Device URI */
             const char *hostname,	/* I - Hostname/manufacturer */
             const char *resource,	/* I - Resource/modelname */
	     char       *options,	/* I - Device options/serial number */
	     int        print_fd,	/* I - File descriptor to print */
	     int        copies,		/* I - Copies to print */
	     int	argc,		/* I - Number of command-line arguments (6 or 7) */
	     char	*argv[])	/* I - Command-line arguments */
{
  int		use_bc;			/* Use backchannel path? */
  int		device_fd;		/* USB device */
  size_t	tbytes;			/* Total number of bytes written */
  struct termios opts;			/* Parallel port options */


  (void)argc;
  (void)argv;

 /*
  * Open the USB port device...
  */

  fputs("STATE: +connecting-to-device\n", stderr);

  do
  {
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
   /*
    * *BSD's ulpt driver currently does not support the
    * back-channel, incorrectly returns data ready on a select(),
    * and locks up on read()...
    */

    use_bc = 0;

#else
   /*
    * Disable backchannel data when printing to Brother, Canon, or
    * Minolta USB printers - apparently these printers will return
    * the IEEE-1284 device ID over and over and over when they get
    * a read request...
    */

    use_bc = strcasecmp(hostname, "Brother") &&
             strcasecmp(hostname, "Canon") &&
             strncasecmp(hostname, "Konica", 6) &&
             strncasecmp(hostname, "Minolta", 7);
#endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ */

    if ((device_fd = open_device(uri, &use_bc)) == -1)
    {
      if (getenv("CLASS") != NULL)
      {
       /*
        * If the CLASS environment variable is set, the job was submitted
	* to a class and not to a specific queue.  In this case, we want
	* to abort immediately so that the job can be requeued on the next
	* available printer in the class.
	*/

        _cupsLangPuts(stderr,
	              _("INFO: Unable to contact printer, queuing on next "
			"printer in class...\n"));

       /*
        * Sleep 5 seconds to keep the job from requeuing too rapidly...
	*/

	sleep(5);

        return (CUPS_BACKEND_FAILED);
      }

      if (errno == EBUSY)
      {
        _cupsLangPuts(stderr,
	              _("INFO: Printer busy; will retry in 10 seconds...\n"));
	sleep(10);
      }
      else if (errno == ENXIO || errno == EIO || errno == ENOENT ||
               errno == ENODEV)
      {
        _cupsLangPuts(stderr,
	              _("INFO: Printer not connected; will retry in 30 "
		        "seconds...\n"));
	sleep(30);
      }
      else
      {
	_cupsLangPrintf(stderr,
	                _("ERROR: Unable to open device file \"%s\": %s\n"),
			resource, strerror(errno));
	return (CUPS_BACKEND_FAILED);
      }
    }
  }
  while (device_fd < 0);

  fputs("STATE: -connecting-to-device\n", stderr);

 /*
  * Set any options provided...
  */

  tcgetattr(device_fd, &opts);

  opts.c_lflag &= ~(ICANON | ECHO | ISIG);	/* Raw mode */

  /**** No options supported yet ****/

  tcsetattr(device_fd, TCSANOW, &opts);

 /*
  * Finally, send the print file...
  */

  tbytes = 0;

  while (copies > 0 && tbytes >= 0)
  {
    copies --;

    if (print_fd != 0)
    {
      fputs("PAGE: 1 1\n", stderr);
      lseek(print_fd, 0, SEEK_SET);
    }

    tbytes = backendRunLoop(print_fd, device_fd, use_bc, side_cb);

    if (print_fd != 0 && tbytes >= 0)
      _cupsLangPrintf(stderr,
#ifdef HAVE_LONG_LONG
		      _("INFO: Sent print file, %lld bytes...\n"),
#else
		      _("INFO: Sent print file, %ld bytes...\n"),
#endif /* HAVE_LONG_LONG */
		      CUPS_LLCAST tbytes);
  }

 /*
  * Close the USB port and return...
  */

  close(device_fd);

  return (tbytes < 0 ? CUPS_BACKEND_FAILED : CUPS_BACKEND_OK);
}
Ejemplo n.º 30
0
ssize_t					/* O - Total bytes on success, -1 on error */
backendRunLoop(
    int         print_fd,		/* I - Print file descriptor */
    int         device_fd,		/* I - Device file descriptor */
    int         snmp_fd,		/* I - SNMP socket or -1 if none */
    http_addr_t *addr,			/* I - Address of device */
    int         use_bc,			/* I - Use back-channel? */
    int         update_state,		/* I - Update printer-state-reasons? */
    int         (*side_cb)(int, int, int, http_addr_t *, int))
					/* I - Side-channel callback */
{
  int		nfds;			/* Maximum file descriptor value + 1 */
  fd_set	input,			/* Input set for reading */
		output;			/* Output set for writing */
  ssize_t	print_bytes,		/* Print bytes read */
		bc_bytes,		/* Backchannel bytes read */
		total_bytes,		/* Total bytes written */
		bytes;			/* Bytes written */
  int		paperout;		/* "Paper out" status */
  int		offline;		/* "Off-line" status */
  char		print_buffer[8192],	/* Print data buffer */
		*print_ptr,		/* Pointer into print data buffer */
		bc_buffer[1024];	/* Back-channel data buffer */
  struct timeval timeout;		/* Timeout for select() */
  time_t	curtime,		/* Current time */
		snmp_update = 0;
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
  struct sigaction action;		/* Actions for POSIX signals */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */


  fprintf(stderr,
          "DEBUG: backendRunLoop(print_fd=%d, device_fd=%d, snmp_fd=%d, "
	  "addr=%p, use_bc=%d, side_cb=%p)\n",
          print_fd, device_fd, snmp_fd, addr, use_bc, side_cb);

 /*
  * If we are printing data from a print driver on stdin, ignore SIGTERM
  * so that the driver can finish out any page data, e.g. to eject the
  * current page.  We only do this for stdin printing as otherwise there
  * is no way to cancel a raw print job...
  */

  if (!print_fd)
  {
#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
    sigset(SIGTERM, SIG_IGN);
#elif defined(HAVE_SIGACTION)
    memset(&action, 0, sizeof(action));

    sigemptyset(&action.sa_mask);
    action.sa_handler = SIG_IGN;
    sigaction(SIGTERM, &action, NULL);
#else
    signal(SIGTERM, SIG_IGN);
#endif /* HAVE_SIGSET */
  }
  else if (print_fd < 0)
  {
   /*
    * Copy print data from stdin, but don't mess with the signal handlers...
    */

    print_fd = 0;
  }

 /*
  * Figure out the maximum file descriptor value to use with select()...
  */

  nfds = (print_fd > device_fd ? print_fd : device_fd) + 1;

 /*
  * Now loop until we are out of data from print_fd...
  */

  for (print_bytes = 0, print_ptr = print_buffer, offline = -1,
           paperout = -1, total_bytes = 0;;)
  {
   /*
    * Use select() to determine whether we have data to copy around...
    */

    FD_ZERO(&input);
    if (!print_bytes)
      FD_SET(print_fd, &input);
    if (use_bc)
      FD_SET(device_fd, &input);
    if (!print_bytes && side_cb)
      FD_SET(CUPS_SC_FD, &input);

    FD_ZERO(&output);
    if (print_bytes || (!use_bc && !side_cb))
      FD_SET(device_fd, &output);

    if (use_bc || side_cb)
    {
      timeout.tv_sec  = 5;
      timeout.tv_usec = 0;

      if (select(nfds, &input, &output, NULL, &timeout) < 0)
      {
       /*
	* Pause printing to clear any pending errors...
	*/

	if (errno == ENXIO && offline != 1 && update_state)
	{
	  fputs("STATE: +offline-report\n", stderr);
	  _cupsLangPuts(stderr, _("INFO: Printer is currently offline.\n"));
	  offline = 1;
	}
	else if (errno == EINTR && total_bytes == 0)
	{
	  fputs("DEBUG: Received an interrupt before any bytes were "
	        "written, aborting!\n", stderr);
          return (0);
	}

	sleep(1);
	continue;
      }
    }

   /*
    * Check if we have a side-channel request ready...
    */

    if (side_cb && FD_ISSET(CUPS_SC_FD, &input))
    {
     /*
      * Do the side-channel request, then start back over in the select
      * loop since it may have read from print_fd...
      */

      if ((*side_cb)(print_fd, device_fd, snmp_fd, addr, use_bc))
        side_cb = NULL;
      continue;
    }

   /*
    * Check if we have back-channel data ready...
    */

    if (FD_ISSET(device_fd, &input))
    {
      if ((bc_bytes = read(device_fd, bc_buffer, sizeof(bc_buffer))) > 0)
      {
	fprintf(stderr,
	        "DEBUG: Received " CUPS_LLFMT " bytes of back-channel data!\n",
	        CUPS_LLCAST bc_bytes);
        cupsBackChannelWrite(bc_buffer, bc_bytes, 1.0);
      }
      else if (bc_bytes < 0 && errno != EAGAIN && errno != EINTR)
      {
        fprintf(stderr, "DEBUG: Error reading back-channel data: %s\n",
	        strerror(errno));
	use_bc = 0;
      }
    }

   /*
    * Check if we have print data ready...
    */

    if (FD_ISSET(print_fd, &input))
    {
      if ((print_bytes = read(print_fd, print_buffer,
                              sizeof(print_buffer))) < 0)
      {
       /*
        * Read error - bail if we don't see EAGAIN or EINTR...
	*/

	if (errno != EAGAIN || errno != EINTR)
	{
	  perror("ERROR: Unable to read print data");
	  return (-1);
	}

        print_bytes = 0;
      }
      else if (print_bytes == 0)
      {
       /*
        * End of file, break out of the loop...
	*/

        break;
      }

      print_ptr = print_buffer;

      fprintf(stderr, "DEBUG: Read %d bytes of print data...\n",
              (int)print_bytes);
    }

   /*
    * Check if the device is ready to receive data and we have data to
    * send...
    */

    if (print_bytes && FD_ISSET(device_fd, &output))
    {
      if ((bytes = write(device_fd, print_ptr, print_bytes)) < 0)
      {
       /*
        * Write error - bail if we don't see an error we can retry...
	*/

        if (errno == ENOSPC)
	{
	  if (paperout != 1 && update_state)
	  {
	    fputs("STATE: +media-empty-warning\n", stderr);
	    _cupsLangPuts(stderr, _("ERROR: Out of paper!\n"));
	    paperout = 1;
	  }
        }
	else if (errno == ENXIO)
	{
	  if (offline != 1 && update_state)
	  {
	    fputs("STATE: +offline-report\n", stderr);
	    _cupsLangPuts(stderr, _("INFO: Printer is currently off-line.\n"));
	    offline = 1;
	  }
	}
	else if (errno != EAGAIN && errno != EINTR && errno != ENOTTY)
	{
	  fprintf(stderr, _("ERROR: Unable to write print data: %s\n"),
	          strerror(errno));
	  return (-1);
	}
      }
      else
      {
        if (paperout && update_state)
	{
	  fputs("STATE: -media-empty-warning\n", stderr);
	  paperout = 0;
	}

	if (offline && update_state)
	{
	  fputs("STATE: -offline-report\n", stderr);
	  _cupsLangPuts(stderr, _("INFO: Printer is now online.\n"));
	  offline = 0;
	}

        fprintf(stderr, "DEBUG: Wrote %d bytes of print data...\n", (int)bytes);

        print_bytes -= bytes;
	print_ptr   += bytes;
	total_bytes += bytes;
      }
    }

   /*
    * Do SNMP updates periodically...
    */

    if (snmp_fd >= 0 && time(&curtime) >= snmp_update)
    {
      if (backendSNMPSupplies(snmp_fd, addr, NULL, NULL))
        snmp_update = INT_MAX;
      else
        snmp_update = curtime + 5;
    }
  }

 /*
  * Return with success...
  */

  return (total_bytes);
}