static int delete_directory(const char *directory) { WS_DIR *dir; WS_DIRENT *file; gchar *filename; int ret = 0; /* delete all contents of directory */ if ((dir = ws_dir_open(directory, 0, NULL)) != NULL) { while ((file = ws_dir_read_name(dir)) != NULL) { filename = g_strdup_printf ("%s%s%s", directory, G_DIR_SEPARATOR_S, ws_dir_get_name(file)); if (test_for_directory(filename) != EISDIR) { ret = ws_remove(filename); } else { /* recurse */ ret = delete_directory (filename); } if (ret != 0) { break; } g_free (filename); } ws_dir_close(dir); } if (ret == 0) { ret = ws_remove(directory); } return ret; }
WSLUA_CONSTRUCTOR Dir_remove(lua_State* L) { /* Removes an empty directory. If the directory was removed successfully, a boolean `true` is returned. If the directory cannot be removed because it does not exist, `false` is returned. If the directory cannot be removed because an error occurred, `nil` is returned. This function only removes empty directories. To remove a directory regardless, use `Dir.remove_all()`. @since 1.11.3 */ #define WSLUA_ARG_Dir_remove_NAME 1 /* The name of the directory, possibly including path. */ const char *dir_path = luaL_checkstring(L, WSLUA_ARG_Dir_remove_NAME); int ret; if (test_for_directory (dir_path) == EISDIR) { ret = ws_remove(dir_path); if (ret != 0) { lua_pushnil(L); } else { lua_pushboolean(L, 1); } } else { lua_pushboolean(L, 0); } WSLUA_RETURN(1); /* Boolean `true` on success, `false` if does not exist, `nil` on error. */ }
/* * Write out a list of filters. * * On success, "*pref_path_return" is set to NULL. * On error, "*pref_path_return" is set to point to the pathname of * the file we tried to read - it should be freed by our caller - * and "*errno_return" is set to the error. */ void save_filter_list(filter_list_type_t list_type, char **pref_path_return, int *errno_return) { const gchar *ff_name; gchar *ff_path, *ff_path_new; GList *fl; GList *flpp; filter_def *filt; FILE *ff; guchar *p, c; *pref_path_return = NULL; /* assume no error */ switch (list_type) { case CFILTER_LIST: ff_name = CFILTER_FILE_NAME; fl = capture_filters; break; case DFILTER_LIST: ff_name = DFILTER_FILE_NAME; fl = display_filters; break; default: g_assert_not_reached(); return; } ff_path = get_persconffile_path(ff_name, TRUE); /* Write to "XXX.new", and rename if that succeeds. That means we don't trash the file if we fail to write it out completely. */ ff_path_new = g_strdup_printf("%s.new", ff_path); if ((ff = ws_fopen(ff_path_new, "w")) == NULL) { *pref_path_return = ff_path; *errno_return = errno; g_free(ff_path_new); return; } flpp = g_list_first(fl); while (flpp) { filt = (filter_def *) flpp->data; /* Write out the filter name as a quoted string; escape any quotes or backslashes. */ putc('"', ff); for (p = (guchar *)filt->name; (c = *p) != '\0'; p++) { if (c == '"' || c == '\\') putc('\\', ff); putc(c, ff); } putc('"', ff); /* Separate the filter name and value with a space. */ putc(' ', ff); /* Write out the filter expression and a newline. */ fprintf(ff, "%s\n", filt->strval); if (ferror(ff)) { *pref_path_return = ff_path; *errno_return = errno; fclose(ff); ws_unlink(ff_path_new); g_free(ff_path_new); return; } flpp = flpp->next; } if (fclose(ff) == EOF) { *pref_path_return = ff_path; *errno_return = errno; ws_unlink(ff_path_new); g_free(ff_path_new); return; } #ifdef _WIN32 /* ANSI C doesn't say whether "rename()" removes the target if it exists; the Win32 call to rename files doesn't do so, which I infer is the reason why the MSVC++ "rename()" doesn't do so. We must therefore remove the target file first, on Windows. XXX - ws_rename() should be ws_stdio_rename() on Windows, and ws_stdio_rename() uses MoveFileEx() with MOVEFILE_REPLACE_EXISTING, so it should remove the target if it exists, so this stuff shouldn't be necessary. Perhaps it dates back to when we were calling rename(), with that being a wrapper around Microsoft's _rename(), which didn't remove the target. */ if (ws_remove(ff_path) < 0 && errno != ENOENT) { /* It failed for some reason other than "it's not there"; if it's not there, we don't need to remove it, so we just drive on. */ *pref_path_return = ff_path; *errno_return = errno; ws_unlink(ff_path_new); g_free(ff_path_new); return; } #endif if (ws_rename(ff_path_new, ff_path) < 0) { *pref_path_return = ff_path; *errno_return = errno; ws_unlink(ff_path_new); g_free(ff_path_new); return; } g_free(ff_path_new); g_free(ff_path); }
/* * Write out a list of disabled protocols. * * On success, "*pref_path_return" is set to NULL. * On error, "*pref_path_return" is set to point to the pathname of * the file we tried to read - it should be freed by our caller - * and "*errno_return" is set to the error. */ void save_disabled_protos_list(char **pref_path_return, int *errno_return) { gchar *ff_path, *ff_path_new; FILE *ff; gint i; protocol_t *protocol; void *cookie; *pref_path_return = NULL; /* assume no error */ ff_path = get_persconffile_path(PROTOCOLS_FILE_NAME, TRUE, TRUE); /* Write to "XXX.new", and rename if that succeeds. That means we don't trash the file if we fail to write it out completely. */ ff_path_new = g_strdup_printf("%s.new", ff_path); if ((ff = ws_fopen(ff_path_new, "w")) == NULL) { *pref_path_return = ff_path; *errno_return = errno; g_free(ff_path_new); return; } /* Iterate over all the protocols */ for (i = proto_get_first_protocol(&cookie); i != -1; i = proto_get_next_protocol(&cookie)) { if (!proto_can_toggle_protocol(i)) { continue; } protocol = find_protocol_by_id(i); if (proto_is_protocol_enabled(protocol)) { continue; } /* Write out the protocol name. */ fprintf(ff, "%s\n", proto_get_protocol_filter_name(i)); } if (fclose(ff) == EOF) { *pref_path_return = ff_path; *errno_return = errno; ws_unlink(ff_path_new); g_free(ff_path_new); return; } #ifdef _WIN32 /* ANSI C doesn't say whether "rename()" removes the target if it exists; the Win32 call to rename files doesn't do so, which I infer is the reason why the MSVC++ "rename()" doesn't do so. We must therefore remove the target file first, on Windows. XXX - ws_rename() should be ws_stdio_rename() on Windows, and ws_stdio_rename() uses MoveFileEx() with MOVEFILE_REPLACE_EXISTING, so it should remove the target if it exists, so this stuff shouldn't be necessary. Perhaps it dates back to when we were calling rename(), with that being a wrapper around Microsoft's _rename(), which didn't remove the target. */ if (ws_remove(ff_path) < 0 && errno != ENOENT) { /* It failed for some reason other than "it's not there"; if it's not there, we don't need to remove it, so we just drive on. */ *pref_path_return = ff_path; *errno_return = errno; ws_unlink(ff_path_new); g_free(ff_path_new); return; } #endif if (ws_rename(ff_path_new, ff_path) < 0) { *pref_path_return = ff_path; *errno_return = errno; ws_unlink(ff_path_new); g_free(ff_path_new); return; } g_free(ff_path_new); g_free(ff_path); }