• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * "lpmove" command for CUPS.
3  *
4  * Copyright © 2020-2024 by OpenPrinting.
5  * Copyright © 2007-2018 by Apple Inc.
6  * Copyright © 1997-2006 by Easy Software Products.
7  *
8  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
9  * information.
10  */
11 
12 /*
13  * Include necessary headers...
14  */
15 
16 #include <cups/cups-private.h>
17 
18 
19 /*
20  * Local functions...
21  */
22 
23 static int	move_job(http_t *http, const char *src, int jobid, const char *dest);
24 static void	usage(void) _CUPS_NORETURN;
25 
26 
27 /*
28  * 'main()' - Parse options and show status information.
29  */
30 
31 int
main(int argc,char * argv[])32 main(int  argc,				/* I - Number of command-line arguments */
33      char *argv[])			/* I - Command-line arguments */
34 {
35   int		i;			/* Looping var */
36   http_t	*http;			/* Connection to server */
37   const char	*opt,			/* Option pointer */
38 		*job;			/* Job name */
39   int		jobid;			/* Job ID */
40   int		num_dests;		/* Number of destinations */
41   cups_dest_t	*dests;			/* Destinations */
42   const char	*src,			/* Original queue */
43 		*dest;			/* New destination */
44 
45 
46   _cupsSetLocale(argv);
47 
48   dest      = NULL;
49   dests     = NULL;
50   job       = NULL;
51   jobid     = 0;
52   num_dests = 0;
53   src       = NULL;
54 
55   for (i = 1; i < argc; i ++)
56   {
57     if (!strcmp(argv[i], "--help"))
58       usage();
59     else if (argv[i][0] == '-')
60     {
61       for (opt = argv[i] + 1; *opt; opt ++)
62       {
63 	switch (*opt)
64 	{
65 	  case 'E' : /* Encrypt */
66 #ifdef HAVE_TLS
67 	      cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
68 
69 #else
70 	      _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]);
71 #endif /* HAVE_TLS */
72 	      break;
73 
74 	  case 'h' : /* Connect to host */
75 	      if (opt[1] != '\0')
76 	      {
77 		cupsSetServer(opt + 1);
78 		opt += strlen(opt) - 1;
79 	      }
80 	      else
81 	      {
82 		i ++;
83 
84 		if (i >= argc)
85 		{
86 		  _cupsLangPuts(stderr, _("Error: need hostname after \"-h\" option."));
87 		  usage();
88 		}
89 
90 		cupsSetServer(argv[i]);
91 	      }
92 	      break;
93 
94 	  default :
95 	      _cupsLangPrintf(stderr, _("%s: Unknown option \"%c\"."), argv[0], *opt);
96 	      usage();
97 	}
98       }
99     }
100     else if (!jobid && !src)
101     {
102       if (num_dests == 0)
103         num_dests = cupsGetDests(&dests);
104 
105       if ((job = strrchr(argv[i], '-')) != NULL &&
106           cupsGetDest(argv[i], NULL, num_dests, dests) == NULL)
107         jobid = atoi(job + 1);
108       else if (isdigit(argv[i][0] & 255) &&
109                !cupsGetDest(argv[i], NULL, num_dests, dests))
110         jobid = atoi(argv[i]);
111       else
112         src = argv[i];
113     }
114     else if (dest == NULL)
115       dest = argv[i];
116     else
117     {
118       _cupsLangPrintf(stderr, _("lpmove: Unknown argument \"%s\"."), argv[i]);
119       usage();
120     }
121   }
122 
123   if ((!jobid && !src) || !dest)
124     usage();
125 
126   http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
127 
128   if (http == NULL)
129   {
130     _cupsLangPrintf(stderr, _("lpmove: Unable to connect to server: %s"),
131 		    strerror(errno));
132     return (1);
133   }
134 
135   return (move_job(http, src, jobid, dest));
136 }
137 
138 
139 /*
140  * 'move_job()' - Move a job.
141  */
142 
143 static int				/* O - 0 on success, 1 on error */
move_job(http_t * http,const char * src,int jobid,const char * dest)144 move_job(http_t     *http,		/* I - HTTP connection to server */
145          const char *src,		/* I - Source queue */
146          int        jobid,		/* I - Job ID */
147 	 const char *dest)		/* I - Destination queue */
148 {
149   ipp_t	*request;			/* IPP Request */
150   char	job_uri[HTTP_MAX_URI],		/* job-uri */
151 	printer_uri[HTTP_MAX_URI];	/* job-printer-uri */
152 
153 
154   if (!http)
155     return (1);
156 
157  /*
158   * Build a CUPS_MOVE_JOB request, which requires the following
159   * attributes:
160   *
161   *    attributes-charset
162   *    attributes-natural-language
163   *    job-uri/printer-uri
164   *    job-printer-uri
165   *    requesting-user-name
166   */
167 
168   request = ippNewRequest(CUPS_MOVE_JOB);
169 
170   if (jobid)
171   {
172     snprintf(job_uri, sizeof(job_uri), "ipp://localhost/jobs/%d", jobid);
173     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL,
174         	 job_uri);
175   }
176   else
177   {
178     httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL,
179                      "localhost", 0, "/printers/%s", src);
180     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
181         	 job_uri);
182   }
183 
184   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
185                NULL, cupsUser());
186 
187   httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri),
188                    "ipp", NULL, "localhost", 0, "/printers/%s", dest);
189   ippAddString(request, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri",
190                NULL, printer_uri);
191 
192  /*
193   * Do the request and get back a response...
194   */
195 
196   ippDelete(cupsDoRequest(http, request, "/jobs"));
197 
198   if (cupsLastError() > IPP_OK_CONFLICT)
199   {
200     _cupsLangPrintf(stderr, "lpmove: %s", cupsLastErrorString());
201     return (1);
202   }
203   else
204     return (0);
205 }
206 
207 
208 /*
209  * 'usage()' - Show program usage and exit.
210  */
211 
212 static void
usage(void)213 usage(void)
214 {
215   _cupsLangPuts(stdout, _("Usage: lpmove [options] job destination\n"
216                           "       lpmove [options] source-destination destination"));
217   _cupsLangPuts(stdout, _("Options:"));
218   _cupsLangPuts(stdout, _("-E                      Encrypt the connection to the server"));
219   _cupsLangPuts(stdout, _("-h server[:port]        Connect to the named server and port"));
220   _cupsLangPuts(stdout, _("-U username             Specify the username to use for authentication"));
221 
222   exit(1);
223 }
224