mirror of
https://github.com/mabam/afpfs-ng-mac.git
synced 2025-01-19 11:31:48 +00:00
156 lines
4.3 KiB
C
156 lines
4.3 KiB
C
/*
|
|
* connect.c
|
|
*
|
|
* Copyright (C) 2007 Alex deVries
|
|
*
|
|
*/
|
|
|
|
#include <signal.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <sys/socket.h>
|
|
|
|
#include "afpfs-ng/afp.h"
|
|
#include "afpfs-ng/dsi.h"
|
|
#include "afpfs-ng/utils.h"
|
|
#include "afpfs-ng/uams_def.h"
|
|
#include "afpfs-ng/codepage.h"
|
|
#include "users.h"
|
|
#include "afpfs-ng/libafpclient.h"
|
|
#include "server.h"
|
|
|
|
|
|
|
|
struct addrinfo * afp_get_address(void * priv, const char * hostname, unsigned int port)
|
|
{
|
|
char port_string[6];
|
|
struct addrinfo hints;
|
|
struct addrinfo * addresses;
|
|
|
|
memset(&hints, 0, sizeof(struct addrinfo));
|
|
hints.ai_family = PF_UNSPEC;
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
|
|
snprintf(port_string, sizeof(port_string), "%u", port);
|
|
int res = getaddrinfo(hostname, port_string, &hints, &addresses);
|
|
if (res != 0 ) {
|
|
log_for_client(priv,AFPFSD,LOG_ERR,
|
|
"Could not resolve %s.\n",hostname);
|
|
return NULL;
|
|
}
|
|
|
|
return addresses;
|
|
}
|
|
|
|
|
|
|
|
struct afp_server * afp_server_full_connect (void * priv, struct afp_connection_request *req)
|
|
{
|
|
int ret;
|
|
struct addrinfo * address;
|
|
struct afp_server * s=NULL;
|
|
struct afp_server * tmpserver;
|
|
char signature[AFP_SIGNATURE_LEN];
|
|
unsigned char versions[SERVER_MAX_VERSIONS];
|
|
unsigned int uams;
|
|
char machine_type[AFP_MACHINETYPE_LEN];
|
|
char server_name[AFP_SERVER_NAME_LEN];
|
|
char server_name_utf8[AFP_SERVER_NAME_UTF8_LEN];
|
|
char server_name_printable[AFP_SERVER_NAME_UTF8_LEN];
|
|
unsigned int rx_quantum;
|
|
char icon[AFP_SERVER_ICON_LEN];
|
|
|
|
if ((address = afp_get_address(priv,req->url.servername, req->url.port)) == NULL)
|
|
goto error;
|
|
|
|
if ((s=find_server_by_address(address))) goto have_server;
|
|
|
|
if ((tmpserver=afp_server_init(address))==NULL) goto error;
|
|
|
|
if ((ret=afp_server_connect(tmpserver,1))<0) {
|
|
if (ret==-ETIMEDOUT) {
|
|
log_for_client(priv,AFPFSD,LOG_ERR,
|
|
"Could not connect, never got a response to getstatus, %s\n",strerror(-ret));
|
|
} else {
|
|
log_for_client(priv,AFPFSD,LOG_ERR,
|
|
"Could not connect, %s\n",strerror(-ret));
|
|
}
|
|
afp_server_remove(tmpserver);
|
|
goto error;
|
|
}
|
|
loop_disconnect(tmpserver);
|
|
|
|
memcpy(icon,&tmpserver->icon,AFP_SERVER_ICON_LEN);
|
|
memcpy(&versions,&tmpserver->versions,SERVER_MAX_VERSIONS);
|
|
uams=tmpserver->supported_uams;
|
|
memcpy(signature,&tmpserver->signature,AFP_SIGNATURE_LEN);
|
|
|
|
memcpy(machine_type,&tmpserver->machine_type,AFP_MACHINETYPE_LEN);
|
|
memcpy(server_name,&tmpserver->server_name,AFP_SERVER_NAME_LEN);
|
|
memcpy(server_name_utf8,&tmpserver->server_name_utf8,
|
|
AFP_SERVER_NAME_UTF8_LEN);
|
|
memcpy(server_name_printable,&tmpserver->server_name_printable,
|
|
AFP_SERVER_NAME_UTF8_LEN);
|
|
rx_quantum=tmpserver->rx_quantum;
|
|
|
|
afp_server_remove(tmpserver);
|
|
|
|
s=find_server_by_signature(signature);
|
|
|
|
if (!s) {
|
|
s = afp_server_init(address);
|
|
|
|
if (afp_server_connect(s,0) !=0) {
|
|
log_for_client(priv,AFPFSD,LOG_ERR,
|
|
"Could not connect to server error: %s\n",
|
|
strerror(errno));
|
|
goto error;
|
|
}
|
|
|
|
//if our user and password strings are both empty and if
|
|
//the server supports anonymous logins, pretend we only support
|
|
//that as auth will never succeed with such credentials
|
|
if(*req->url.username == '\0' && *req->url.password == '\0'
|
|
&& (uams & UAM_NOUSERAUTHENT)) {
|
|
req->uam_mask = UAM_NOUSERAUTHENT;
|
|
}
|
|
|
|
|
|
if ((afp_server_complete_connection(priv,
|
|
s,address,(unsigned char *) &versions,uams,
|
|
req->url.username, req->url.password,
|
|
req->url.requested_version, req->uam_mask))==NULL) {
|
|
goto error;
|
|
}
|
|
s->supported_uams=uams;
|
|
memcpy(s->signature,signature,AFP_SIGNATURE_LEN);
|
|
memcpy(s->server_name,server_name,AFP_SERVER_NAME_LEN);
|
|
memcpy(s->server_name_utf8,server_name_utf8,
|
|
AFP_SERVER_NAME_UTF8_LEN);
|
|
memcpy(s->server_name_printable,server_name_printable,
|
|
AFP_SERVER_NAME_UTF8_LEN);
|
|
memcpy(s->machine_type,machine_type,AFP_MACHINETYPE_LEN);
|
|
memcpy(s->icon,icon,AFP_SERVER_ICON_LEN);
|
|
s->rx_quantum=rx_quantum;
|
|
}
|
|
have_server:
|
|
|
|
/* Figure out if we're using netatalk */
|
|
if (strcmp(s->machine_type,"Netatalk")==0)
|
|
s->server_type=AFPFS_SERVER_TYPE_NETATALK;
|
|
else if (strcmp(s->machine_type,"Airport")==0)
|
|
s->server_type=AFPFS_SERVER_TYPE_AIRPORT;
|
|
else if (strcmp(s->machine_type,"Macintosh")==0)
|
|
s->server_type=AFPFS_SERVER_TYPE_MACINTOSH;
|
|
else
|
|
s->server_type=AFPFS_SERVER_TYPE_UNKNOWN;
|
|
|
|
return s;
|
|
error:
|
|
if ((s) && (!something_is_mounted(s))) { /* FIXME */
|
|
afp_server_remove(s);
|
|
}
|
|
return NULL;
|
|
}
|
|
|