afpfs-ng-mac/lib/proto_desktop.c

228 lines
6.1 KiB
C

/*
* fork.c
*
* Copyright (C) 2006 Alex deVries
*
*/
#include <string.h>
#include <stdlib.h>
#include "afpfs-ng/dsi.h"
#include "afpfs-ng/afp.h"
#include "afpfs-ng/utils.h"
#include "afpfs-ng/afp_protocol.h"
#include "dsi_protocol.h"
/* closedt, addicon, geticoninfo, addappl, removeappl */
int afp_geticon(struct afp_volume * volume , unsigned int filecreator,
unsigned int filetype, unsigned char icontype,
unsigned short length, struct afp_icon * icon)
{
struct {
struct dsi_header dsi_header __attribute__((__packed__));
uint8_t command;
uint8_t pad1;
uint16_t dtrefnum ;
uint32_t filecreator;
uint32_t filetype ;
uint8_t icontype ;
uint8_t pad2;
uint16_t length ;
} __attribute__((__packed__)) request_packet;
dsi_setup_header(volume->server,&request_packet.dsi_header,DSI_DSICommand);
request_packet.command=afpGetIcon;
request_packet.pad1=0;
/* I'm not entirely sure these two should be translated */
request_packet.dtrefnum=htons(volume->dtrefnum);
request_packet.filecreator=htonl(filecreator);
request_packet.filetype=htonl(filetype);
request_packet.icontype=icontype;
request_packet.pad2=0;
request_packet.length=htons(length);
return dsi_send(volume->server, (char *)&request_packet,
sizeof(request_packet),DSI_DEFAULT_TIMEOUT,
afpGetIcon,(void *) icon);
}
int afp_geticon_reply(struct afp_server *server, char * buf, unsigned int size, void * other)
{
struct {
struct dsi_header header __attribute__((__packed__));
} * reply_packet = (void *) buf;
struct afp_icon * icon =other;
unsigned int len=size-sizeof(*reply_packet);
if (size < (sizeof (*reply_packet)+icon->maxsize)) {
log_for_client(NULL,AFPFSD,LOG_WARNING,"getcomment icon is too short\n");
return -1;
}
icon->size=len;
memcpy(icon->data,buf+sizeof(*reply_packet),len);
return 0;
}
int afp_addcomment(struct afp_volume *volume, unsigned int did,
const char * pathname, char * comment, uint64_t *size)
{
struct {
struct dsi_header dsi_header __attribute__((__packed__));
uint8_t command;
uint8_t pad;
uint16_t dtrefnum ;
uint32_t dirid ;
} __attribute__((__packed__)) * request_packet;
unsigned int len=sizeof(*request_packet) +
sizeof_path_header(volume->server)+strlen(pathname)
+ strlen(comment)+1;
char * msg, *p;
int rc;
msg=malloc(len+1);
memset(msg,0,len+1);
p=msg+(sizeof(*request_packet));
request_packet=(void *) msg;
dsi_setup_header(volume->server,&request_packet->dsi_header,DSI_DSICommand);
request_packet->command=afpAddComment;
request_packet->pad=0;
request_packet->dtrefnum=htons(volume->dtrefnum);
request_packet->dirid=htonl(did);
copy_path(volume->server,p,pathname,strlen(pathname));
unixpath_to_afppath(volume->server,p);
p=msg+sizeof(*request_packet) +sizeof_path_header(volume->server)+strlen(pathname);
if (((uintptr_t) p) & 0x1) {
/* Make sure we're on an even boundary */
p++;
len++;
}
copy_to_pascal(p,comment);
*size=strlen(comment);
rc=dsi_send(volume->server, (char *)msg,len,DSI_DEFAULT_TIMEOUT,
afpAddComment,(void *) comment);
free(msg);
return rc;
}
int afp_getcomment(struct afp_volume *volume, unsigned int did,
const char * pathname, struct afp_comment * comment)
{
struct {
struct dsi_header dsi_header __attribute__((__packed__));
uint8_t command;
uint8_t pad;
uint16_t dtrefnum ;
uint32_t dirid ;
} __attribute__((__packed__)) * request_packet;
unsigned int len=sizeof(*request_packet) +
sizeof_path_header(volume->server)+strlen(pathname);
char * msg, *path;
int rc;
msg=malloc(len);
path=msg+(sizeof(*request_packet));
request_packet=(void *) msg;
dsi_setup_header(volume->server,&request_packet->dsi_header,DSI_DSICommand);
request_packet->command=afpGetComment;
request_packet->pad=0;
request_packet->dtrefnum=htons(volume->dtrefnum);
request_packet->dirid=htonl(did);
copy_path(volume->server,path,pathname,strlen(pathname));
unixpath_to_afppath(volume->server,path);
rc=dsi_send(volume->server, (char *)msg,len,DSI_DEFAULT_TIMEOUT,
afpGetComment,(void *) comment);
free(msg);
return rc;
}
int afp_getcomment_reply(struct afp_server *server, char * buf, unsigned int size, void * other)
{
struct {
struct dsi_header header __attribute__((__packed__));
uint8_t commentlen;
} __attribute__((__packed__)) * reply_packet = (void *) buf;
struct afp_comment * comment=other;
unsigned int len;
if (size < sizeof (struct dsi_header)) {
log_for_client(NULL,AFPFSD,LOG_WARNING,
"getcomment response is too short\n");
return -1;
}
len=min(size-sizeof(*reply_packet),comment->maxsize);
len=min(len,reply_packet->commentlen);
memcpy(comment->data,buf+sizeof(*reply_packet),len);
comment->size=len;
return 0;
}
int afp_closedt(struct afp_server * server, unsigned short refnum)
{
struct {
struct dsi_header dsi_header __attribute__((__packed__));
uint8_t command;
uint8_t pad;
uint16_t refnum ;
} __attribute__((__packed__)) request_packet;
dsi_setup_header(server,&request_packet.dsi_header,DSI_DSICommand);
request_packet.command=afpCloseDT;
request_packet.pad=0;
request_packet.refnum=htons(refnum);
return dsi_send(server, (char *) &request_packet,
sizeof(request_packet),DSI_DEFAULT_TIMEOUT,afpCloseDT,NULL);
}
int afp_opendt(struct afp_volume *volume, unsigned short * refnum)
{
struct {
struct dsi_header dsi_header __attribute__((__packed__));
uint8_t command;
uint8_t pad;
uint16_t volid ;
} __attribute__((__packed__)) request_packet;
dsi_setup_header(volume->server,&request_packet.dsi_header,DSI_DSICommand);
request_packet.command=afpOpenDT;
request_packet.pad=0;
request_packet.volid=htons(volume->volid);
return dsi_send(volume->server, (char *) &request_packet,
sizeof(request_packet),DSI_DEFAULT_TIMEOUT,afpOpenDT,
(void *) refnum);
}
int afp_opendt_reply(struct afp_server *server, char * buf, unsigned int size, void * other)
{
struct {
struct dsi_header header __attribute__((__packed__));
uint16_t refnum ;
} __attribute__((__packed__)) * reply_packet = (void *) buf;
unsigned short * refnum = other;
if (size < sizeof (*reply_packet)) {
log_for_client(NULL,AFPFSD,LOG_WARNING,"opendt response is too short\n");
return -1;
}
*refnum=ntohs(reply_packet->refnum);
return 0;
}