int appledouble_open(struct afp_volume * volume, const char * path, int flags, struct afp_file_info *fp) { char * newpath; int ret; switch((fp->resource = extra_translate(volume, path, &newpath))) { case AFP_META_RESOURCE: if (get_dirid(volume,newpath,fp->basename,&fp->did)<0) { ret=-ENOENT; goto error; } ret=ll_open(volume,newpath,flags,fp); free(newpath); if (ret<0) return ret; return 1; case AFP_META_APPLEDOUBLE: free(newpath); return -EISDIR; case AFP_META_FINDERINFO: if (get_dirid(volume,newpath,fp->basename,&fp->did)<0) return -ENOENT; free(newpath); return 1; case AFP_META_COMMENT: if (get_dirid(volume,newpath,fp->basename,&fp->did)<0) { ret=-ENOENT; goto error; } if (volume->dtrefnum==0) { switch(afp_opendt(volume,&volume->dtrefnum)) { case kFPParamErr: case kFPMiscErr: free(newpath); return -EIO; case kFPNoErr: default: break; } } free(newpath); return 1; case AFP_META_SERVER_ICON: free(newpath); return 1; } return 0; error: free(newpath); return ret; }
int ml_open(struct afp_volume * volume, const char *path, int flags, struct afp_file_info **newfp) { /* FIXME: doesn't handle create properly */ struct afp_file_info * fp ; int ret; unsigned int dirid; char converted_path[AFP_MAX_PATH]; if (convert_path_to_afp(volume->server->path_encoding, converted_path,(char *) path,AFP_MAX_PATH)) return -EINVAL; if (invalid_filename(volume->server,converted_path)) return -ENAMETOOLONG; if (volume_is_readonly(volume) && (flags & (O_WRONLY|O_RDWR|O_TRUNC|O_APPEND|O_CREAT))) return -EACCES; if ((fp=malloc(sizeof(*fp)))==NULL) { return -1; } *newfp=fp; memset(fp,0,sizeof(*fp)); ret=appledouble_open(volume,path,flags,fp); if (ret<0) return ret; if (ret==1) goto out; if (get_dirid(volume,converted_path,fp->basename,&dirid)<0) return -ENOENT; fp->did=dirid; ret=ll_open(volume,converted_path,flags,fp); if (ret<0) goto error; out: return 0; error: free(fp); return ret; }
int app_receive_file(const char* term, const char* file_name) { LOG // start link layer int fd = ll_open(term, RECEIVER); if (fd == -1) { perror("ll_open"); return -1; } int ctrlStart; control_param startParams[2]; if (app_receive_control_packet(fd, &ctrlStart, 2, startParams) != 0) { perror("app_receive_control_packet (start)"); return -1; } if (ctrlStart != CONTROL_FIELD_START) { ERRORF("Control field received (%d) is not CONTROL_FIELD_START", ctrlStart); return -1; } DEBUGF("File size to receive: %d", startParams[0].file_size.size.w); DEBUGF("File name to receive: %d", startParams[1].file_name.name); free(startParams[1].file_name.name); FILE* output_file = fopen(file_name, "wb"); if(output_file == NULL) { perror("ERROR: Opening output file"); return -1; } int total_size_read = 0; int seq_number = -1; while (total_size_read != startParams[0].file_size.size.w) { char* buffer; int length; int seq_number_before = seq_number; if (app_receive_data_packet(fd, &seq_number, &buffer, &length) != 0) { perror("app_receive_data_packet"); free(buffer); return -1; } if (seq_number != 0 && seq_number_before + 1 != seq_number) { ERRORF("Expected sequence number %d but got %d", seq_number_before + 1, seq_number); free(buffer); return -1; } total_size_read += length; fwrite(buffer, sizeof(char), length, output_file); free(buffer); } if (fclose(output_file) != 0) { perror("ERROR: Closing output file"); return -1; } int ctrlEnd; if (app_receive_control_packet(fd, &ctrlEnd, 0, NULL) != 0) { perror("app_receive_control_packet (end)"); return -1; } if (ctrlEnd != CONTROL_FIELD_END) { ERRORF("Control field received (%d) is not CONTROL_FIELD_END", ctrlEnd); return -1; } if (!ll_close(fd)) { perror("ll_close"); return -1; } return 0; }
int app_send_file(const char* term, const char* file_name) { LOG // open file FILE* file = fopen(file_name, "rb"); if (!file) { perror("fopen"); return -1; } // start link layer int fd = ll_open(term, TRANSMITTER); if (fd == -1) { perror("ll_open"); return -1; } int file_size = get_file_size(file); if (file_size == -1) { perror("get_file_size"); return -1; } // build control params control_param paramStartFileSize; paramStartFileSize.type = FIELD_PARAM_TYPE_FILE_SIZE; paramStartFileSize.file_size.size.w = file_size; control_param paramStartFileName; paramStartFileName.type = FIELD_PARAM_TYPE_FILE_NAME; paramStartFileName.file_name.name = (char*)file_name; control_param params[] = { paramStartFileSize, paramStartFileName }; if (app_send_control_packet(fd, CONTROL_FIELD_START, 2, params) != 0) { perror("app_send_control_packet"); return -1; } int i = 0; char* buffer = malloc(MAX_DATA_PACKET_SIZE); size_t read_bytes; size_t write_bytes = 0; while ((read_bytes = fread(buffer, sizeof(char), MAX_DATA_PACKET_SIZE, file)) != 0) { if (app_send_data_packet(fd, (i++) % 255, buffer, read_bytes) == -1) { perror("app_send_data_packet"); free(buffer); return -1; } write_bytes += read_bytes; buffer = memset(buffer, 0, MAX_DATA_PACKET_SIZE); printf("\rProgress: %3d%%", (int)(write_bytes / (float)file_size * 100)); fflush(stdout); } printf("\n"); free(buffer); if (fclose(file) != 0) { perror("fclose"); return -1; } if (app_send_control_packet(fd, CONTROL_FIELD_END, 0, NULL) != 0) { perror("app_send_control_packet"); return -1; } if (!ll_close(fd)) { perror("ll_close"); return -1; } return 0; }