• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba/source/client/
1/*
2   Unix SMB/Netbios implementation.
3   Version 2.0.
4   SMB backend for the Common UNIX Printing System ("CUPS")
5   Copyright 1999 by Easy Software Products
6   Copyright Andrew Tridgell 1994-1998
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23#define NO_SYSLOG
24
25#include "includes.h"
26
27/*
28 * Globals...
29 */
30
31extern BOOL		in_client;	/* Boolean for client library */
32extern struct in_addr	ipzero;		/* Any address */
33
34
35/*
36 * Local functions...
37 */
38
39static struct cli_state	*smb_connect(char *, char *, char *, char *, char *);
40static int		smb_print(struct cli_state *, char *, FILE *);
41
42
43/*
44 * 'main()' - Main entry for SMB backend.
45 */
46
47 int				/* O - Exit status */
48 main(int  argc,			/* I - Number of command-line arguments */
49     char *argv[])		/* I - Command-line arguments */
50{
51  int		i;		/* Looping var */
52  int		copies;		/* Number of copies */
53  char		uri[1024],	/* URI */
54		*sep,		/* Pointer to separator */
55		*username,	/* Username */
56		*password,	/* Password */
57		*workgroup,	/* Workgroup */
58		*server,	/* Server name */
59		*printer;	/* Printer name */
60  FILE		*fp;		/* File to print */
61  int		status;		/* Status of LPD job */
62  struct cli_state *cli;	/* SMB interface */
63
64  /* we expect the URI in argv[0]. Detect the case where it is in argv[1] and cope */
65  if (argc > 2 && strncmp(argv[0],"smb://", 6) && !strncmp(argv[1],"smb://", 6)) {
66	  argv++;
67	  argc--;
68  }
69
70
71  if (argc < 6 || argc > 7)
72  {
73    fprintf(stderr, "Usage: %s [DEVICE_URI] job-id user title copies options [file]\n",
74            argv[0]);
75    fputs("       The DEVICE_URI environment variable can also contain the\n", stderr);
76    fputs("       destination printer:\n", stderr);
77    fputs("\n", stderr);
78    fputs("           smb://[username:password@][workgroup/]server/printer\n", stderr);
79    return (1);
80  }
81
82 /*
83  * If we have 7 arguments, print the file named on the command-line.
84  * Otherwise, print data from stdin...
85  */
86
87  if (argc == 6)
88  {
89   /*
90    * Print from Copy stdin to a temporary file...
91    */
92
93    fp     = stdin;
94    copies = 1;
95  }
96  else if ((fp = fopen(argv[6], "rb")) == NULL)
97  {
98    perror("ERROR: Unable to open print file");
99    return (1);
100  }
101  else
102    copies = atoi(argv[4]);
103
104 /*
105  * Fine the URI...
106  */
107
108  if (strncmp(argv[0], "smb://", 6) == 0)
109    strncpy(uri, argv[0], sizeof(uri) - 1);
110  else if (getenv("DEVICE_URI") != NULL)
111    strncpy(uri, getenv("DEVICE_URI"), sizeof(uri) - 1);
112  else
113  {
114    fputs("ERROR: No device URI found in argv[0] or DEVICE_URI environment variable!\n", stderr);
115    return (1);
116  }
117
118  uri[sizeof(uri) - 1] = '\0';
119
120 /*
121  * Extract the destination from the URI...
122  */
123
124  if ((sep = strrchr(uri, '@')) != NULL)
125  {
126    username = uri + 6;
127    *sep++ = '\0';
128
129    server = sep;
130
131   /*
132    * Extract password as needed...
133    */
134
135    if ((password = strchr(username, ':')) != NULL)
136      *password++ = '\0';
137    else
138      password = "";
139  }
140  else
141  {
142    username = "";
143    password = "";
144    server   = uri + 6;
145  }
146
147  if ((sep = strchr(server, '/')) == NULL)
148  {
149    fputs("ERROR: Bad URI - need printer name!\n", stderr);
150    return (1);
151  }
152
153  *sep++ = '\0';
154  printer = sep;
155
156  if ((sep = strchr(printer, '/')) != NULL)
157  {
158   /*
159    * Convert to smb://[username:password@]workgroup/server/printer...
160    */
161
162    *sep++ = '\0';
163
164    workgroup = server;
165    server    = printer;
166    printer   = sep;
167  }
168  else
169    workgroup = NULL;
170
171 /*
172  * Setup the SAMBA server state...
173  */
174
175  setup_logging("smbspool", True);
176
177  TimeInit();
178  charset_initialise();
179
180  in_client = True;   /* Make sure that we tell lp_load we are */
181
182  if (!lp_load(CONFIGFILE, True, False, False))
183  {
184    fprintf(stderr, "ERROR: Can't load %s - run testparm to debug it\n", CONFIGFILE);
185    return (1);
186  }
187
188  if (workgroup == NULL)
189    workgroup = lp_workgroup();
190
191  codepage_initialise(lp_client_code_page());
192
193  load_interfaces();
194
195  if ((cli = smb_connect(workgroup, server, printer, username, password)) == NULL)
196  {
197    perror("ERROR: Unable to connect to SAMBA host");
198    return (1);
199  }
200
201 /*
202  * Queue the job...
203  */
204
205  for (i = 0; i < copies; i ++)
206    if ((status = smb_print(cli, argv[3] /* title */, fp)) != 0)
207      break;
208
209  cli_shutdown(cli);
210
211 /*
212  * Return the queue status...
213  */
214
215  return (status);
216}
217
218
219/*
220 * 'smb_connect()' - Return a connection to a server.
221 */
222
223static struct cli_state *		/* O - SMB connection */
224smb_connect(char *workgroup,		/* I - Workgroup */
225            char *server,		/* I - Server */
226            char *share,		/* I - Printer */
227            char *username,		/* I - Username */
228            char *password)		/* I - Password */
229{
230  struct cli_state	*c;		/* New connection */
231  struct nmb_name	called,		/* NMB name of server */
232			calling;	/* NMB name of client */
233  struct in_addr	ip;		/* IP address of server */
234  pstring		myname;		/* Client name */
235
236
237 /*
238  * Get the names and addresses of the client and server...
239  */
240
241  get_myname(myname);
242
243  ip = ipzero;
244
245  make_nmb_name(&calling, myname, 0x0);
246  make_nmb_name(&called, server, 0x20);
247
248 /*
249  * Open a new connection to the SMB server...
250  */
251
252  if ((c = cli_initialise(NULL)) == NULL)
253  {
254    fputs("ERROR: cli_initialize() failed...\n", stderr);
255    return (NULL);
256  }
257
258  if (!cli_set_port(c, SMB_PORT))
259  {
260    fputs("ERROR: cli_set_port() failed...\n", stderr);
261    return (NULL);
262  }
263
264  if (!cli_connect(c, server, &ip))
265  {
266    fputs("ERROR: cli_connect() failed...\n", stderr);
267    return (NULL);
268  }
269
270  if (!cli_session_request(c, &calling, &called))
271  {
272    fputs("ERROR: cli_session_request() failed...\n", stderr);
273    return (NULL);
274  }
275
276  if (!cli_negprot(c))
277  {
278    fputs("ERROR: SMB protocol negotiation failed\n", stderr);
279    cli_shutdown(c);
280    return (NULL);
281  }
282
283 /*
284  * Do password stuff...
285  */
286
287  if (!cli_session_setup(c, username,
288			 password, strlen(password),
289			 password, strlen(password),
290			 workgroup))
291  {
292    fprintf(stderr, "ERROR: SMB session setup failed: %s\n", cli_errstr(c));
293    return (NULL);
294  }
295
296  if (!cli_send_tconX(c, share, "?????",
297		      password, strlen(password)+1))
298  {
299    fprintf(stderr, "ERROR: SMB tree connect failed: %s\n", cli_errstr(c));
300    cli_shutdown(c);
301    return (NULL);
302  }
303
304 /*
305  * Return the new connection...
306  */
307
308  return (c);
309}
310
311
312/*
313 * 'smb_print()' - Queue a job for printing using the SMB protocol.
314 */
315
316static int				/* O - 0 = success, non-0 = failure */
317smb_print(struct cli_state *cli,	/* I - SMB connection */
318          char             *title,	/* I - Title/job name */
319          FILE             *fp)		/* I - File to print */
320{
321  int	fnum;		/* File number */
322  int	nbytes,		/* Number of bytes read */
323	tbytes;		/* Total bytes read */
324  char	buffer[8192];	/* Buffer for copy */
325
326
327 /*
328  * Open the printer device...
329  */
330
331  if ((fnum = cli_open(cli, title, O_WRONLY | O_CREAT | O_TRUNC, DENY_NONE)) == -1)
332  {
333    fprintf(stderr, "ERROR: %s opening remote file %s\n",
334            cli_errstr(cli), title);
335    return (1);
336  }
337
338 /*
339  * Copy the file to the printer...
340  */
341
342  if (fp != stdin)
343    rewind(fp);
344
345  tbytes = 0;
346
347  while ((nbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0)
348  {
349    if (cli_write(cli, fnum, 0, buffer, tbytes, nbytes) != nbytes)
350    {
351      fprintf(stderr, "ERROR: Error writing file: %s\n", cli_errstr(cli));
352      break;
353    }
354
355    tbytes += nbytes;
356  }
357
358  if (!cli_close(cli, fnum))
359  {
360    fprintf(stderr, "ERROR: %s closing remote file %s\n",
361            cli_errstr(cli), title);
362    return (1);
363  }
364  else
365    return (0);
366}
367