/* * directory.c * * Copyright (C) 2006 Alex deVries * */ #include #include #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" #include "afp_replies.h" int afp_moveandrename(struct afp_volume *volume, unsigned int src_did, unsigned int dst_did, char * src_path, char * dst_path, char *new_name) { struct { struct dsi_header dsi_header __attribute__((__packed__)); uint8_t command; uint8_t pad; uint16_t volid ; uint32_t src_did; uint32_t dst_did ; } __attribute__((__packed__)) * request_packet; char * p; char * msg; struct afp_server * server = volume->server; unsigned int len; unsigned int dlen=0,slen=0,nlen=0; int ret; unsigned short header_len=sizeof_path_header(server); char null_path[255]; if (dst_path==NULL) { null_path[0]='\0'; dlen=0; dst_path=null_path; } else { dlen=strlen(dst_path); } if (src_path) slen=strlen(src_path); if (new_name) nlen=strlen(new_name); len = sizeof(*request_packet) + (3* header_len) + dlen + slen + nlen; if ((msg=malloc(len)) == NULL) return -1; request_packet=(void *) msg; dsi_setup_header(server,&request_packet->dsi_header,DSI_DSICommand); request_packet->command=afpMoveAndRename; request_packet->pad=0; request_packet->volid=htons(volume->volid); request_packet->src_did=htonl(src_did); request_packet->dst_did=htonl(dst_did); p=msg+sizeof(*request_packet); copy_path(server,p,src_path,slen); unixpath_to_afppath(server,p); p+=sizeof_path_header(server)+slen; copy_path(server,p,dst_path,dlen); unixpath_to_afppath(server,p); p+=sizeof_path_header(server)+dlen; copy_path(server,p,new_name,nlen); unixpath_to_afppath(server,p); ret=dsi_send(server, (char *) msg,len,DSI_DEFAULT_TIMEOUT,afpMoveAndRename,NULL); free(msg); return ret; } int afp_rename(struct afp_volume *volume, unsigned int dirid, char * path_from, char * path_to) { struct { struct dsi_header dsi_header __attribute__((__packed__)); uint8_t command; uint8_t pad; uint16_t volid; uint32_t dirid; } __attribute__((__packed__)) * request_packet; char * pathfromptr, *pathtoptr; char * msg; struct afp_server * server = volume->server; unsigned int len = sizeof(*request_packet) + sizeof_path_header(server) + strlen(path_from) + sizeof_path_header(server) + strlen(path_to); int ret; if ((msg=malloc(len)) == NULL) return -1; request_packet=(void *) msg; dsi_setup_header(server,&request_packet->dsi_header,DSI_DSICommand); request_packet->command=afpRename; request_packet->pad=0; request_packet->volid=htons(volume->volid); request_packet->dirid=htonl(dirid); pathfromptr=msg+sizeof(*request_packet); copy_path(server,pathfromptr,path_from,strlen(path_from)); unixpath_to_afppath(server,pathfromptr); pathtoptr=pathfromptr+sizeof_path_header(server) + strlen(path_from); copy_path(server,pathtoptr,path_to,strlen(path_to)); unixpath_to_afppath(server,pathtoptr); ret=dsi_send(server, (char *) msg,len,DSI_DEFAULT_TIMEOUT, afpRename,NULL); free(msg); return ret; } int afp_createdir(struct afp_volume * volume, unsigned int dirid, const char * pathname, unsigned int *did_p) { struct { struct dsi_header dsi_header __attribute__((__packed__)); uint8_t command; uint8_t pad; uint16_t volid; uint32_t dirid; } __attribute__((__packed__)) * request_packet; char * pathptr; char * msg; struct afp_server * server = volume->server; unsigned int len = sizeof(*request_packet) + sizeof_path_header(server) + strlen(pathname); int ret; if ((msg=malloc(len)) == NULL) return -1; pathptr=msg+sizeof(*request_packet); request_packet = (void *) msg; dsi_setup_header(server,&request_packet->dsi_header,DSI_DSICommand); request_packet->command=afpCreateDir; request_packet->pad=0; request_packet->volid=htons(volume->volid); request_packet->dirid=htonl(dirid); copy_path(server,pathptr,pathname,strlen(pathname)); unixpath_to_afppath(server,pathptr); ret=dsi_send(server, (char *) msg,len,DSI_DEFAULT_TIMEOUT, afpCreateDir,(void *)did_p); free(msg); return ret; } int afp_createdir_reply(struct afp_server * server, char * buf, unsigned int size, void * other) { /* We're actually just going to ignore the return bitmap and forkid. */ struct { struct dsi_header header __attribute__((__packed__)); uint16_t bitmap; uint16_t forkid; } __attribute__((__packed__)) * reply_packet = (void *) buf; unsigned short * dir_p = (void *) other; *dir_p = 0; if (reply_packet->header.return_code.error_code) return (reply_packet->header.return_code.error_code); if (sizedsi_header.return_code.error_code) { return reply->dsi_header.return_code.error_code; } if (sizereqcount);i++) { entry = (void *) p; if (p>max) { return -1; } prev=filecur; if ((filecur=malloc(sizeof(struct afp_file_info)))==NULL) { return -1; } if (filebase==NULL) { filebase=filecur; prev=filecur; } else { prev->next=filecur; } parse_reply_block(server,p+sizeof(*entry), ntohs(entry->size),entry->isdir, ntohs(reply->filebitmap), ntohs(reply->dirbitmap), filecur); p+=entry->size; } *x=filebase; return 0; } int afp_enumerateext2_reply(struct afp_server *server, char * buf, unsigned int size, void * other) { struct { struct dsi_header dsi_header __attribute__((__packed__)); uint16_t filebitmap; uint16_t dirbitmap; uint16_t reqcount; } __attribute__((__packed__)) * reply = (void *) buf; struct sEntry{ uint16_t size; uint8_t isdir; uint8_t pad; } __attribute__((__packed__)) * entry; char * p = buf + sizeof(*reply); int i; //char *max=buf+size; struct afp_file_info * filebase = NULL, *filecur = NULL, *new_file = NULL, **x = (struct afp_file_info **) other; if (reply->dsi_header.return_code.error_code) { return reply->dsi_header.return_code.error_code; } if (sizereqcount);i++) { if ((new_file=malloc(sizeof(struct afp_file_info)))==NULL) { return -1; } new_file->next=NULL; if (filecur) { filecur->next=new_file; filecur=new_file; } else { filebase=new_file; filecur=new_file; } entry = (struct sEntry *)p; parse_reply_block(server,p+sizeof(*entry), ntohs(entry->size),entry->isdir, ntohs(reply->filebitmap), ntohs(reply->dirbitmap), filecur); p+=ntohs(entry->size); } *x=filebase; return 0; } int afp_enumerate( struct afp_volume * volume, unsigned int dirid, unsigned int filebitmap, unsigned int dirbitmap, unsigned short reqcount, unsigned short startindex, char * pathname, struct afp_file_info ** file_p) { struct { struct dsi_header dsi_header __attribute__((__packed__)); uint8_t command; uint8_t pad; uint16_t volid; uint32_t dirid; uint16_t filebitmap; uint16_t dirbitmap; uint16_t reqcount; uint16_t startindex; uint16_t maxreplysize; } __attribute__((__packed__)) * afp_enumerate_request_packet; unsigned short len; char * data; int rc; struct afp_file_info * files = NULL; struct afp_server * server = volume->server; char * path; len = sizeof_path_header(server) + strlen(pathname) + sizeof(*afp_enumerate_request_packet); if ((data=malloc(len))==NULL) return -1; path = data+sizeof(*afp_enumerate_request_packet); afp_enumerate_request_packet = (void *) data; dsi_setup_header(server,&afp_enumerate_request_packet->dsi_header,DSI_DSICommand); afp_enumerate_request_packet->command=afpEnumerate; afp_enumerate_request_packet->pad=0; afp_enumerate_request_packet->volid=htons(volume->volid); afp_enumerate_request_packet->dirid=htonl(dirid); afp_enumerate_request_packet->filebitmap=htons(filebitmap); afp_enumerate_request_packet->dirbitmap=htons(dirbitmap); afp_enumerate_request_packet->reqcount=htons(reqcount); afp_enumerate_request_packet->startindex=htons(startindex); afp_enumerate_request_packet->maxreplysize=htons(5280); copy_path(server,path,pathname,strlen(pathname)); unixpath_to_afppath(server,path); rc=dsi_send(server, (char *) data,len,DSI_DEFAULT_TIMEOUT, afpEnumerate,(void **) &files); *file_p = files; free(data); return rc; } int afp_enumerateext2( struct afp_volume * volume, unsigned int dirid, unsigned int filebitmap, unsigned int dirbitmap, unsigned short reqcount, unsigned long startindex, char * pathname, struct afp_file_info ** file_p) { struct { struct dsi_header dsi_header __attribute__((__packed__)); uint8_t command; uint8_t pad; uint16_t volid; uint32_t dirid; uint16_t filebitmap; uint16_t dirbitmap; uint16_t reqcount; uint32_t startindex; uint32_t maxreplysize; } __attribute__((__packed__)) * afp_enumerateext2_request_packet; unsigned short len; char * data; int rc; struct afp_file_info * files = NULL; struct afp_server * server = volume->server; char * path; len = sizeof_path_header(server) + strlen(pathname) + sizeof(*afp_enumerateext2_request_packet); if ((data=malloc(len))==NULL) return -1; path = data+sizeof(*afp_enumerateext2_request_packet); afp_enumerateext2_request_packet = (void *) data; dsi_setup_header(server,&afp_enumerateext2_request_packet->dsi_header,DSI_DSICommand); afp_enumerateext2_request_packet->command=afpEnumerateExt2; afp_enumerateext2_request_packet->pad=0; afp_enumerateext2_request_packet->volid=htons(volume->volid); afp_enumerateext2_request_packet->dirid=htonl(dirid); afp_enumerateext2_request_packet->filebitmap=htons(filebitmap); afp_enumerateext2_request_packet->dirbitmap=htons(dirbitmap); afp_enumerateext2_request_packet->reqcount=htons(reqcount); afp_enumerateext2_request_packet->startindex=htonl(startindex); afp_enumerateext2_request_packet->maxreplysize=htonl(5280); copy_path(server,path,pathname,strlen(pathname)); unixpath_to_afppath(server,path); rc=dsi_send(server, (char *) data,len,DSI_DEFAULT_TIMEOUT, afpEnumerateExt2,(void **) &files); *file_p = files; free(data); return rc; }