]> git.ipfire.org Git - thirdparty/cups.git/blob - systemv/cupsaddsmb.c
Change the end copyright for Easy Software Products files to 2003.
[thirdparty/cups.git] / systemv / cupsaddsmb.c
1 /*
2 * "$Id: cupsaddsmb.c,v 1.14 2002/12/17 19:00:20 swdev Exp $"
3 *
4 * "cupsaddsmb" command for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 2001-2003 by Easy Software Products.
7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
19 *
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * Contents:
25 *
26 * main() - Export printers on the command-line.
27 * do_samba_command() - Do a SAMBA command, asking for a password as needed.
28 * export_dest() - Export a destination to SAMBA.
29 * usage() - Show program usage and exit...
30 */
31
32 /*
33 * Include necessary headers...
34 */
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <cups/cups.h>
39 #include <cups/language.h>
40 #include <cups/string.h>
41 #include <errno.h>
42
43
44 /*
45 * Local globals...
46 */
47
48 int Verbosity = 0;
49 const char *SAMBAUser,
50 *SAMBAServer;
51
52
53 /*
54 * Local functions...
55 */
56
57 int do_samba_command(const char *, const char *);
58 int export_dest(const char *);
59 void usage();
60
61
62 /*
63 * 'main()' - Export printers on the command-line.
64 */
65
66 int /* O - Exit status */
67 main(int argc, /* I - Number of command-line arguments */
68 char *argv[]) /* I - Command-line arguments */
69 {
70 int i, j; /* Looping vars */
71 int status; /* Status from export_dest() */
72 int export_all; /* Export all printers? */
73 int num_printers; /* Number of printers */
74 char **printers; /* Printers */
75
76
77 /*
78 * Parse command-line arguments...
79 */
80
81 export_all = 0;
82
83 SAMBAUser = cupsUser();
84 SAMBAServer = NULL;
85
86 for (i = 1; i < argc; i ++)
87 if (strcmp(argv[i], "-a") == 0)
88 export_all = 1;
89 else if (strcmp(argv[i], "-U") == 0)
90 {
91 i ++;
92 if (i >= argc)
93 usage();
94
95 SAMBAUser = argv[i];
96 }
97 else if (strcmp(argv[i], "-H") == 0)
98 {
99 i ++;
100 if (i >= argc)
101 usage();
102
103 SAMBAServer = argv[i];
104 }
105 else if (strcmp(argv[i], "-h") == 0)
106 {
107 i ++;
108 if (i >= argc)
109 usage();
110
111 cupsSetServer(argv[i]);
112 }
113 else if (strcmp(argv[i], "-v") == 0)
114 Verbosity = 1;
115 else if (argv[i][0] != '-')
116 {
117 if (SAMBAServer == NULL)
118 SAMBAServer = cupsServer();
119
120 if ((status = export_dest(argv[i])) != 0)
121 return (status);
122 }
123 else
124 usage();
125
126 /*
127 * See if the user specified "-a"...
128 */
129
130 if (export_all)
131 {
132 /*
133 * Export all printers...
134 */
135
136 if (SAMBAServer == NULL)
137 SAMBAServer = cupsServer();
138
139 num_printers = cupsGetPrinters(&printers);
140
141 for (j = 0, status = 0; j < num_printers; j ++)
142 if ((status = export_dest(printers[j])) != 0)
143 break;
144
145 for (j = 0; j < num_printers; j ++)
146 free(printers[j]);
147
148 if (num_printers)
149 free(printers);
150
151 if (status)
152 return (status);
153 }
154
155 return (0);
156 }
157
158
159 /*
160 * 'do_samba_command()' - Do a SAMBA command, asking for
161 * a password as needed.
162 */
163
164 int /* O - Status of command */
165 do_samba_command(const char *command, /* I - Command to run */
166 const char *subcmd) /* I - Sub-command */
167 {
168 int status; /* Status of command */
169 char temp[4096]; /* Command/prompt string */
170 static const char *p = NULL; /* Password data */
171
172
173 for (status = 1;;)
174 {
175 if (p == NULL)
176 {
177 snprintf(temp, sizeof(temp),
178 "Password for %s required to access %s via SAMBA: ",
179 SAMBAUser, SAMBAServer);
180
181 if ((p = cupsGetPassword(temp)) == NULL)
182 break;
183 }
184
185 snprintf(temp, sizeof(temp), "%s -N -U\'%s%%%s\' -c \'%s\'",
186 command, SAMBAUser, p, subcmd);
187
188 if (Verbosity)
189 printf("Running command: %s\n", temp);
190 else
191 strlcat(temp, " </dev/null >/dev/null 2>/dev/null", sizeof(temp));
192
193 if ((status = system(temp)) != 0)
194 {
195 if (Verbosity)
196 puts("");
197
198 if (p[0])
199 p = NULL;
200 else
201 break;
202 }
203 else
204 {
205 if (Verbosity)
206 puts("");
207
208 break;
209 }
210 }
211
212 return (status);
213 }
214
215
216 /*
217 * 'export_dest()' - Export a destination to SAMBA.
218 */
219
220 int /* O - 0 on success, non-zero on error */
221 export_dest(const char *dest) /* I - Destination to export */
222 {
223 int i; /* Looping var */
224 int status; /* Status of smbclient/rpcclient commands */
225 const char *ppdfile; /* PPD file for printer drivers */
226 char command[1024], /* Command to run */
227 subcmd[1024]; /* Sub-command */
228 const char *datadir; /* CUPS_DATADIR */
229 FILE *fp; /* PPD file */
230 http_t *http; /* Connection to server */
231 cups_lang_t *language; /* Default language */
232 ipp_t *request, /* IPP request */
233 *response; /* IPP response */
234 ipp_attribute_t *attr; /* IPP attribute */
235 static const char *pattrs[] = /* Printer attributes we want */
236 {
237 "job-sheets-supported",
238 "job-sheets-default"
239 };
240
241
242 if ((datadir = getenv("CUPS_DATADIR")) == NULL)
243 datadir = CUPS_DATADIR;
244
245 /*
246 * Get the PPD file...
247 */
248
249 if ((ppdfile = cupsGetPPD(dest)) == NULL)
250 {
251 fprintf(stderr, "Warning: No PPD file for printer \"%s\" - skipping!\n", dest);
252 return (0);
253 }
254
255 /*
256 * Append the supported banner pages to the PPD file...
257 */
258
259 if ((http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL)
260 {
261 fprintf(stderr, "Unable to connect to server \"%s\" for %s - %s\n",
262 cupsServer(), dest, strerror(errno));
263 unlink(ppdfile);
264 return (1);
265 }
266
267 request = ippNew();
268 request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
269 request->request.op.request_id = 1;
270
271 language = cupsLangDefault();
272
273 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
274 "attributes-charset", NULL, cupsLangEncoding(language));
275
276 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
277 "attributes-natural-language", NULL, language->language);
278
279 snprintf(command, sizeof(command), "ipp://localhost/printers/%s", dest);
280 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
281 "printer-uri", NULL, command);
282
283 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
284 "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]),
285 NULL, pattrs);
286
287 /*
288 * Do the request and get back a response...
289 */
290
291 if ((response = cupsDoRequest(http, request, "/")) != NULL)
292 {
293 if (response->request.status.status_code > IPP_OK_CONFLICT)
294 {
295 fprintf(stderr, "ERROR: get-printer-attributes failed for %s: %s\n",
296 dest, ippErrorString(response->request.status.status_code));
297 ippDelete(response);
298 unlink(ppdfile);
299 return (2);
300 }
301 }
302 else
303 {
304 fprintf(stderr, "ERROR: get-printer-attributes failed for %s: %s\n",
305 dest, ippErrorString(cupsLastError()));
306 unlink(ppdfile);
307 return (2);
308 }
309
310 /*
311 * Append the banner attributes to the end of the PPD file...
312 */
313
314 if ((fp = fopen(ppdfile, "a")) == NULL)
315 {
316 fprintf(stderr, "ERROR: Unable to append banner attributes to PPD file for %s - %s\n",
317 dest, strerror(errno));
318 ippDelete(response);
319 unlink(ppdfile);
320 return (3);
321 }
322
323 if ((attr = ippFindAttribute(response, "job-sheets-supported", IPP_TAG_NAME)) != NULL)
324 {
325 fprintf(fp, "*cupsJobSheetsSupported: \"%s", attr->values[0].string.text);
326
327 for (i = 1; i < attr->num_values; i ++)
328 fprintf(fp, ",%s", attr->values[i].string.text);
329
330 fputs("\"\n", fp);
331 }
332
333 if ((attr = ippFindAttribute(response, "job-sheets-default", IPP_TAG_NAME)) != NULL)
334 {
335 fprintf(fp, "*cupsJobSheetsDefault: \"%s", attr->values[0].string.text);
336
337 if (attr->num_values > 1)
338 fprintf(fp, ",%s", attr->values[1].string.text);
339
340 fputs("\"\n", fp);
341 }
342
343 fclose(fp);
344
345 ippDelete(response);
346 cupsLangFree(language);
347 httpClose(http);
348
349 /*
350 * See which drivers are available - the new CUPS drivers or the
351 * Adobe drivers?
352 */
353
354 snprintf(command, sizeof(command), "%s/drivers/cupsdrvr.dll", datadir);
355 if (access(command, 0) == 0)
356 {
357 /*
358 * Do the smbclient commands needed for the CUPS WinNT drivers...
359 */
360
361 snprintf(command, sizeof(command), "smbclient //%s/print\\$", SAMBAServer);
362
363 snprintf(subcmd, sizeof(subcmd),
364 "mkdir W32X86;"
365 "put %s W32X86/%s.ppd;"
366 "put %s/drivers/cupsdrvr.dll W32X86/cupsdrvr.dll;"
367 "put %s/drivers/cupsui.dll W32X86/cupsui.dll;"
368 "put %s/drivers/cups.hlp W32X86/cups.hlp",
369 ppdfile, dest, datadir, datadir, datadir);
370
371 if ((status = do_samba_command(command, subcmd)) != 0)
372 {
373 fprintf(stderr, "ERROR: Unable to copy Windows printer driver files (%d)!\n",
374 status);
375 unlink(ppdfile);
376 return (4);
377 }
378
379 /*
380 * Do the rpcclient commands needed for the CUPS WinNT drivers...
381 */
382
383 snprintf(subcmd, sizeof(subcmd),
384 "adddriver \"Windows NT x86\" \"%s:cupsdrvr.dll:%s.ppd:cupsui.dll:cups.hlp:NULL:RAW:NULL\"",
385 dest, dest);
386
387 snprintf(command, sizeof(command), "rpcclient %s", SAMBAServer);
388
389 if ((status = do_samba_command(command, subcmd)) != 0)
390 {
391 fprintf(stderr, "ERROR: Unable to install Windows printer driver files (%d)!\n",
392 status);
393 unlink(ppdfile);
394 return (5);
395 }
396 }
397 else
398 {
399 /*
400 * Do the smbclient commands needed for the Adobe WinNT drivers...
401 */
402
403 snprintf(command, sizeof(command), "smbclient //%s/print\\$", SAMBAServer);
404
405 snprintf(subcmd, sizeof(subcmd),
406 "mkdir W32X86;"
407 "put %s W32X86/%s.PPD;"
408 "put %s/drivers/ADOBEPS5.DLL W32X86/ADOBEPS5.DLL;"
409 "put %s/drivers/ADOBEPSU.DLL W32X86/ADOBEPSU.DLL;"
410 "put %s/drivers/ADOBEPSU.HLP W32X86/ADOBEPSU.HLP",
411 ppdfile, dest, datadir, datadir, datadir);
412
413 if ((status = do_samba_command(command, subcmd)) != 0)
414 {
415 fprintf(stderr, "ERROR: Unable to copy Windows printer driver files (%d)!\n",
416 status);
417 unlink(ppdfile);
418 return (4);
419 }
420
421 /*
422 * Do the rpcclient commands needed for the Adobe WinNT drivers...
423 */
424
425 snprintf(subcmd, sizeof(subcmd),
426 "adddriver \"Windows NT x86\" \"%s:ADOBEPS5.DLL:%s.PPD:ADOBEPSU.DLL:ADOBEPSU.HLP:NULL:RAW:NULL\"",
427 dest, dest);
428
429 snprintf(command, sizeof(command), "rpcclient %s", SAMBAServer);
430
431 if ((status = do_samba_command(command, subcmd)) != 0)
432 {
433 fprintf(stderr, "ERROR: Unable to install Windows printer driver files (%d)!\n",
434 status);
435 unlink(ppdfile);
436 return (5);
437 }
438 }
439
440 snprintf(command, sizeof(command), "%s/drivers/ADOBEPS4.DRV", datadir);
441 if (access(command, 0) == 0)
442 {
443 /*
444 * Do the smbclient commands needed for the Adobe Win9x drivers...
445 */
446
447 snprintf(command, sizeof(command), "smbclient //%s/print\\$", SAMBAServer);
448
449 snprintf(subcmd, sizeof(subcmd),
450 "mkdir WIN40;"
451 "put %s WIN40/%s.PPD;"
452 "put %s/drivers/ADFONTS.MFM WIN40/ADFONTS.MFM;"
453 "put %s/drivers/ADOBEPS4.DRV WIN40/ADOBEPS4.DRV;"
454 "put %s/drivers/ADOBEPS4.HLP WIN40/ADOBEPS4.HLP;"
455 "put %s/drivers/DEFPRTR2.PPD WIN40/DEFPRTR2.PPD;"
456 "put %s/drivers/ICONLIB.DLL WIN40/ICONLIB.DLL;"
457 "put %s/drivers/PSMON.DLL WIN40/PSMON.DLL;",
458 ppdfile, dest, datadir, datadir, datadir,
459 datadir, datadir, datadir);
460
461 if ((status = do_samba_command(command, subcmd)) != 0)
462 {
463 fprintf(stderr, "ERROR: Unable to copy Windows printer driver files (%d)!\n",
464 status);
465 unlink(ppdfile);
466 return (6);
467 }
468
469 /*
470 * Do the rpcclient commands needed for the Adobe Win9x drivers...
471 */
472
473 snprintf(command, sizeof(command), "rpcclient %s", SAMBAServer);
474
475 snprintf(subcmd, sizeof(subcmd),
476 "adddriver \"Windows 4.0\" \"%s:ADOBEPS4.DRV:%s.PPD:NULL:ADOBEPS4.HLP:PSMON.DLL:RAW:"
477 "ADOBEPS4.DRV,%s.PPD,ADOBEPS4.HLP,PSMON.DLL,ADFONTS.MFM,DEFPRTR2.PPD,ICONLIB.DLL\"",
478 dest, dest, dest);
479
480 if ((status = do_samba_command(command, subcmd)) != 0)
481 {
482 fprintf(stderr, "ERROR: Unable to install Windows printer driver files (%d)!\n",
483 status);
484 unlink(ppdfile);
485 return (7);
486 }
487 }
488
489 unlink(ppdfile);
490
491 /*
492 * Finally, associate the drivers we just added with the queue...
493 */
494
495 snprintf(command, sizeof(command), "rpcclient %s", SAMBAServer);
496
497 snprintf(subcmd, sizeof(subcmd), "setdriver %s %s", dest, dest);
498
499 if ((status = do_samba_command(command, subcmd)) != 0)
500 {
501 fprintf(stderr, "ERROR: Unable to install Windows printer driver files (%d)!\n",
502 status);
503 return (8);
504 }
505
506 return (0);
507 }
508
509
510 /*
511 * 'usage()' - Show program usage and exit...
512 */
513
514 void
515 usage()
516 {
517 puts("Usage: cupsaddsmb [options] printer1 ... printerN");
518 puts(" cupsaddsmb [options] -a");
519 puts("");
520 puts("Options:");
521 puts(" -H samba-server Use the named SAMBA server");
522 puts(" -U samba-user Authenticate using the named SAMBA user");
523 puts(" -a Export all printers");
524 puts(" -h cups-server Use the named CUPS server");
525 puts(" -v Be verbose (show commands)");
526 exit(1);
527 }
528
529
530 /*
531 * End of "$Id: cupsaddsmb.c,v 1.14 2002/12/17 19:00:20 swdev Exp $".
532 */