mirror of
https://github.com/mabam/afpfs-ng-mac.git
synced 2025-01-06 01:32:09 +00:00
159 lines
4.4 KiB
C
159 lines
4.4 KiB
C
|
|
/*
|
|
* proto_server.c
|
|
*
|
|
* Copyright (C) 2006 Alex deVries
|
|
*
|
|
*/
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "afpfs-ng/dsi.h"
|
|
#include "afpfs-ng/afp.h"
|
|
#include "afpfs-ng/utils.h"
|
|
#include "dsi_protocol.h"
|
|
#include "afpfs-ng/afp_protocol.h"
|
|
#include "afpfs-ng/codepage.h"
|
|
#include "afp_internal.h"
|
|
|
|
int afp_getsrvrparms(struct afp_server *server)
|
|
{
|
|
struct {
|
|
struct dsi_header dsi_header __attribute__((__packed__));
|
|
uint8_t command;
|
|
} __attribute__((__packed__)) afp_getsrvrparms_request;
|
|
|
|
dsi_setup_header(server,&afp_getsrvrparms_request.dsi_header,DSI_DSICommand);
|
|
afp_getsrvrparms_request.command=afpGetSrvrParms;
|
|
dsi_send(server, (char *) &afp_getsrvrparms_request,
|
|
sizeof(afp_getsrvrparms_request),DSI_DEFAULT_TIMEOUT,
|
|
afpGetSrvrParms,NULL);
|
|
return 0;
|
|
}
|
|
|
|
|
|
int afp_getsrvrparms_reply(struct afp_server *server, char * msg, unsigned int size, void * ignore)
|
|
{
|
|
struct {
|
|
struct dsi_header header __attribute__((__packed__));
|
|
uint32_t time __attribute__((__packed__));
|
|
uint8_t numvolumes;
|
|
} __attribute__((__packed__)) *afp_getsrvparm_reply = (void *) msg;
|
|
int i;
|
|
char * p;
|
|
struct afp_volume * newvolumes;
|
|
|
|
if (size < sizeof(*afp_getsrvparm_reply)) {
|
|
log_for_client(NULL,AFPFSD,LOG_WARNING,"getsrvparm_reply response too short\n");
|
|
return -1;
|
|
}
|
|
|
|
server->connect_time = AD_DATE_TO_UNIX(afp_getsrvparm_reply->time);
|
|
|
|
server->num_volumes=afp_getsrvparm_reply->numvolumes;
|
|
|
|
newvolumes=malloc(afp_getsrvparm_reply->numvolumes * sizeof(struct afp_volume));
|
|
|
|
memset(newvolumes,0,afp_getsrvparm_reply->numvolumes * sizeof(struct afp_volume));
|
|
|
|
server->volumes=newvolumes;
|
|
|
|
p=(char *) (&afp_getsrvparm_reply->numvolumes)+1;
|
|
|
|
for (i=0;i<afp_getsrvparm_reply->numvolumes;i++) {
|
|
struct afp_volume * vol;
|
|
vol=&server->volumes[i];
|
|
vol->flags=p[0];
|
|
vol->server=server;
|
|
p++;
|
|
p+=copy_from_pascal(vol->volume_name,p,
|
|
AFP_VOLUME_NAME_LEN)+1;
|
|
|
|
/* Here's the logic; until we call openvol, we should
|
|
* first use the AFP version to figure out what the
|
|
* format of the volume name is. In openvol, we use
|
|
* the volume attributes bit (since we have it then).
|
|
*/
|
|
|
|
if (server->using_version->av_number < 30)
|
|
memcpy(vol->volume_name_printable,
|
|
vol->volume_name,AFP_VOLUME_NAME_LEN);
|
|
else
|
|
convert_utf8dec_to_utf8pre(vol->volume_name,
|
|
strlen(vol->volume_name),
|
|
vol->volume_name_printable,
|
|
AFP_VOLUME_NAME_UTF8_LEN);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int afp_getsrvrmsg_reply(struct afp_server *server, char *buf, unsigned int size, void * other)
|
|
{
|
|
struct afp_getsrvrmsg_reply_packet {
|
|
struct dsi_header dsi_header __attribute__((__packed__));
|
|
uint16_t messagetype;
|
|
uint16_t messagebitmap;
|
|
} __attribute__((__packed__)) * afp_getsrvrmsg_reply = (void *) buf;
|
|
|
|
char * mesg = other, * src;
|
|
|
|
if (size < sizeof(struct afp_getsrvrmsg_reply_packet)) {
|
|
log_for_client(NULL,AFPFSD,LOG_WARNING,"getsrvrmsg response too short\n");
|
|
return -1;
|
|
}
|
|
|
|
src=buf + (sizeof(struct afp_getsrvrmsg_reply_packet));
|
|
|
|
if (ntohs(afp_getsrvrmsg_reply->messagebitmap) & AFP_GETSRVRMSG_UTF8)
|
|
copy_from_pascal_two(mesg,src,200);
|
|
else
|
|
copy_from_pascal(mesg,src,200);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int afp_getsrvrmsg(struct afp_server *server, unsigned short messagetype,
|
|
unsigned char utf8, unsigned char block, char * mesg)
|
|
{
|
|
int rc;
|
|
struct afp_getsrvrmsg_request_packet {
|
|
struct dsi_header dsi_header __attribute__((__packed__));
|
|
uint8_t command;
|
|
uint8_t pad;
|
|
uint16_t messagetype __attribute__((__packed__));
|
|
uint16_t messagebitmap __attribute__((__packed__));
|
|
} __attribute__((__packed__)) afp_getsrvrmsg_request;
|
|
|
|
dsi_setup_header(server,&afp_getsrvrmsg_request.dsi_header,DSI_DSICommand);
|
|
afp_getsrvrmsg_request.command=afpGetSrvrMsg;
|
|
afp_getsrvrmsg_request.pad=0;
|
|
afp_getsrvrmsg_request.messagetype=htons(messagetype);
|
|
afp_getsrvrmsg_request.messagebitmap=
|
|
htons( AFP_GETSRVRMSG_GETMSG | (utf8 ? AFP_GETSRVRMSG_UTF8:0));
|
|
/* Get the message, and yes, we support UTF8 */
|
|
rc=dsi_send(server, (char *) &afp_getsrvrmsg_request,
|
|
sizeof(afp_getsrvrmsg_request),block,afpGetSrvrMsg,(void *) mesg);
|
|
|
|
return rc;
|
|
}
|
|
|
|
int afp_zzzzz(struct afp_server *server)
|
|
{
|
|
|
|
struct {
|
|
struct dsi_header dsi_header __attribute__((__packed__));
|
|
uint8_t command;
|
|
uint8_t pad;
|
|
uint32_t reserved;
|
|
} __attribute__((__packed__)) request;
|
|
|
|
dsi_setup_header(server,&request.dsi_header,DSI_DSICommand);
|
|
request.command=afpZzzzz;
|
|
request.pad=0;
|
|
request.reserved=0;
|
|
return dsi_send(server, (char *) &request,
|
|
sizeof(request),DSI_DEFAULT_TIMEOUT,afpZzzzz,NULL);
|
|
}
|
|
|