int afp_server_connect(struct afp_server *server, int full) { int error = 0; struct timeval t1, t2; struct addrinfo *address; char log_msg[64]; char ip_addr[INET6_ADDRSTRLEN]; address = server->address; while (address) { switch(address->ai_family) { case AF_INET6: inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)address->ai_addr)->sin6_addr), ip_addr, INET6_ADDRSTRLEN); break; case AF_INET: inet_ntop(AF_INET, &(((struct sockaddr_in *)address->ai_addr)->sin_addr), ip_addr, INET6_ADDRSTRLEN); break; default: snprintf(ip_addr, 22, "unknown address family"); break; } snprintf(log_msg, sizeof(log_msg), "trying %s ...", ip_addr); log_for_client(NULL, AFPFSD, LOG_NOTICE, log_msg); server->fd = socket(address->ai_family, address->ai_socktype, address->ai_protocol); if (server->fd >= 0) { if (connect(server->fd, address->ai_addr, address->ai_addrlen) == 0) break; close(server->fd); server->fd = -1; } address = address->ai_next; } if(server->fd < 0) { error = errno; goto error; } server->exit_flag = 0; server->lastrequestid = 0; server->connect_state = SERVER_STATE_CONNECTED; server->used_address = address; add_server(server); add_fd_and_signal(server->fd); if (!full) { return 0; } /* Get the status, and calculate the transmit time. We use this to * calculate our rx quantum. */ gettimeofday(&t1,NULL); if ((error=dsi_getstatus(server))!=0) goto error; gettimeofday(&t2,NULL); afp_server_identify(server); if ((t2.tv_sec - t1.tv_sec) > 0) server->tx_delay= (t2.tv_sec - t1.tv_sec) * 1000; else server->tx_delay= (t2.tv_usec - t1.tv_usec) / 1000; /* Calculate the quantum based on our tx_delay and a threshold */ /* For now, we'll just set a default */ /* This is the default in 10.4.x where x > 7 */ server->rx_quantum = 128 * 1024; return 0; error: return -error; }
struct afp_server * afp_server_complete_connection( void * priv, struct afp_server * server, struct sockaddr_in * address, unsigned char * versions, unsigned int uams, char * username, char * password, unsigned int requested_version, unsigned int uam_mask) { char loginmsg[AFP_LOGINMESG_LEN]; int using_uam; #define LOGIN_ERROR_MESG_LEN 1024 char mesg[LOGIN_ERROR_MESG_LEN]; unsigned int len=0; memset(loginmsg,0,AFP_LOGINMESG_LEN); server->requested_version=requested_version; memcpy(server->username,username,sizeof(server->username)); memcpy(server->password,password,sizeof(server->password)); add_fd_and_signal(server->fd); dsi_opensession(server); /* Figure out what version we're using */ if (((server->using_version= pick_version(versions,requested_version))==NULL)) { log_for_client(priv,AFPFSD,LOG_ERR, "Server cannot handle AFP version %d\n", requested_version); goto error; } using_uam=pick_uam(uams,uam_mask); if (using_uam==-1) { log_for_client(priv,AFPFSD,LOG_ERR, "Could not pick a matching UAM.\n"); goto error; } server->using_uam=using_uam; if (afp_server_login(server,mesg,&len,LOGIN_ERROR_MESG_LEN)) { log_for_client(priv,AFPFSD,LOG_ERR, "Login error: %s\n", mesg); goto error; } if (afp_getsrvrparms(server)) { log_for_client(priv,AFPFSD,LOG_ERR, "Could not get server parameters\n"); goto error; } /* If we haven't gotten a proper date back, so set it to the connect time. */ if (server->connect_time==3094168448) { struct timeval tv; gettimeofday(&tv,NULL); server->connect_time = tv.tv_sec; } afp_getsrvrmsg(server,AFPMESG_LOGIN, ((server->using_version->av_number>=30)?1:0), DSI_DEFAULT_TIMEOUT,loginmsg); /* block */ if (strlen(loginmsg)>0) log_for_client(priv,AFPFSD,LOG_NOTICE, "Login message: %s\n", loginmsg); memcpy(server->loginmesg,loginmsg, AFP_LOGINMESG_LEN); return server; error: afp_server_remove(server); return NULL; }