int appledouble_truncate(struct afp_volume * volume, const char * path, int offset) { char * newpath; int resource = extra_translate(volume, path, &newpath); struct afp_file_info fp; int ret; int dirid; char basename[AFP_MAX_PATH]; switch(resource) { case AFP_META_RESOURCE: get_dirid(volume,newpath,basename,&dirid); ret=afp_openfork(volume,1,dirid,O_WRONLY, basename,&fp); ret=ll_zero_file(volume,fp.forkid,0); if (ret<0) { afp_closefork(volume,fp.forkid); remove_opened_fork(volume,fp); free(newpath); return ret; } afp_closefork(volume,fp.forkid); remove_opened_fork(volume,fp); return 1; case AFP_META_APPLEDOUBLE: free(newpath); return -EISDIR; case AFP_META_FINDERINFO: free(newpath); return 1; case AFP_META_COMMENT: free(newpath); return 1; case AFP_META_SERVER_ICON: free(newpath); return -EPERM; } return 0; }
int ml_truncate(struct afp_volume * vol, const char * path, off_t offset) { int ret=0; char converted_path[AFP_MAX_PATH]; struct afp_file_info *fp; int flags; if (convert_path_to_afp(vol->server->path_encoding, converted_path,(char *) path,AFP_MAX_PATH)) return -EINVAL; /* The approach here is to get the forkid by calling ml_open() (and not afp_openfork). Note the fake afp_file_info used just to grab this forkid. */ if (invalid_filename(vol->server,converted_path)) return -ENAMETOOLONG; if (volume_is_readonly(vol)) return -EACCES; ret=appledouble_truncate(vol,path,offset); if (ret<0) return ret; if (ret==1) return 0; /* Here, we're going to use the untranslated path since it is translated through the ml_open() */ flags=O_WRONLY; if ((ml_open(vol,path,flags,&fp))) { return ret; }; if ((ret=ll_zero_file(vol,fp->forkid,0))) goto out; afp_closefork(vol,fp->forkid); remove_opened_fork(vol, fp); free(fp); out: return -ret; }