From: Andre Noll Date: Fri, 21 Sep 2007 09:01:13 +0000 (+0200) Subject: Merge commit 'remotes/meins/v0.3' into v0.3 X-Git-Tag: v0.3.0~383 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=2c679eeb8bbc93220f85403eca6e9380dc624a6a;hp=f9a064539e63c9d57702822d9d844c8ef04e9bcf Merge commit 'remotes/meins/v0.3' into v0.3 --- diff --git a/Makefile.in b/Makefile.in index 0cce0a77..cd2f9c3e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -97,7 +97,7 @@ dbadm_objs = dbadm.o exec.o close_on_fork.o string.o fade_objs = fade.cmdline.o fade.o exec.o close_on_fork.o string.o fd.o krell_objs = krell.o string.o slider_objs = slider.o string.o -fsck_objs = osl.o rbtree.o fsck.o string.o sha1.o +fsck_objs = osl.o rbtree.o fsck.o string.o sha1.o fsck.cmdline.o *.o: para.h config.h gcc-compat.h @@ -139,10 +139,11 @@ grab_client.cmdline.h grab_client.cmdline.c: grab_client.ggo %.cmdline.h %.cmdline.c: %.ggo case $< in client.ggo) O="--unamed-opts=command";; \ audioc.ggo) O="--unamed-opts=command";; \ + fsck.ggo) O="--unamed-opts=table";; \ esac; \ + echo "$O"; if test $< != fsck.ggo; then O="$$O --conf-parser "; fi; \ gengetopt $$O \ --no-handle-version \ - --conf-parser \ --file-name=$(*F).cmdline \ --func-name $(*F)_cmdline_parser \ --arg-struct-name=$(*F)_args_info \ @@ -245,8 +246,8 @@ para_fade: $(fade_objs) para_server: @server_objs@ $(CC) -o $@ @server_objs@ @server_ldflags@ -para_fsck: $(fsck_objs) - $(CC) -o $@ $(fsck_objs) -lssl +para_fsck: @fsck_objs@ + $(CC) -o $@ @fsck_objs@ @fsck_ldflags@ para_sdl_gui: $(sdl_gui_objs) $(CC) -o $@ $(sdl_gui_objs) -lSDL_image diff --git a/afs_common.c b/afs_common.c index 72be6a9d..17b4e16f 100644 --- a/afs_common.c +++ b/afs_common.c @@ -7,7 +7,12 @@ /** \file afs_common.c Functions common to all audio file selectors. */ +#include +#include + + #include "para.h" +#include "fd.h" #include "server.cmdline.h" #include "afh.h" #include "server.h" @@ -34,29 +39,17 @@ int find_audio_files(const char *dirname, int (*f)(const char *, const char *)) { DIR *dir = NULL; + int ret, ret2, cwd_fd; struct dirent *entry; - /* - * Opening the current directory (".") and calling fchdir() to return - * is usually faster and more reliable than saving cwd in some buffer - * and calling chdir() afterwards (see man 3 getcwd). - */ - int cwd_fd = open(".", O_RDONLY); - struct stat s; - int ret; - if (cwd_fd < 0) - return -E_GETCWD; - ret = -E_CHDIR; - if (chdir(dirname) < 0) - goto out; - ret = -E_OPENDIR; - dir = opendir("."); - if (!dir) - goto out; + ret = para_opendir(dirname, &dir, &cwd_fd); + if (ret < 0) + return ret; /* scan cwd recursively */ while ((entry = readdir(dir))) { mode_t m; char *tmp; + struct stat s; if (!strcmp(entry->d_name, ".")) continue; @@ -87,8 +80,9 @@ int find_audio_files(const char *dirname, int (*f)(const char *, const char *)) out: if (dir) closedir(dir); - if (fchdir(cwd_fd) < 0) - ret = -E_CHDIR; + ret2 = fchdir(cwd_fd); + if (ret2 < 0 && ret >= 0) + ret = ret2; close(cwd_fd); if (ret < 0) PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret)); diff --git a/alsa_write.c b/alsa_write.c index 6f92612a..3ad8f5df 100644 --- a/alsa_write.c +++ b/alsa_write.c @@ -12,15 +12,16 @@ * based on the vplay program by Michael Beck. */ +#include +#include +#include + #include "para.h" #include "fd.h" #include "string.h" #include "list.h" #include "sched.h" #include "write.h" - -#include - #include "alsa_write.cmdline.h" #include "error.h" diff --git a/audioc.c b/audioc.c index 15faebf1..66ff2a26 100644 --- a/audioc.c +++ b/audioc.c @@ -6,6 +6,9 @@ /** \file audioc.c the client program used to connect to para_audiod */ +#include +#include + #include "audioc.cmdline.h" #include "para.h" #include "error.h" diff --git a/audiod.c b/audiod.c index 5e0ff8d4..1fdbea75 100644 --- a/audiod.c +++ b/audiod.c @@ -5,6 +5,8 @@ */ /** \file audiod.c the paraslash's audio daemon */ +#include +#include #include "para.h" #include "error.h" diff --git a/audiod_command.c b/audiod_command.c index ea8c1a58..d424cf2e 100644 --- a/audiod_command.c +++ b/audiod_command.c @@ -6,8 +6,10 @@ /** \file audiod_command.c commands for para_audiod */ -#include "para.h" +#include +#include +#include "para.h" #include "audiod.cmdline.h" #include "list.h" #include "close_on_fork.h" diff --git a/client_common.c b/client_common.c index d950d2d7..7c93b917 100644 --- a/client_common.c +++ b/client_common.c @@ -6,6 +6,9 @@ /** \file client_common.c common functions of para_client and para_audiod */ +#include +#include + #include "para.h" #include "error.h" #include "list.h" diff --git a/command.c b/command.c index 212a1800..072b972c 100644 --- a/command.c +++ b/command.c @@ -6,9 +6,12 @@ /** \file command.c does client authentication and executes server commands */ -#include /* gettimeofday */ -#include "para.h" /* gettimeofday */ +#include +#include +#include +#include +#include "para.h" #include "server.cmdline.h" #include "afs_common.h" #include "afh.h" @@ -16,7 +19,6 @@ #include "vss.h" #include "send.h" #include "rc4.h" -#include #include "error.h" #include "net.h" #include "daemon.h" diff --git a/configure.ac b/configure.ac index 1c9bee43..1c7925db 100644 --- a/configure.ac +++ b/configure.ac @@ -124,6 +124,10 @@ client_cmdline_objs="client.cmdline" client_errlist_objs="client net string crypt fd sched stdin stdout client_common" client_ldflags="" +fsck_cmdline_objs="fsck.cmdline" +fsck_errlist_objs="osl rbtree fsck string sha1 fd" + + ########################################################################### ssl dnl @synopsis CHECK_SSL dnl @@ -173,6 +177,7 @@ CHECK_SSL($enable_ssldir) server_ldflags="$srver_ldflags $SSL_LDFLAGS $SSL_LIBS" client_ldflags="$client_ldflags $SSL_LDFLAGS $SSL_LIBS" audiod_ldflags="$audiod_ldflags $SSL_LDFLAGS $SSL_LIBS" +fsck_ldflags="$fsck_ldflags $SSL_LDFLAGS $SSL_LIBS" ########################################################################### ucred AC_MSG_CHECKING(for struct ucred) @@ -524,6 +529,7 @@ audiod_objs="$audiod_cmdline_objs $audiod_errlist_objs" server_objs="$server_cmdline_objs $server_errlist_objs" write_objs="$write_cmdline_objs $write_errlist_objs" client_objs="$client_cmdline_objs $client_errlist_objs" +fsck_objs="$fsck_cmdline_objs $fsck_errlist_objs" audioc_objs="$audioc_cmdline_objs $audioc_errlist_objs" AC_SUBST(recv_objs, add_dot_o($recv_objs)) @@ -556,6 +562,11 @@ AC_SUBST(client_ldflags, $client_ldflags) AC_DEFINE_UNQUOTED(INIT_CLIENT_ERRLISTS, objlist_to_errlist($client_errlist_objs), errors used by para_client) +AC_SUBST(fsck_objs, add_dot_o($fsck_objs)) +AC_SUBST(fsck_ldflags, $fsck_ldflags) +AC_DEFINE_UNQUOTED(INIT_FSCK_ERRLISTS, + objlist_to_errlist($fsck_errlist_objs), errors used by para_fsck) + AC_SUBST(audioc_objs, add_dot_o($audioc_objs)) AC_DEFINE_UNQUOTED(INIT_AUDIOC_ERRLISTS, objlist_to_errlist($audioc_errlist_objs), errors used by para_audioc) diff --git a/dccp.c b/dccp.c index 62de4f7d..52782732 100644 --- a/dccp.c +++ b/dccp.c @@ -11,6 +11,9 @@ * (C) 2005 Ian McDonald */ +#include +#include + #include "para.h" #include "error.h" #include "dccp.h" diff --git a/dccp_recv.c b/dccp_recv.c index 2f946fc6..47351afb 100644 --- a/dccp_recv.c +++ b/dccp_recv.c @@ -11,6 +11,9 @@ * (C) 2005 Ian McDonald */ +#include +#include + #include "para.h" #include "error.h" #include "dccp.h" diff --git a/dccp_send.c b/dccp_send.c index 3509d5d8..c506fd96 100644 --- a/dccp_send.c +++ b/dccp_send.c @@ -11,6 +11,9 @@ * (C) 2005 Ian McDonald */ +#include +#include + #include "para.h" #include "error.h" #include "afh.h" diff --git a/error.h b/error.h index 98b702c4..7d2424cf 100644 --- a/error.h +++ b/error.h @@ -74,6 +74,7 @@ enum para_subsystem { SS_PLAYLIST, SS_SHA1, SS_RBTREE, + SS_FSCK, NUM_SS }; @@ -94,9 +95,13 @@ enum para_subsystem { extern const char **para_errlist[]; /** \endcond */ +#define FSCK_ERRORS \ + PARA_ERROR(FSCK_SYNTAX, "fsck syntax error"), \ + PARA_ERROR(RANGE_VIOLATION, "range violation detected, very bad"), \ + PARA_ERROR(NOT_A_REGULAR_FILE, "not a regular file"), \ + + #define OSL_ERRORS \ - PARA_ERROR(OSL_OPENDIR, "can not open directory"), \ - PARA_ERROR(OSL_CHDIR, "failed to change directory"), \ PARA_ERROR(BAD_DB_DIR, "invalid database directory"), \ PARA_ERROR(NO_COLUMN_DESC, "missing column description"), \ PARA_ERROR(BAD_NAME, "invalid name for a column/table"), \ @@ -116,26 +121,18 @@ extern const char **para_errlist[]; PARA_ERROR(BAD_SIZE, "invalid size specified"), \ PARA_ERROR(TRUNC, "failed to truncate file"), \ PARA_ERROR(UNLINK, "failed to remove file"), \ - PARA_ERROR(EXIST, "file or directory already exists"), \ - PARA_ERROR(ISDIR, "error: is a directory"), \ PARA_ERROR(NOTDIR, "error: not a directory"), \ - PARA_ERROR(NOENT, "no such file or directory"), \ - PARA_ERROR(OSL_PERM, "permission denied"), \ PARA_ERROR(BAD_TABLE, "table not open"), \ - PARA_ERROR(BAD_TABLE_HEADER, "table header corruption"), \ PARA_ERROR(BAD_TABLE_DESC, "invalid table description"), \ PARA_ERROR(RB_KEY_EXISTS, "key already exists in rbtree"), \ PARA_ERROR(RB_KEY_NOT_FOUND, "key not found in rbtree"), \ PARA_ERROR(BAD_ROW_NUM, "invalid row number"), \ PARA_ERROR(INDEX_CORRUPTION, "index corruption detected"), \ PARA_ERROR(INVALID_OBJECT, "reference to invalid object"), \ - PARA_ERROR(MKDIR, "failed to create directory"), \ - PARA_ERROR(OPEN, "failed to open file"), \ PARA_ERROR(STAT, "can not stat file"), \ PARA_ERROR(FSTAT, "fstat error"), \ PARA_ERROR(RENAME, "rename failed"), \ PARA_ERROR(EMPTY, "file empty"), \ - PARA_ERROR(NOSPC, "no space left on device"), \ PARA_ERROR(MMAP, "mmap error"), \ PARA_ERROR(MUNMAP, "munmap failed"), \ PARA_ERROR(WRITE, "write error"), \ @@ -146,20 +143,17 @@ extern const char **para_errlist[]; PARA_ERROR(VERSION_MISMATCH, "table version not suppoerted"), \ PARA_ERROR(BAD_COLUMN_NUM, "invalid column number"), \ PARA_ERROR(BAD_TABLE_FLAGS, "invalid flags in table description"), \ - PARA_ERROR(RBTREE_EMPTY, "rbtree is empty"), \ PARA_ERROR(BAD_ROW, "invalid row"), \ - PARA_ERROR(OSL_GETCWD, "can not get current working directory"), \ - PARA_ERROR(OSL_LSTAT, "lstat error"), \ #define RBTREE_ERRORS \ #define AFS_ERRORS \ - PARA_ERROR(AFS_SYNTAX, "afs syntax error"), \ - PARA_ERROR(FORK, "fork error"), \ PARA_ERROR(BAD_TABLE_NAME, "invalid table"), \ PARA_ERROR(INPUT_TOO_LARGE, "input too large for stdin command"), \ + PARA_ERROR(READ, "read error"), \ + PARA_ERROR(ATOL, "failed to convert to long"), \ #define MOOD_ERRORS \ @@ -169,8 +163,6 @@ extern const char **para_errlist[]; PARA_ERROR(MOOD_LOADED, "mood loaded"), \ PARA_ERROR(MOOD_BUSY, "mood is in use"), \ PARA_ERROR(NOT_ADMISSIBLE, "file is not admussible"), \ - PARA_ERROR(READ, "read error"), \ - PARA_ERROR(ATOL, "failed to convert to long"), \ #define ATTRIBUTE_ERRORS \ @@ -401,8 +393,6 @@ extern const char **para_errlist[]; #define AFS_COMMON_ERRORS \ PARA_ERROR(GETCWD, "can not get current working directory"), \ - PARA_ERROR(CHDIR, "can not change directory"), \ - PARA_ERROR(OPENDIR, "can not open directory"), \ PARA_ERROR(LSTAT, "lstat error"), \ @@ -494,6 +484,17 @@ extern const char **para_errlist[]; PARA_ERROR(F_GETFL, "failed to get fd flags"), \ PARA_ERROR(F_SETFL, "failed to set fd flags"), \ PARA_ERROR(FGETS, "fgets error"), \ + PARA_ERROR(EXIST, "file or directory already exists"), \ + PARA_ERROR(ISDIR, "error: is a directory"), \ + PARA_ERROR(NOENT, "no such file or directory"), \ + PARA_ERROR(OPEN_PERM, "open error (permission denied)"), \ + PARA_ERROR(MKDIR_PERM, "mkdir error (permission denied)"), \ + PARA_ERROR(MKDIR, "failed to create directory"), \ + PARA_ERROR(CHDIR, "failed to change directory"), \ + PARA_ERROR(FCHDIR, "fchdir failed"), \ + PARA_ERROR(OPENDIR, "can not open directory"), \ + PARA_ERROR(NOSPC, "no space left on device"), \ + PARA_ERROR(OPEN, "failed to open file"), \ #define WRITE_ERRORS \ @@ -686,6 +687,7 @@ SS_ENUM(BLOB); SS_ENUM(PLAYLIST); SS_ENUM(SHA1); SS_ENUM(RBTREE); +SS_ENUM(FSCK); /** \endcond */ #undef PARA_ERROR /* rest of the world only sees the error text */ diff --git a/fade.c b/fade.c index d9834a2b..38a6517c 100644 --- a/fade.c +++ b/fade.c @@ -6,6 +6,9 @@ /** \file fade.c a volume fader and alarm clock */ +#include +#include + #include "fade.cmdline.h" #include "para.h" #include "fd.h" diff --git a/fd.c b/fd.c index 556f3e96..398bf2ce 100644 --- a/fd.c +++ b/fd.c @@ -6,11 +6,13 @@ /** \file fd.c helper functions for file descriptor handling */ -#include "para.h" +#include +#include #include #include #include +#include "para.h" #include "error.h" /** * check whether a file exists @@ -134,7 +136,7 @@ again: } /** - * *paraslash's wrapper for mmap + * Paraslash's wrapper for mmap. * * \param length number of bytes to mmap * \param prot either PROT_NONE or the bitwise OR of one or more of @@ -157,3 +159,129 @@ void *para_mmap(size_t length, int prot, int flags, int fd, off_t offset) exit(EXIT_FAILURE); } +/** + * Wrapper for the open(2) system call. + * + * \param path The filename. + * \param flags The usual open(2) flags. + * \param mode Specifies the permissions to use. + * + * The mode parameter must be specified when O_CREAT is in the flags, and is ignored + * otherwise. + * + * \return Positive on success, negative on errors. + * + * \sa open(2). + */ +int para_open(const char *path, int flags, mode_t mode) +{ + int ret = open(path, flags, mode); + + if (ret >= 0) + return ret; + switch (errno) { + case EEXIST: + ret = -E_EXIST; + break; + case EISDIR: + ret = -E_ISDIR; + break; + case ENOENT: + ret = -E_NOENT; + break; + case EPERM: + ret = -E_OPEN_PERM; + break; + }; + PARA_ERROR_LOG("failed to open %s: %s\n", path, strerror(errno)); + return ret; +} + +/** + * Save the cwd and open a given directory. + * + * \param dirname Path to the directory to open. + * \param dir Result pointer. + * \param cwd File descriptor of the current working directory. + * + * \return Positive on success, negative on errors. + * + * Opening the current directory (".") and calling fchdir() to return is + * usually faster and more reliable than saving cwd in some buffer and calling + * chdir() afterwards. + * + * If \a cwd is not \p NULL "." is opened and the resulting file descriptor is + * stored in \a cwd. If the function returns success, and \a cwd is not \p + * NULL, the caller must close this file descriptor (probably after calling + * fchdir(*cwd)). + * + * On errors, the function undos everything, so the caller needs neither close + * any files, nor change back to the original working directory. + * + * \sa getcwd(3). + * + */ +int para_opendir(const char *dirname, DIR **dir, int *cwd) +{ + int ret; + + if (cwd) { + ret = para_open(".", O_RDONLY, 0); + if (ret < 0) + return ret; + *cwd = ret; + } + ret = -E_CHDIR; + if (chdir(dirname) < 0) + goto close_cwd; + ret = -E_OPENDIR; + *dir = opendir("."); + if (!*dir) + goto change_to_orig_dir; + return 1; +/* Ignore return value of fchdir() and close(). We're busted anyway. */ +change_to_orig_dir: + if (cwd) + fchdir(*cwd); +close_cwd: + if (cwd) + close(*cwd); + return ret; +} + +/** + * A wrapper for fchdir(). + * + * \param fd An open file descriptor + * + * \return Positive on success, negative on errors. + */ +int para_fchdir(int fd) +{ + if (fchdir(fd) < 0) + return -E_FCHDIR; + return 1; +} + +/** + * A wrapper for mkdir(2). + * + * \param path Name of the directory to create. + * \param mode The permissions to use. + * + * \return positive on success, negative on errors. + */ +int para_mkdir(const char *path, mode_t mode) +{ + if (!mkdir(path, mode)) + return 1; + if (errno == EEXIST) + return -E_EXIST; + if (errno == ENOSPC) + return -E_NOSPC; + if (errno == ENOTDIR) + return -E_NOTDIR; + if (errno == EPERM) + return -E_MKDIR_PERM; + return -E_MKDIR; +} diff --git a/fd.h b/fd.h index 9f553343..9bbf7b57 100644 --- a/fd.h +++ b/fd.h @@ -13,3 +13,7 @@ int mark_fd_nonblock(int fd); void para_fd_set(int fd, fd_set *fds, int *max_fileno); __must_check int para_fgets(char *line, int size, FILE *f); void *para_mmap(size_t length, int prot, int flags, int fd, off_t offset); +int para_open(const char *path, int flags, mode_t mode); +int para_opendir(const char *dirname, DIR **dir, int *cwd); +int para_mkdir(const char *path, mode_t mode); +int para_fchdir(int fd); diff --git a/file_write.c b/file_write.c index 89910345..50d3fae7 100644 --- a/file_write.c +++ b/file_write.c @@ -6,6 +6,9 @@ /** \file file_write.c simple output plugin for testing purposes */ +#include +#include + #include "para.h" #include "list.h" #include "sched.h" diff --git a/filter_chain.c b/filter_chain.c index b3987444..7852220a 100644 --- a/filter_chain.c +++ b/filter_chain.c @@ -6,6 +6,9 @@ /** \file filter_chain.c common helper functions for filter input/output */ +#include +#include + #include "para.h" #include "list.h" #include "sched.h" diff --git a/fsck.c b/fsck.c index bc4083ae..5f95b74f 100644 --- a/fsck.c +++ b/fsck.c @@ -1,18 +1,25 @@ +/* + * Copyright (C) 1997-2007 Andre Noll + * + * Licensed under the GPL v2. For licencing details see COPYING. + */ + +/** \file fsck.c The program used to check an osl table. */ + + +#include +#include + #include "para.h" +#include "fd.h" #include "error.h" #include "osl_core.h" +#include "fsck.cmdline.h" -#define OSL_DUMP_DIR "/tmp/osldump" - -enum errors { - E_FSCK_SYNTAX = 501, - E_RANGE_VIOLATION, - E_NO_DS_FILE, - E_NOT_A_REGULAR_FILE, - E_BAD_HASH_PATH, -}; +static struct fsck_args_info conf; -INIT_STDERR_LOGGING(1); +INIT_FSCK_ERRLISTS; +INIT_STDERR_LOGGING(conf.loglevel_arg); /* taken from git */ signed char hexval_table[256] = { @@ -93,7 +100,8 @@ static int check_range(struct osl_table *t, uint32_t row_num, uint32_t col_num) // PARA_INFO_LOG("obj: %p..%p\n", obj_start, obj_start + obj.size); // PARA_INFO_LOG("map: %p..%p\n", map_start, map_start + col->data_map.size); if (obj_start < map_start || obj_start + obj.size > map_start + col->data_map.size) { - PARA_CRIT_LOG("row %u, col %u: range violation, very bad\n", row_num, col_num); + PARA_CRIT_LOG("range violation in row %u, col %u\n", row_num, + col_num); return -E_RANGE_VIOLATION; } PARA_DEBUG_LOG("col %u: ok\n", col_num); @@ -568,10 +576,6 @@ out: return ret; } -#define FSCK 1 -#define FORCE 1 -#define DUMP 0 - static void set_dummy_contents(struct osl_table_description *desc) { int i; @@ -603,7 +607,7 @@ static int fsck_init(struct osl_table_description *desc, struct osl_table **t) } PARA_INFO_LOG("unmapping index\n"); para_munmap(map.data, map.size); - if (FORCE) + if (conf.force_given) ret = map_table(*t, (MAP_TBL_FL_IGNORE_DIRTY)); else ret = map_table(*t, 0); @@ -864,25 +868,89 @@ out: fsck_cleanup(t); return ret; } -int main(__a_unused int argc, __a_unused char **argv) + +static int check_table(char *base_dir, char *table_name) { + struct osl_table_description desc = { + .column_descriptions = NULL, + .dir = base_dir, + .name = table_name + }; int ret; - struct osl_table_description desc = {.column_descriptions = NULL}; - ret = -E_FSCK_SYNTAX; - if (argc < 3) - goto out; - desc.dir = argv[1]; - desc.name = argv[2]; - if (FSCK) { + if (!conf.no_fsck_given) { ret = fsck(&desc); if (ret < 0) - goto out; + return ret; + } + if (!conf.dump_dir_given || !*conf.dump_dir_arg) + return 1; + return dump_table(conf.dump_dir_arg, &desc); +} + +static int check_all_tables(char *base_dir) +{ + DIR *dir; + struct dirent *entry; + int cwd_fd, ret2, ret = para_opendir(base_dir, &dir, &cwd_fd); + + if (ret < 0) + return ret; + while ((entry = readdir(dir))) { + mode_t m; + struct stat s; + if (!strcmp(entry->d_name, ".")) + continue; + if (!strcmp(entry->d_name, "..")) + continue; + if (lstat(entry->d_name, &s) == -1) + continue; + m = s.st_mode; + if (!S_ISDIR(m)) + continue; + ret = check_table(base_dir, entry->d_name); + if (ret < 0) + break; + } + closedir(dir); + ret2 = para_fchdir(cwd_fd); + if (ret2 < 0 && ret >= 0) + ret = ret2; + close(cwd_fd); + return ret; +} + +int main(__a_unused int argc, char **argv) +{ + int i, ret; + char *base_dir = NULL; + + ret = fsck_cmdline_parser(argc, argv, &conf); + if (ret < 0) { + ret = -E_FSCK_SYNTAX; + goto out; + } + HANDLE_VERSION_FLAG("fsck", conf); + if (conf.base_dir_given) + base_dir = conf.base_dir_arg; + else { + char *home = para_homedir(); + base_dir = make_message("%s/.paraslash/afs_database", home); + free(home); + } + if (!conf.inputs_num) { + ret = check_all_tables(base_dir); + goto out; + } + for (i = 0; i < conf.inputs_num; i++) { + ret = check_table(base_dir, conf.inputs[i]); + if (ret < 0) + break; } - if (DUMP) - ret = dump_table(OSL_DUMP_DIR, &desc); out: + if (!conf.base_dir_given) + free(base_dir); if (ret < 0) - PARA_ERROR_LOG("error %d\n", ret); - return ret < 0? EXIT_FAILURE: EXIT_SUCCESS; + PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret)); + return ret < 0? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/fsck.ggo b/fsck.ggo new file mode 100644 index 00000000..207bc853 --- /dev/null +++ b/fsck.ggo @@ -0,0 +1,47 @@ +option "loglevel" l +#~~~~~~~~~~~~~~~~~~ + +"set loglevel (0-6)" + + int typestr="level" + default="4" + optional + +option "base_dir" b +#~~~~~~~~~~~~~~~~~~ +"Full path to the database directory +containing the table(s) to be checked. +(default='~/.paraslash/afs_database'" + + string typestr="path" + optional + +option "dump_dir" d +#~~~~~~~~~~~~~~~~~~ +"If path is non-empty, para_fsck will write a +dump of all given tables to the specified +path." + + string typestr="path" + optional + default="" + +option "no_fsck" n +#~~~~~~~~~~~~~~~~~ +"Disable fsck mode." + + flag off + +option "force" f +#~~~~~~~~~~~~~~~ +"Force fsck even if the table is dirty. +Ignored if -n is given." + + flag off + +option "dry_run" - +#~~~~~~~~~~~~~~~~~ +"Only report problems, don't try to fix them." + + flag off + diff --git a/grab_client.c b/grab_client.c index 11aed36a..d842cb8a 100644 --- a/grab_client.c +++ b/grab_client.c @@ -11,6 +11,9 @@ * \sa filter_chain filter_chain_info filter */ +#include +#include + #include "para.h" #include "grab_client.cmdline.h" #include "list.h" diff --git a/gui.c b/gui.c index 28291a86..d8e20034 100644 --- a/gui.c +++ b/gui.c @@ -6,6 +6,9 @@ /** \file gui.c ncurses-based interface for paraslash */ +#include +#include + #include "gui.cmdline.h" #include "para.h" #include "gui.h" diff --git a/gui_common.c b/gui_common.c index 6ca226e6..dc3450a8 100644 --- a/gui_common.c +++ b/gui_common.c @@ -1,3 +1,15 @@ +/* + * Copyright (C) 2006-2007 Andre Noll + * + * Licensed under the GPL v2. For licencing details see COPYING. + */ + +/** \file gui_common.c Functions used by the guis of paraslash. */ + + +#include +#include + #include "para.h" #include "string.h" #include "fd.h" diff --git a/http_recv.c b/http_recv.c index f82924d9..71aef76a 100644 --- a/http_recv.c +++ b/http_recv.c @@ -6,6 +6,9 @@ /** \file http_recv.c paraslash's http receiver */ +#include +#include + #include "para.h" #include "error.h" #include "http.h" diff --git a/http_send.c b/http_send.c index 8636d10d..3f03f00b 100644 --- a/http_send.c +++ b/http_send.c @@ -6,6 +6,8 @@ /** \file http_send.c paraslash's http sender */ +#include +#include #include "para.h" #include "server.cmdline.h" diff --git a/osl.c b/osl.c index b1aaf3e5..ab3b8de4 100644 --- a/osl.c +++ b/osl.c @@ -5,13 +5,15 @@ */ /** \file osl.c Object storage layer functions. */ +#include /* readdir() */ +#include + + #include "para.h" #include "error.h" +#include "fd.h" #include "list.h" #include "osl_core.h" -#include /* readdir() */ -#include - /** * A wrapper for lseek(2). * @@ -93,46 +95,6 @@ ssize_t para_write_all(int fd, const void *buf, size_t size) } return 1; } -/** - * Wrapper for the open(2) system call. - * - * \param path The filename. - * \param flags The usual open(2) flags. - * \param mode Specifies the permissions to use. - * - * The mode parameter must be specified when O_CREAT is in the flags, and is ignored - * otherwise. - * - * \return Positive on success, negative on errors. Possible errors: \p - * E_EXIST, \p E_ISDIR, \p E_NOENT, \p E_OSL_PERM. - * - * \sa open(2). - */ -int para_open(const char *path, int flags, mode_t mode) -{ - PARA_DEBUG_LOG("opening %s\n", path); - int ret = open(path, flags, mode); - - if (ret >= 0) - return ret; - switch (errno) { - case EEXIST: - ret = -E_EXIST; - break; - case EISDIR: - ret = -E_ISDIR; - break; - case ENOENT: - ret = -E_NOENT; - break; - case EPERM: - ret = -E_OSL_PERM; - break; - }; - PARA_ERROR_LOG("failed to open %s: %s\n", path, strerror(errno)); - return ret; -} - /** * Open a file, write the given buffer and close the file. * @@ -259,37 +221,22 @@ out: int for_each_file_in_dir(const char *dirname, int (*func)(const char *, const void *), const void *private_data) { - DIR *dir = NULL; + DIR *dir; struct dirent *entry; - /* - * Opening the current directory (".") and calling fchdir() to return - * is usually faster and more reliable than saving cwd in some buffer - * and calling chdir() afterwards (see man 3 getcwd). - */ - int cwd_fd = open(".", O_RDONLY); - struct stat s; - int ret = -1; - -// PARA_DEBUG_LOG("dirname: %s\n", dirname); - if (cwd_fd < 0) - return -E_OSL_GETCWD; - ret = -E_OSL_CHDIR; - if (chdir(dirname) < 0) - goto out; - ret = -E_OSL_OPENDIR; - dir = opendir("."); - if (!dir) - goto out; + int cwd_fd, ret2, ret = para_opendir(dirname, &dir, &cwd_fd); + + if (ret < 0) + return ret; /* scan cwd recursively */ while ((entry = readdir(dir))) { mode_t m; char *tmp; + struct stat s; if (!strcmp(entry->d_name, ".")) continue; if (!strcmp(entry->d_name, "..")) continue; - ret = -E_OSL_LSTAT; if (lstat(entry->d_name, &s) == -1) continue; m = s.st_mode; @@ -311,29 +258,14 @@ int for_each_file_in_dir(const char *dirname, } ret = 1; out: - if (dir) - closedir(dir); - if (fchdir(cwd_fd) < 0 && ret >= 0) - ret = -E_OSL_CHDIR; + closedir(dir); + ret2 = para_fchdir(cwd_fd); + if (ret2 < 0 && ret >= 0) + ret = ret2; close(cwd_fd); return ret; } -int para_mkdir(const char *path, mode_t mode) -{ - if (!mkdir(path, mode)) - return 1; - if (errno == EEXIST) - return -E_EXIST; - if (errno == ENOSPC) - return -E_NOSPC; - if (errno == ENOTDIR) - return -E_NOTDIR; - if (errno == EPERM) - return E_OSL_PERM; - return -E_MKDIR; -} - static int verify_name(const char *name) { if (!name) @@ -652,7 +584,7 @@ static int compare_table_descriptions(struct osl_table *t) ret = -E_BAD_TABLE_FLAGS; if (desc.flags != t->desc->flags) goto out; - ret = E_BAD_COLUMN_NUM; + ret = -E_BAD_COLUMN_NUM; if (desc.num_columns != t->desc->num_columns) goto out; FOR_EACH_COLUMN(i, t->desc, cd1) { @@ -820,8 +752,7 @@ static void unmap_column(struct osl_table *t, unsigned col_num) * \param t Pointer to a mapped table. * \param flags Options for unmapping. * - * \return Positive on success, negative on errors. Possible errors include: - * E_NOT_MAPPED, E_MUNMAP. + * \return Positive on success, negative on errors. * * \sa map_table(), enum osl_close_flags, para_munmap(). */ diff --git a/osl.h b/osl.h index d787564f..b0ad7391 100644 --- a/osl.h +++ b/osl.h @@ -179,12 +179,10 @@ int osl_get_rank(const struct osl_table *t, struct osl_row *r, int for_each_file_in_dir(const char *dirname, int (*func)(const char *, const void *), const void *private_data); -int para_open(const char *pathname, int flags, mode_t mode); int mmap_full_file(const char *filename, int open_mode, struct osl_object *obj); ssize_t para_write_all(int fd, const void *buf, size_t size); int para_lseek(int fd, off_t *offset, int whence); int para_write_file(const char *filename, const void *buf, size_t size); -int para_mkdir(const char *path, mode_t mode); /** * A wrapper for munmap(2). diff --git a/recv.c b/recv.c index 423ccbc2..3a3d1426 100644 --- a/recv.c +++ b/recv.c @@ -6,8 +6,10 @@ /** \file recv.c the stand-alone audio stream receiver */ -#include "para.h" +#include +#include +#include "para.h" #include "list.h" #include "sched.h" #include "recv.h" diff --git a/sched.c b/sched.c index 144eaf6e..a7660f59 100644 --- a/sched.c +++ b/sched.c @@ -6,7 +6,10 @@ /** \file sched.c paraslash's scheduling functions */ +#include /* readdir() */ +#include #include + #include "para.h" #include "ipc.h" #include "fd.h" diff --git a/sdl_gui.c b/sdl_gui.c index d30aad80..c63f9b80 100644 --- a/sdl_gui.c +++ b/sdl_gui.c @@ -6,6 +6,9 @@ /** \file sdl_gui.c SDL-based interface for paraslash */ +#include +#include + #include "para.h" #include "gui_common.h" #include "fd.h" diff --git a/server.c b/server.c index e94de736..d98e9603 100644 --- a/server.c +++ b/server.c @@ -15,6 +15,8 @@ * */ +#include +#include #include "para.h" #include "server.cmdline.h" diff --git a/signal.c b/signal.c index 0abe005c..bf0cd5cc 100644 --- a/signal.c +++ b/signal.c @@ -5,14 +5,14 @@ */ /** \file signal.c signal handling functions */ - +#include +#include +#include #include "para.h" +#include "error.h" #include "fd.h" -#include - -#include "error.h" static int signal_pipe[2]; /** diff --git a/stat.c b/stat.c index 202dff8f..ce6adeda 100644 --- a/stat.c +++ b/stat.c @@ -8,6 +8,11 @@ * \file stat.c functions used for sending/receiving the status of para_server * and para_audiod */ + + +#include +#include + #include "para.h" #include "close_on_fork.h" #include "list.h" diff --git a/stdin.c b/stdin.c index d9f9bd93..83ff48f5 100644 --- a/stdin.c +++ b/stdin.c @@ -6,6 +6,10 @@ /** \file stdin.c functions that deal with reading from stdin */ +#include /* readdir() */ +#include + + #include "para.h" #include "string.h" #include "list.h" diff --git a/stdout.c b/stdout.c index 84f2f7ca..c6160791 100644 --- a/stdout.c +++ b/stdout.c @@ -6,6 +6,9 @@ /** \file stdout.c functions that deal with writing to stdout */ +#include /* readdir() */ +#include + #include "para.h" #include "string.h" #include "list.h" diff --git a/user_list.c b/user_list.c index 18df94b4..8e21b238 100644 --- a/user_list.c +++ b/user_list.c @@ -6,6 +6,9 @@ /** \file user_list.c user handling for para_server */ +#include +#include + #include "para.h" #include "error.h" #include "fd.h" diff --git a/vss.c b/vss.c index 3ba5994b..e6cf5967 100644 --- a/vss.c +++ b/vss.c @@ -11,11 +11,14 @@ * senders. */ +#include /* mmap */ +#include /* gettimeofday */ +#include +#include + #include "para.h" #include "afh.h" #include "server.h" -#include /* mmap */ -#include /* gettimeofday */ #include "server.cmdline.h" #include "afs_common.h" #include "vss.h" diff --git a/write.c b/write.c index 64c08d8b..a3b1de1c 100644 --- a/write.c +++ b/write.c @@ -6,6 +6,9 @@ /** \file write.c Paraslash's standalone wav/raw player */ +#include +#include + #include "para.h" #include "string.h" #include "write.cmdline.h"