int checkout(char* dest, int client_id) { FILE * f; string command; string new_dest; string old_dest; strcat(dest,"/cvs"); if ((f = fopen(dest, "r")) != NULL) { client_send("The directory already exists", client_id); client_send(END_OF_TRANSMISSION, client_id); return 0; } new_dest = remove_last_appended(dest); run_command(COMMAND_CP_2, REPOSITORY_PATH, new_dest); command = append_to_path(dest, "/.cvs"); if ((f = fopen(command, "w")) != NULL) { fprintf(f, "%d\n", client_id); fclose(f); } free(command); old_dest = append_to_path(dest, "old"); run_command(COMMAND_RM, old_dest, NULL); client_send("Checked out", client_id); client_send(END_OF_TRANSMISSION, client_id); return 0; }
/* array = '[' [ value { ',' value } ] ']' */ static int parse_array(struct frozen *f) { int i = 0, current_path_len; char buf[20]; CALL_BACK(f, JSON_TYPE_ARRAY_START, NULL, 0); TRY(test_and_skip(f, '[')); { { SET_STATE(f, f->cur - 1, "", 0); while (cur(f) != ']') { snprintf(buf, sizeof(buf), "[%d]", i); i++; current_path_len = append_to_path(f, buf, strlen(buf)); f->cur_name = f->path + strlen(f->path) - strlen(buf) + 1 /*opening brace*/; f->cur_name_len = strlen(buf) - 2 /*braces*/; TRY(parse_value(f)); truncate_path(f, current_path_len); if (cur(f) == ',') f->cur++; } TRY(test_and_skip(f, ']')); truncate_path(f, fstate.path_len); CALL_BACK(f, JSON_TYPE_ARRAY_END, fstate.ptr, f->cur - fstate.ptr); } } return 0; }
static int do_cd(void) { int ret = -1; char name[MAX_FILE_NAME_LENGTH + 1]; char *path; struct directory *dir; if (read_all(STDIN, name, MAX_FILE_NAME_LENGTH) != MAX_FILE_NAME_LENGTH) return -1; name[MAX_FILE_NAME_LENGTH] = '\0'; if ((path = get_path_from_dir(&vfs, pwd)) == NULL) return -1; if ((path = append_to_path(path, name)) == NULL) goto free_path; if ((dir = lookup_dir(&vfs, path, 1)) == NULL) goto free_path; pwd = dir; ret = 0; free_path: free(path); return ret; }
static int do_rm(void) { int ret = -1; char name[MAX_FILE_NAME_LENGTH + 1]; char *path; struct file *file; if (read_all(STDIN, name, MAX_FILE_NAME_LENGTH) != MAX_FILE_NAME_LENGTH) return -1; name[MAX_FILE_NAME_LENGTH] = '\0'; if ((path = get_path_from_dir(&vfs, pwd)) == NULL) return -1; if ((path = append_to_path(path, name)) == NULL) goto free_path; if ((file = lookup_file(&vfs, path, 1)) == NULL) goto free_path; if (delete_file(&vfs, USER_UID, file) != 0) goto free_path; ret = 0; free_path: free(path); return ret; }
static int do_read(void) { int ret = -1; char name[MAX_FILE_NAME_LENGTH + 1]; char *contents, *path; struct file *file; if (read_all(STDIN, name, MAX_FILE_NAME_LENGTH) != MAX_FILE_NAME_LENGTH) return -1; name[MAX_FILE_NAME_LENGTH] = '\0'; if ((path = get_path_from_dir(&vfs, pwd)) == NULL) return -1; if ((path = append_to_path(path, name)) == NULL) goto free_path; if ((file = lookup_file(&vfs, path, 1)) == NULL) goto free_path; if (read_file(&vfs, USER_UID, path, (unsigned char **)&contents) != 0) goto free_path; write_all(STDOUT, contents, file->size); ret = 0; free_path: free(path); return ret; }
int rename_file(char* dest, char* file, char * new_name, int client_id){ string local_old_path, server_old_path, local_new_path, server_new_path; string position, file_folder; string old_repo_path = calloc(1, MAX_PATH_LENGTH); string filename, newname, file_path, new_path; char old_file[MAX_PATH_LENGTH]; char old_new_name[MAX_PATH_LENGTH]; int version; struct dirent entry; struct dirent * result; DIR * old; local_old_path = append_to_path(dest, file); local_new_path = append_to_path(dest, new_name); server_old_path = append_to_path(REPOSITORY_PATH, file); server_new_path = append_to_path(REPOSITORY_PATH, new_name); if (!get_node_from_path(repository_tree, file)) { client_send("File not found in server", client_id); client_send(END_OF_TRANSMISSION, client_id); return NON_EXISTING_FILE; } run_command(COMMAND_MV, local_old_path, local_new_path); run_command(COMMAND_MV, server_old_path, server_new_path); file_folder = remove_last_appended(file); old_repo_path = append_to_path(OLD_REPO_PATH, file_folder); if (!(old = opendir(old_repo_path))) { client_send("File renamed", client_id); client_send(END_OF_TRANSMISSION, client_id); return SUCCESS; } filename = get_last_path(file); newname = get_last_path(new_name); do { readdir_r(old, &entry, &result); if ( strncmp(entry.d_name, ".", 1) && strncmp(entry.d_name, "..", 2)){ if (!strncmp(filename, entry.d_name, strlen(filename))) { position = strchr(entry.d_name, '-'); if (position) { sscanf(position+1, "%d", &version); sprintf(old_new_name, "%s-%d", newname, version); file_path = append_to_path(old_repo_path, entry.d_name); new_path = append_to_path(old_repo_path, old_new_name); run_command(COMMAND_MV, file_path, new_path); } } } } while ( result != NULL ); repository_tree = (fstree_t)new_fstree(); retrieve_tree(REPOSITORY_PATH, repository_tree->root); client_send("File renamed.", client_id); client_send(END_OF_TRANSMISSION, client_id); }
/* pair = key ':' value */ static int parse_pair(struct frozen *f) { int current_path_len; const char *tok; skip_whitespaces(f); tok = f->cur; TRY(parse_key(f)); current_path_len = append_to_path(f, *tok == '"' ? tok + 1 : tok, *tok == '"' ? f->cur - tok - 2 : f->cur - tok); TRY(test_and_skip(f, ':')); TRY(parse_value(f)); truncate_path(f, current_path_len); return 0; }
static int do_write(void) { int ret = -1; char name[MAX_FILE_NAME_LENGTH + 1]; size_t size; char *contents, *path; struct file *file; if (read_all(STDIN, name, MAX_FILE_NAME_LENGTH) != MAX_FILE_NAME_LENGTH) return -1; name[MAX_FILE_NAME_LENGTH] = '\0'; if (read_all(STDIN, &size, sizeof(size)) != sizeof(size)) return -1; if (size > MAX_FILE_SIZE) return -1; if ((contents = calloc(size)) == NULL) return -1; if (read_all(STDIN, contents, size) != size) goto free_contents; if ((path = get_path_from_dir(&vfs, pwd)) == NULL) goto free_contents; if ((path = append_to_path(path, name)) == NULL) goto free_path; if ((file = create_file(&vfs, path)) == NULL) goto free_path; if (write_file(&vfs, USER_UID, path, (unsigned char *)contents, size) != 0) goto free_path; free(path); return 0; free_path: free(path); free_contents: free(contents); return ret; }
/* array = '[' [ value { ',' value } ] ']' */ static int parse_array(struct frozen *f) { int i = 0, current_path_len; char buf[20]; TRY(test_and_skip(f, '[')); { SET_STATE(f, f->cur - 1, JSON_TYPE_ARRAY, "", 0); while (cur(f) != ']') { snprintf(buf, sizeof(buf), "[%d]", i); i++; current_path_len = append_to_path(f, buf, strlen(buf)); TRY(parse_value(f)); truncate_path(f, current_path_len); if (cur(f) == ',') f->cur++; } TRY(test_and_skip(f, ']')); CALL_BACK(f); } return 0; }
static int do_ln(void) { int ret = -1; char name[MAX_FILE_NAME_LENGTH + 1]; size_t size; char *src, *dst; if (read_all(STDIN, name, MAX_FILE_NAME_LENGTH) != MAX_FILE_NAME_LENGTH) return -1; name[MAX_FILE_NAME_LENGTH] = '\0'; if (read_all(STDIN, &size, sizeof(size)) != sizeof(size)) return -1; if (size > MAX_FILE_SIZE) return -1; if ((dst = calloc(size + 1)) == NULL) return -1; if (read_all(STDIN, dst, size) != size) goto free_dst; if ((src = get_path_from_dir(&vfs, pwd)) == NULL) goto free_dst; if ((src = append_to_path(src, name)) == NULL) goto free_src; if (create_symlink(&vfs, USER_UID, src, dst) != 0) goto free_src; ret = 0; free_src: free(src); free_dst: free(dst); return ret; }
static long route_full(long src, long dst) { long next_node,tmp,tmp2,this_node,exit_switch,i; //for each dimension i, if the coordinates differ, then ammend them. //if i is not next_nodej and next_node and dst do not differ at //next_nodej then we need to leave next_node via the intersection of //next_node and dst at these coordinates; otherwise, we choose //arbitrarily, but (try to do it) in a way that balances the usage //of the links in the network. Finally, settle into dstj coordinate //if necessary. next_node=src; for(i=0; i<param_k; i++) { if(coordinates_intersect(src,dst,i)==-1) { if(get_j(next_node)!=i) { //we are changing on dimension i, but if next_node and dst do //not differ at dimension get_j(next_node) (different from i), //then we may need to exit get_j(next_node) via a specific //switch. otherwise pick one arbitrarily. if((exit_switch= coordinates_intersect(next_node,dst,get_j(next_node)))==-1 || exit_switch==param_n) { //THIS DEALS WITH THE param_n return value //coordinates_intersect #ifdef DEBUG if(src!=next_node) { printf("Expected next_node=src in this case\n"); exit(-1); } #endif #ifdef DETERMINISTIC exit_switch=make_det(src,dst)?get_uj(next_node):get_upj(next_node); #else exit_switch=(rand()%2)?get_uj(next_node):get_upj(next_node); #endif } //having chosen an exit switch, we append this switch to the path if((next_node = append_to_path( next_node, (exit_switch==get_uj(next_node))?0:1 ) ) == -1 ) { empty_path(&path,&path_tail); return -1; } //next_node is now a switch and we need to get to the server //on dimension i. } else { //we are changing on dimension get_j(next_node), so the //exit switch is arbitrary, since these dimensions differ. #ifdef DEBUG if(src!=next_node) { printf("Expected next_node=src in this case\n"); exit(-1); } #endif #ifdef DETERMINISTIC if((next_node = append_to_path(next_node, (( make_det(src,dst) )?0:1)))==-1) #else if((next_node = append_to_path(next_node,rand()%2))==-1) #endif { empty_path(&path,&path_tail); return -1; } } //next_node is a switch here if((next_node = append_to_path( next_node, get_port_to_server( next_node, i, (get_j(dst)==i)? #ifdef DETERMINISTIC (make_det(src,dst)? get_uj(dst) : get_upj(dst)) #else ((rand()%2)? get_uj(dst) : get_upj(dst)) #endif : label[dst][i] ) ))==-1) { empty_path(&path,&path_tail); return -1; } } #ifdef DEBUG if(coordinates_intersect(next_node,dst,i)==-1) { empty_path(&path,&path_tail); return -1; } #endif } // Settling step. if(next_node==dst) return 1; //next_node and dst at same switch this_node=next_node; if(((next_node = network[this_node].port[tmp=0].neighbour.node) == network[dst].port[tmp2=1].neighbour.node ) || (network[this_node].port[0].neighbour.node == network[dst].port[tmp2=0].neighbour.node ) || ((next_node = network[this_node].port[tmp=1].neighbour.node) == network[dst].port[tmp2=1].neighbour.node ) || (network[this_node].port[1].neighbour.node) == network[dst].port[tmp2=0].neighbour.node ) { if( ((next_node=append_to_path(this_node,tmp))==-1) || ((next_node= append_to_path(next_node, network[dst].port[tmp2].neighbour.port))==-1) ) { empty_path(&path,&path_tail); return -1; } return 1; } else return 1; }