// Deletes a table to the server. This function is synchronous and does not use // a worker. // // server - The server. // header - The message header. // table - The table the message is working against // input - The input file stream. // output - The output file stream. // // Returns 0 if successful, otherwise returns -1. int sky_delete_table_message_process(sky_server *server, sky_message_header *header, sky_table *_table, FILE *input, FILE *output) { int rc = 0; size_t sz; sky_delete_table_message *message = NULL; sky_table *table = NULL; bstring path = NULL; check(server != NULL, "Server required"); check(header != NULL, "Message header required"); check(input != NULL, "Input stream required"); check(output != NULL, "Output stream required"); (void)_table; struct tagbstring status_str = bsStatic("status"); struct tagbstring ok_str = bsStatic("ok"); // Parse message. message = sky_delete_table_message_create(); check_mem(message); rc = sky_delete_table_message_unpack(message, input); check(rc == 0, "Unable to parse 'delete_table' message"); // Retrieve table reference from server. rc = sky_server_get_table(server, message->name, &table); check(rc == 0, "Unable to find table: %s", bdata(message->name)); check(table != NULL, "Table does not exist: %s", bdata(message->name)); // Detach table first. path = bstrcpy(table->path); check_mem(path); rc = sky_server_close_table(server, table); check(rc == 0, "Unable to close table before deletion"); // If the table exists then delete it. if(sky_file_exists(path)) { rc = sky_file_rm_r(path); check(rc == 0, "Unable to delete table: %s", bdata(path)); } // Return. // {status:"OK"} minipack_fwrite_map(output, 1, &sz); check(sz > 0, "Unable to write output"); check(sky_minipack_fwrite_bstring(output, &status_str) == 0, "Unable to write status key"); check(sky_minipack_fwrite_bstring(output, &ok_str) == 0, "Unable to write status value"); fclose(input); fclose(output); bdestroy(path); sky_delete_table_message_free(message); return 0; error: if(input) fclose(input); if(output) fclose(output); bdestroy(path); sky_delete_table_message_free(message); return -1; }
// Recursively deletes a file or directory. // // path - The path of the file or directory to delete. // // Returns 0 if successful, otherwise returns -1. int sky_file_rm_r(bstring path) { int rc; bstring ent_path = NULL; check(path != NULL, "Path required"); // If path doesn't exist then just ignore it. if(sky_file_exists(path)) { // If the file is a directory then delete its contents first and then // delete it. if(sky_file_is_dir(path)) { // Open directory. DIR *dir = opendir(bdata(path)); check(dir != NULL, "Unable to open directory: %s", bdata(path)); // Remove each file inside directory. struct dirent *ent; while((ent = readdir(dir))) { if(strcmp(ent->d_name, ".") != 0 && strcmp(ent->d_name, "..") != 0) { ent_path = bformat("%s/%s", bdata(path), ent->d_name); check_mem(ent_path); rc = sky_file_rm_r(ent_path); check(rc == 0, "Unable to delete: %s", bdata(ent_path)); bdestroy(ent_path); } } // Close directory. closedir(dir); // Remove directory. remove(bdata(path)); } // If this is a file then delete it. else { rc = sky_file_rm(path); check(rc == 0, "Unable to delete file: %s", bdata(path)); } } return 0; error: bdestroy(ent_path); return -1; }