Initial import package mtools: Programs for accessing MS-DOS disks without mounting...
[profile/ivi/mtools.git] / floppyd_installtest.c
1 /*  Copyright 1999 Peter Schlaile.
2  *  Copyright 1999-2002,2006,2007,2009 Alain Knaff.
3  *  This file is part of mtools.
4  *
5  *  Mtools is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  Mtools is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with Mtools.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  * Small install-test utility to check if a floppyd-server is running on the
19  * X-Server-Host.
20  *
21  * written by:
22  *
23  * Peter Schlaile
24  *
25  * udbz@rz.uni-karlsruhe.de
26  *
27  */
28
29 #include "sysincludes.h"
30 #include "stream.h"
31 #include "mtools.h"
32 #include "msdos.h"
33 #include "scsi.h"
34 #include "partition.h"
35 #include "floppyd_io.h"
36
37 #ifdef USE_FLOPPYD
38 #include <sys/socket.h>
39 #include <arpa/inet.h>
40 #include <netdb.h>
41
42 /* ######################################################################## */
43
44 typedef unsigned char Byte;
45 typedef unsigned long Dword;
46
47 const char* AuthErrors[] = {
48         "Auth success!",
49         "Auth failed: Packet oversized!",
50         "Auth failed: X-Cookie doesn't match!",
51         "Auth failed: Wrong transmission protocol version!",
52         "Auth failed: Device locked!"
53 };
54
55 #include "byte_dword.h"
56 #include "read_dword.h"
57
58 static int write_dword(int handle, Dword parm)
59 {
60         Byte val[4];
61
62         dword2byte(parm, val);
63
64         if(write(handle, val, 4) < 4)
65                 return -1;
66         return 0;
67 }
68
69
70 /* ######################################################################## */
71
72 static int authenticate_to_floppyd(char fullauth, int sock, char *display, 
73                                    int protoversion)
74 {
75         off_t filelen=0;
76         Byte buf[16];
77         const char *command[] = { "xauth", "xauth", "extract", "-", 0, 0 };
78         char *xcookie = NULL;
79         Dword errcode;
80         int bytesRead;
81
82         if (fullauth) {
83                 command[4] = display;
84
85                 filelen=strlen(display);
86                 filelen += 100;
87
88                 xcookie = (char *) safe_malloc(filelen+4);
89                 filelen = safePopenOut(command, xcookie+4, filelen);
90                 if(filelen < 1)
91                     return AUTH_AUTHFAILED;
92         }
93         dword2byte(4,buf);
94         dword2byte(protoversion,buf+4);
95         if(write(sock, buf, 8) < 8)
96                 return AUTH_IO_ERROR;
97
98         bytesRead = read_dword(sock);
99
100         if (bytesRead != 4 && bytesRead != 12) {
101                 return AUTH_WRONGVERSION;
102         }
103
104
105         errcode = read_dword(sock);
106
107         if (errcode != AUTH_SUCCESS) {
108                 return errcode;
109         }
110
111
112         if(bytesRead == 8) {
113             protoversion = read_dword(sock);
114             read_dword(sock);
115         }
116         
117         fprintf(stderr, "Protocol Version=%d\n", protoversion);
118
119         if (fullauth) {
120                 dword2byte(filelen, (Byte *) xcookie);
121                 if(write(sock, xcookie, filelen+4) < filelen+4)
122                         return AUTH_IO_ERROR;
123
124                 if (read_dword(sock) != 4) {
125                         return AUTH_PACKETOVERSIZE;
126                 }
127
128                 errcode = read_dword(sock);
129         }
130
131         return errcode;
132
133 }
134
135
136 /* ######################################################################## */
137
138 static int get_host_and_port(const char* name, char** hostname, char **display,
139                              short* port)
140 {
141         char* newname = strdup(name);
142         char* p;
143         char* p2;
144
145         p = newname;
146         while (*p != '/' && *p) p++;
147         p2 = p;
148         if (*p) p++;
149         *p2 = 0;
150         
151         *port = atoi(p);
152         if (*port == 0) {
153                 *port = FLOPPYD_DEFAULT_PORT;   
154         }
155
156         *display = strdup(newname);
157
158         p = newname;
159         while (*p != ':' && *p) p++;
160         p2 = p;
161         if (*p) p++;
162         *p2 = 0;
163
164         *port += atoi(p);  /* add display number to the port */
165
166         if (!*newname || strcmp(newname, "unix") == 0) {
167                 free(newname);
168                 newname = strdup("localhost");
169         }
170
171         *hostname = newname;
172         return 1;
173 }
174
175 /*
176  *  * Return the IP address of the specified host.
177  *  */
178 static IPaddr_t getipaddress(char *ipaddr)
179 {
180         
181         struct hostent  *host;
182         IPaddr_t        ip;
183         
184         if (((ip = inet_addr(ipaddr)) == INADDR_NONE) &&
185             (strcmp(ipaddr, "255.255.255.255") != 0)) {
186                 
187                 if ((host = gethostbyname(ipaddr)) != NULL) {
188                         memcpy(&ip, host->h_addr, sizeof(ip));
189                 }
190                 
191                 endhostent();
192         }
193         
194 #ifdef DEBUG
195         fprintf(stderr, "IP lookup %s -> 0x%08lx\n", ipaddr, ip);
196 #endif
197           
198         return (ip);
199 }
200
201 /*
202  *  * Connect to the floppyd server.
203  *  */
204 static int connect_to_server(IPaddr_t ip, short port)
205 {
206         
207         struct sockaddr_in      addr;
208         int                     sock;
209         
210         /*
211          * Allocate a socket.
212          */
213         if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
214                 return (-1);
215         }
216         
217         /*
218          * Set the address to connect to.
219          */
220         
221         addr.sin_family = AF_INET;
222         addr.sin_port = htons(port);
223         addr.sin_addr.s_addr = ip;
224         
225         /*
226          * Connect our socket to the above address.
227          */
228         if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
229                 return (-1);
230         }
231
232         /*
233          * Set the keepalive socket option to on.
234          */
235         {
236                 int             on = 1;
237                 setsockopt(STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, 
238                            (char *)&on, sizeof(on));
239
240         }
241         
242         return (sock);
243 }
244
245 int main (int argc, char** argv) 
246 {
247         char* hostname;
248         char* display;
249         char* name;
250         short port;
251         int sock;
252         int reply;
253         int rval;
254         int protoversion;
255         char fullauth = 0;
256         Byte opcode = OP_CLOSE;
257
258         if (argc < 2) {
259                puts("Usage: floppyd_installtest [-f] Connect-String\n"
260                     "-f\tDo full X-Cookie-Authentication");
261                return -1;
262         }
263
264         name = argv[1];
265         if (strcmp(name, "-f") == 0) {
266                 fullauth = 1;
267                 name = argv[2];
268         }
269
270         rval = get_host_and_port(name, &hostname, &display, &port);
271         
272         if (!rval) return -1;
273
274         sock = connect_to_server(getipaddress(hostname), port);
275
276         if (sock == -1) {
277                 fprintf(stderr,
278                         "Can't connect to floppyd server on %s, port %i!\n",
279                         hostname, port);
280                 return -1;
281         }
282         
283         protoversion = FLOPPYD_PROTOCOL_VERSION;
284         while(1) {
285             reply = authenticate_to_floppyd(fullauth, sock, display,
286                                             protoversion);
287             if(protoversion == FLOPPYD_PROTOCOL_VERSION_OLD)
288                 break;
289             if(reply == AUTH_WRONGVERSION) {
290                 /* fall back on old version */
291                 protoversion = FLOPPYD_PROTOCOL_VERSION_OLD;
292                 continue;
293             }
294             break;
295         }
296
297         if (reply != 0) {
298                 fprintf(stderr, 
299                         "Connection to floppyd failed:\n"
300                         "%s\n", AuthErrors[reply]);
301                 return -1;
302         }
303         
304         free(hostname);
305         free(display);
306
307         if(write_dword(sock, 1) < 0) {
308                 fprintf(stderr,
309                         "Short write to floppyd:\n"
310                         "%s\n", strerror(errno));
311         }
312
313         if(write(sock, &opcode, 1) < 0) {
314                 fprintf(stderr,
315                         "Short write to floppyd:\n"
316                         "%s\n", strerror(errno));
317         }
318
319         close(sock);
320
321         return 0;
322 }
323 #endif