]>
Commit | Line | Data |
---|---|---|
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 | ||
60 | int /* O - Exit status */ | |
61 | main(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 | */ |