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