1 /*
2 * connect.c
3 *
4 * Copyright (C) 2007 Alex deVries
5 *
6 */
7
8 #include <signal.h>
9 #include <errno.h>
10 #include <string.h>
11 #include <sys/socket.h>
12
13 #include "afpfs-ng/afp.h"
14 #include "afpfs-ng/dsi.h"
15 #include "afpfs-ng/utils.h"
16 #include "afpfs-ng/uams_def.h"
17 #include "afpfs-ng/codepage.h"
18 #include "users.h"
19 #include "afpfs-ng/libafpclient.h"
20 #include "server.h"
21
22
23
afp_get_address(void * priv,const char * hostname,unsigned int port,struct sockaddr_in * address)24 int afp_get_address(void * priv, const char * hostname, unsigned int port,
25 struct sockaddr_in * address)
26 {
27 struct hostent *h;
28 h= gethostbyname(hostname);
29 if (!h) {
30 log_for_client(priv,AFPFSD,LOG_ERR,
31 "Could not resolve %s.\n",hostname);
32 goto error;
33 }
34
35 memset(address,0,sizeof(*address));
36 address->sin_family = AF_INET;
37 address->sin_port = htons(port);
38 memcpy(&address->sin_addr,h->h_addr,h->h_length);
39 return 0;
40 error:
41 return -1;
42 }
43
44
45
afp_server_full_connect(void * priv,struct afp_connection_request * req)46 struct afp_server * afp_server_full_connect (void * priv, struct afp_connection_request *req)
47 {
48 int ret;
49 struct sockaddr_in address;
50 struct afp_server * s=NULL;
51 struct afp_server * tmpserver;
52 char signature[AFP_SIGNATURE_LEN];
53 unsigned char versions[SERVER_MAX_VERSIONS];
54 unsigned int uams;
55 char machine_type[AFP_MACHINETYPE_LEN];
56 char server_name[AFP_SERVER_NAME_LEN];
57 char server_name_utf8[AFP_SERVER_NAME_UTF8_LEN];
58 char server_name_printable[AFP_SERVER_NAME_UTF8_LEN];
59 unsigned int rx_quantum;
60 char icon[AFP_SERVER_ICON_LEN];
61
62 if (afp_get_address(priv,req->url.servername, req->url.port,&address)<0)
63 goto error;
64
65 if ((s=find_server_by_address(&address))) goto have_server;
66
67 if ((tmpserver=afp_server_init(&address))==NULL) goto error;
68
69 if ((ret=afp_server_connect(tmpserver,1))<0) {
70 if (ret==-ETIMEDOUT) {
71 log_for_client(priv,AFPFSD,LOG_ERR,
72 "Could not connect, never got a response to getstatus, %s\n",strerror(-ret));
73 } else {
74 log_for_client(priv,AFPFSD,LOG_ERR,
75 "Could not connect, %s\n",strerror(-ret));
76 }
77 afp_server_remove(tmpserver);
78 afp_server_remove(tmpserver);
79 goto error;
80 }
81 loop_disconnect(tmpserver);
82
83 memcpy(icon,&tmpserver->icon,AFP_SERVER_ICON_LEN);
84 memcpy(&versions,&tmpserver->versions,SERVER_MAX_VERSIONS);
85 uams=tmpserver->supported_uams;
86 memcpy(signature,&tmpserver->signature,AFP_SIGNATURE_LEN);
87
88 memcpy(machine_type,&tmpserver->machine_type,AFP_MACHINETYPE_LEN);
89 memcpy(server_name,&tmpserver->server_name,AFP_SERVER_NAME_LEN);
90 memcpy(server_name_utf8,&tmpserver->server_name_utf8,
91 AFP_SERVER_NAME_UTF8_LEN);
92 memcpy(server_name_printable,&tmpserver->server_name_printable,
93 AFP_SERVER_NAME_UTF8_LEN);
94 rx_quantum=tmpserver->rx_quantum;
95
96 afp_server_remove(tmpserver);
97
98 s=find_server_by_signature(signature);
99
100 if (!s) {
101 s = afp_server_init(&address);
102
103 if (afp_server_connect(s,0) !=0) {
104 log_for_client(priv,AFPFSD,LOG_ERR,
105 "Could not connect to server error: %s\n",
106 strerror(errno));
107 goto error;
108 }
109
110 if ((afp_server_complete_connection(priv,
111 s,&address,(unsigned char *) &versions,uams,
112 req->url.username, req->url.password,
113 req->url.requested_version, req->uam_mask))==NULL) {
114 goto error;
115 }
116 s->supported_uams=uams;
117 memcpy(s->signature,signature,AFP_SIGNATURE_LEN);
118 memcpy(s->server_name,server_name,AFP_SERVER_NAME_LEN);
119 memcpy(s->server_name_utf8,server_name_utf8,
120 AFP_SERVER_NAME_UTF8_LEN);
121 memcpy(s->server_name_printable,server_name_printable,
122 AFP_SERVER_NAME_UTF8_LEN);
123 memcpy(s->machine_type,machine_type,AFP_MACHINETYPE_LEN);
124 memcpy(s->icon,icon,AFP_SERVER_ICON_LEN);
125 s->rx_quantum=rx_quantum;
126 }
127 have_server:
128
129 /* Figure out if we're using netatalk */
130 if (strcmp(s->machine_type,"Netatalk")==0)
131 s->server_type=AFPFS_SERVER_TYPE_NETATALK;
132 else if (strcmp(s->machine_type,"Airport")==0)
133 s->server_type=AFPFS_SERVER_TYPE_AIRPORT;
134 else if (strcmp(s->machine_type,"Macintosh")==0)
135 s->server_type=AFPFS_SERVER_TYPE_MACINTOSH;
136 else
137 s->server_type=AFPFS_SERVER_TYPE_UNKNOWN;
138
139 return s;
140 error:
141 if ((s) && (!something_is_mounted(s))) { /* FIXME */
142 afp_server_remove(s);
143 }
144 return NULL;
145 }
146
147