]> git.ipfire.org Git - thirdparty/cups.git/blame - backend/socket.c
Added range check for template name copy buffer.
[thirdparty/cups.git] / backend / socket.c
CommitLineData
43e2fc22 1/*
d4c438d4 2 * "$Id: socket.c,v 1.12 2000/02/10 00:57:52 mike Exp $"
43e2fc22 3 *
e73c6c0a 4 * AppSocket backend for the Common UNIX Printing System (CUPS).
43e2fc22 5 *
71fe22b7 6 * Copyright 1997-2000 by Easy Software Products, all rights reserved.
43e2fc22 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" 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
58ec2a95 17 * 44141 Airport View Drive, Suite 204
43e2fc22 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 *
decc1f36 26 * main() - Send a file to the printer or server.
43e2fc22 27 */
28
29/*
30 * Include necessary headers.
31 */
32
e73c6c0a 33#include <cups/cups.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <stdarg.h>
37#include <cups/string.h>
38#include <errno.h>
39#include <sys/types.h>
40#include <sys/stat.h>
41
42#if defined(WIN32) || defined(__EMX__)
43# include <winsock.h>
44#else
45# include <sys/socket.h>
46# include <netinet/in.h>
47# include <arpa/inet.h>
48# include <netdb.h>
49#endif /* WIN32 || __EMX__ */
50
51
52/*
53 * 'main()' - Send a file to the printer or server.
54 *
55 * Usage:
56 *
57 * printer-uri job-id user title copies options [file]
58 */
59
60int /* O - Exit status */
61main(int argc, /* I - Number of command-line arguments (6 or 7) */
62 char *argv[]) /* I - Command-line arguments */
63{
64 char method[255], /* Method in URI */
65 hostname[1024], /* Hostname */
66 username[255], /* Username info (not used) */
67 resource[1024]; /* Resource info (not used) */
68 FILE *fp; /* Print file */
3f9cb6c6 69 int copies; /* Number of copies to print */
e73c6c0a 70 int port; /* Port number */
71 int fd; /* AppSocket */
72 int error; /* Error code (if any) */
73 struct sockaddr_in addr; /* Socket address */
74 struct hostent *hostaddr; /* Host address */
7c88bf41 75 int wbytes; /* Number of bytes written */
76 size_t nbytes, /* Number of bytes read */
e73c6c0a 77 tbytes; /* Total number of bytes written */
7c88bf41 78 char buffer[8192], /* Output buffer */
79 *bufptr; /* Pointer into buffer */
e73c6c0a 80 struct timeval timeout; /* Timeout for select() */
81 fd_set input; /* Input set for select() */
82
83
68edc300 84 if (argc == 1)
85 {
d4c438d4 86 puts("network socket \"Unknown\" \"AppSocket/HP JetDirect\"");
68edc300 87 return (0);
88 }
89 else if (argc < 6 || argc > 7)
e73c6c0a 90 {
91 fprintf(stderr, "Usage: %s job-id user title copies options [file]\n",
92 argv[0]);
93 return (1);
94 }
95
96 /*
97 * If we have 7 arguments, print the file named on the command-line.
98 * Otherwise, send stdin instead...
99 */
100
101 if (argc == 6)
3f9cb6c6 102 {
103 fp = stdin;
104 copies = 1;
105 }
e73c6c0a 106 else
107 {
108 /*
109 * Try to open the print file...
110 */
111
112 if ((fp = fopen(argv[6], "rb")) == NULL)
113 {
decc1f36 114 perror("ERROR: unable to open print file");
e73c6c0a 115 return (1);
116 }
3f9cb6c6 117
118 copies = atoi(argv[4]);
e73c6c0a 119 }
120
121 /*
122 * Extract the hostname and port number from the URI...
123 */
124
125 httpSeparate(argv[0], method, username, hostname, &port, resource);
126
127 if (port == 0)
128 port = 9100; /* Default to HP JetDirect/Tektronix PhaserShare */
129
130 /*
131 * Then try to connect to the remote host...
132 */
133
134 if ((hostaddr = gethostbyname(hostname)) == NULL)
135 {
136 fprintf(stderr, "ERROR: Unable to locate printer \'%s\' - %s",
137 hostname, strerror(errno));
138 return (1);
139 }
140
141 fprintf(stderr, "INFO: Attempting to connect to host %s on port %d\n",
142 hostname, port);
143
144 memset(&addr, 0, sizeof(addr));
145 memcpy(&(addr.sin_addr), hostaddr->h_addr, hostaddr->h_length);
146 addr.sin_family = hostaddr->h_addrtype;
147 addr.sin_port = htons(port);
148
3f9cb6c6 149 while (copies > 0)
e73c6c0a 150 {
3f9cb6c6 151 for (;;)
e73c6c0a 152 {
3f9cb6c6 153 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
e73c6c0a 154 {
2cc18dd2 155 perror("ERROR: Unable to create socket");
3f9cb6c6 156 return (1);
e73c6c0a 157 }
3f9cb6c6 158
159 if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
e73c6c0a 160 {
3f9cb6c6 161 error = errno;
162 close(fd);
163 fd = -1;
164
165 if (error == ECONNREFUSED)
166 {
167 fprintf(stderr, "INFO: Network host \'%s\' is busy; will retry in 30 seconds...\n",
168 hostname);
169 sleep(30);
170 }
171 else
172 {
173 perror("ERROR: Unable to connect to printer");
2cc18dd2 174 sleep(30);
3f9cb6c6 175 }
e73c6c0a 176 }
3f9cb6c6 177 else
178 break;
e73c6c0a 179 }
e73c6c0a 180
e73c6c0a 181 /*
3f9cb6c6 182 * Finally, send the print file...
e73c6c0a 183 */
184
3f9cb6c6 185 copies --;
7c88bf41 186
3f9cb6c6 187 if (fp != stdin)
e73c6c0a 188 {
3f9cb6c6 189 fputs("PAGE: 1 1\n", stderr);
190 rewind(fp);
e73c6c0a 191 }
e73c6c0a 192
3f9cb6c6 193 fputs("INFO: Connected to host, sending print job...\n", stderr);
e73c6c0a 194
3f9cb6c6 195 tbytes = 0;
196 while ((nbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0)
e73c6c0a 197 {
198 /*
3f9cb6c6 199 * Write the print data to the printer...
200 */
201
202 tbytes += nbytes;
203 bufptr = buffer;
204
205 while (nbytes > 0)
206 {
207 if ((wbytes = send(fd, bufptr, nbytes, 0)) < 0)
208 {
209 perror("ERROR: Unable to send print file to printer");
210 break;
211 }
212
213 nbytes -= wbytes;
214 bufptr += wbytes;
215 }
216
217 /*
218 * Check for possible data coming back from the printer...
e73c6c0a 219 */
220
3f9cb6c6 221 timeout.tv_sec = 0;
222 timeout.tv_usec = 0;
223 FD_ZERO(&input);
224 FD_SET(fd, &input);
225 if (select(fd + 1, &input, NULL, NULL, &timeout) > 0)
226 {
227 /*
228 * Grab the data coming back and spit it out to stderr...
229 */
230
231 if ((nbytes = recv(fd, buffer, sizeof(buffer), 0)) > 0)
232 fprintf(stderr, "INFO: Received %u bytes of back-channel data!\n",
233 nbytes);
234 }
235 else if (argc > 6)
236 fprintf(stderr, "INFO: Sending print file, %u bytes...\n", tbytes);
e73c6c0a 237 }
3f9cb6c6 238
239 /*
240 * Close the socket connection...
241 */
242
243 close(fd);
e73c6c0a 244 }
245
246 /*
3f9cb6c6 247 * Close the input file and return...
e73c6c0a 248 */
249
e73c6c0a 250 if (fp != stdin)
251 fclose(fp);
252
253 return (0);
254}
43e2fc22 255
256
257/*
d4c438d4 258 * End of "$Id: socket.c,v 1.12 2000/02/10 00:57:52 mike Exp $".
43e2fc22 259 */