From e584774f0883867e296ee0999770850a0689d292 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Thu, 3 Apr 2008 21:59:05 +0000 Subject: [PATCH] - API: change boinc_resolve_filename() so that it detects symbolic links and treats them as a special case. Also, if the virtual file doesn't exist (as in the standalone case) just return zero; otherwise if the app is running standalone and checks the return value, it will error out. NOTE: apps that check the return value of boinc_resolve_filename() won't work on 6.12+ under Unix; recompiling with this change will fix the problem. svn path=/trunk/boinc/; revision=15012 --- checkin_notes | 15 +++++++++++++++ lib/app_ipc.C | 22 ++++++++++++++++++---- lib/filesys.C | 12 ++++++++++-- lib/filesys.h | 1 + 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/checkin_notes b/checkin_notes index 53031f6c2c..c876d0e9b6 100644 --- a/checkin_notes +++ b/checkin_notes @@ -3055,3 +3055,18 @@ Rom April 3 2008 CACreateBOINCAccounts.cpp CACreateBOINCGroups.cpp CAMigrateBOINCData.cpp + +David April 3 2008 + - API: change boinc_resolve_filename() so that it detects symbolic links + and treats them as a special case. + Also, if the virtual file doesn't exist (as in the standalone case) + just return zero; otherwise if the app is running standalone + and checks the return value, it will error out. + + NOTE: apps that check the return value of boinc_resolve_filename() + won't work on 6.12+ under Unix; + recompiling with this change will fix the problem. + + lib/ + app_ipc.C + filesys.C,h diff --git a/lib/app_ipc.C b/lib/app_ipc.C index 3fe22a55b6..65a5aa331a 100644 --- a/lib/app_ipc.C +++ b/lib/app_ipc.C @@ -302,24 +302,38 @@ void APP_CLIENT_SHM::reset_msgs() { memset(shm, 0, sizeof(SHARED_MEM)); } -// resolve "symbolic link" +// Resolve virtual name (in slot dir) to physical path (in project dir). +// Cases: +// - Windows and pre-6.12 Unix: +// virtual name refers to a "soft link" (XML file acting as symbolic link) +// - 6.12+ Unix: +// virtual name is a symbolic link +// - Standalone: physical path is same as virtual name // -int boinc_resolve_filename(const char *virtual_name, char *physical_name, int len) { +int boinc_resolve_filename( + const char *virtual_name, char *physical_name, int len +) { FILE *fp; char buf[512], *p; if (!virtual_name) return ERR_NULL; strlcpy(physical_name, virtual_name, len); +#ifndef _WIN32 + if (is_symlink(virtual_name)) { + return 0; + } +#endif + // Open the link file and read the first line // fp = boinc_fopen(virtual_name, "r"); - if (!fp) return ERR_FOPEN; + if (!fp) return 0; // must initialize buf since fgets() on an empty file won't do anything // buf[0] = 0; - p =fgets(buf, 512, fp); + p =fgets(buf, sizeof(buf), fp); fclose(fp); // If it's the XML tag, return its value, diff --git a/lib/filesys.C b/lib/filesys.C index 2da24e8bc8..c01f89d4db 100644 --- a/lib/filesys.C +++ b/lib/filesys.C @@ -88,6 +88,14 @@ int is_dir(const char* path) { return (!retval && (sbuf.st_mode & S_IFDIR)); } +#ifndef _WIN32 +int is_symlink(const char* path) { + struct stat sbuf; + int retval = stat(path, &sbuf); + return (!retval && (sbuf.st_mode & S_IFLNK)); +} +#endif + // Open a directory // DIRREF dir_open(const char* p) { @@ -337,7 +345,7 @@ int clean_out_dir(const char* dirpath) { // return total size of files in directory and optionally its subdirectories // Win: use special version because stat() is slow, can be avoided -// Unix: skip symbolic links +// Unix: follow symbolic links // int dir_size(const char* dirpath, double& size, bool recurse) { #ifdef WIN32 @@ -386,7 +394,7 @@ int dir_size(const char* dirpath, double& size, bool recurse) { if (retval) continue; size += x; } - } else if (is_file(subdir)) { + } else { retval = file_size(subdir, x); if (retval) continue; size += x; diff --git a/lib/filesys.h b/lib/filesys.h index b807301064..c7cdd112b9 100644 --- a/lib/filesys.h +++ b/lib/filesys.h @@ -57,6 +57,7 @@ extern "C" { extern char boinc_failed_file[256]; extern int is_file(const char* path); extern int is_dir(const char* path); + extern int is_symlink(const char* path); extern int boinc_truncate(const char*, double); extern int boinc_file_exists(const char* path); extern int boinc_file_or_symlink_exists(const char* path);