mirror of
https://github.com/mabam/afpfs-ng-mac.git
synced 2025-01-18 04:34:22 +00:00
228 lines
6.1 KiB
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;
|
|
}
|
|
|