From 7a180b0ef8db7b12c662fb6630975f41e3c921b0 Mon Sep 17 00:00:00 2001 From: "Carlos R. Mafra" Date: Sun, 15 Jan 2012 05:54:34 +0000 Subject: [PATCH] WINGs: Add copy_file() to libWUtil This is essentially the fetchFile() from wcolorpanel.c from the last commit, but renamed to a better name. This patch just adds the function to the lib. Nobody uses it yet. --- WINGs/WINGs/WUtil.h | 2 ++ WINGs/findfile.c | 57 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/WINGs/WINGs/WUtil.h b/WINGs/WINGs/WUtil.h index f3131c51..4872df5f 100644 --- a/WINGs/WINGs/WUtil.h +++ b/WINGs/WINGs/WUtil.h @@ -201,6 +201,8 @@ char* wfindfileinarray(WMPropList* array, char *file); char* wexpandpath(char *path); +int copy_file(char *toPath, char *srcFile, char *destFile); + /* don't free the returned string */ char* wgethomedir(void); diff --git a/WINGs/findfile.c b/WINGs/findfile.c index 70d1e47c..70493a55 100644 --- a/WINGs/findfile.c +++ b/WINGs/findfile.c @@ -22,7 +22,9 @@ #include "WUtil.h" +#include #include +#include #include #include #include @@ -33,6 +35,8 @@ #define PATH_MAX 1024 #endif +#define RETRY( x ) do { x; } while (errno == EINTR); + char *wgethomedir() { static char *home = NULL; @@ -403,3 +407,56 @@ char *wfindfileinarray(WMPropList * array, char *file) } return NULL; } + +int copy_file(char *dir, char *src_file, char *dest_file) +{ + FILE *src, *dst; + size_t nread, nwritten; + char *dstpath; + struct stat st; + char buf[4096]; + + /* only to a directory */ + if (stat(dir, &st) != 0 || !S_ISDIR(st.st_mode)) + return -1; + /* only copy files */ + if (stat(src_file, &st) != 0 || !S_ISREG(st.st_mode)) + return -1; + + RETRY( src = fopen(src_file, "rb") ) + if (src == NULL) { + werror(_("Could not open %s"), src_file); + return -1; + } + + dstpath = wstrconcat(dir, dest_file); + RETRY( dst = fopen(dstpath, "wb") ) + if (dst == NULL) { + werror(_("Could not create %s"), dstpath); + wfree(dstpath); + RETRY( fclose(src) ) + return -1; + } + + do { + RETRY( nread = fread(buf, 1, sizeof(buf), src) ) + if (ferror(src)) + break; + + RETRY( nwritten = fwrite(buf, 1, nread, dst) ) + if (ferror(dst) || feof(src) || nread != nwritten) + break; + + } while (1); + + if (ferror(src) || ferror(dst)) + unlink(dstpath); + + RETRY( fclose(src) ) + fchmod(fileno(dst), st.st_mode); + fsync(fileno(dst)); + RETRY( fclose(dst) ) + wfree(dstpath); + + return 0; +}