diff options
-rw-r--r-- | filecopy/Makefile | 58 | ||||
-rw-r--r-- | filecopy/filecopy-help.pd | 15 | ||||
-rw-r--r-- | filecopy/filecopy.c | 180 |
3 files changed, 253 insertions, 0 deletions
diff --git a/filecopy/Makefile b/filecopy/Makefile new file mode 100644 index 0000000..0acba62 --- /dev/null +++ b/filecopy/Makefile @@ -0,0 +1,58 @@ +NAME=filecopy +CSYM=filecopy + +LIBDIR=/usr/local/lib +PDDIR=$(LIBDIR)/pd +INSTALLPATH=$(PDDIR)/extra/ + +current: pd_darwin + + +# ----------------------- Linux ----------------------- + +pd_linux: $(NAME).pd_linux + +.SUFFIXES: .pd_linux + +LINUXCFLAGS = -ggdb -DPD -O3 -fPIC -funroll-loops -fomit-frame-pointer \ + -Wall -W -Wshadow -Wstrict-prototypes -Werror \ + -Wno-unused -Wno-parentheses -Wno-switch + +# Debug +#LINUXCFLAGS = -ggdb -g -DPD -O0 -fPIC -funroll-loops -fomit-frame-pointer \ + -Wall -W -Wshadow -Wstrict-prototypes -Werror \ + -Wno-unused -Wno-parentheses -Wno-switch + +LINUXINCLUDE = -I/usr/include -I./include -I../../../pd/src + +.c.pd_linux: + $(CC) $(LINUXCFLAGS) $(LINUXINCLUDE) -c $(NAME).c + ld --export-dynamic -shared -o $(NAME).pd_linux $(NAME).o -lc + strip --strip-unneeded $(NAME).pd_linux + rm -f *.o + +# ----------------------- Mac OSX ----------------------- + +pd_darwin: $(NAME).pd_darwin + +.SUFFIXES: .pd_darwin + +DARWINCFLAGS = -DPD -O3 -Wall -W -Wshadow -Wstrict-prototypes \ + -Wno-unused -Wno-parentheses -Wno-switch -L/usr/local/lib/ + +DARWININCLUDE = $(LINUXINCLUDE) + +.c.pd_darwin: + $(CC) $(DARWINCFLAGS) $(DARWININCLUDE) -c $(NAME).c + $(CC) -bundle -undefined suppress -flat_namespace -o $(NAME).pd_darwin $(NAME).o + rm -f *.o + +# ----------------------- Generic ----------------------- + +clean: + rm -f *.o *.pd_* so_locations + +install: + cp filecopy.pd_* $(INSTALLPATH) + install -d $(PDDIR)/doc/5.reference/filecopy/ + install -m 644 doc/help-* $(PDDIR)/doc/5.reference/ diff --git a/filecopy/filecopy-help.pd b/filecopy/filecopy-help.pd new file mode 100644 index 0000000..34b67d7 --- /dev/null +++ b/filecopy/filecopy-help.pd @@ -0,0 +1,15 @@ +#N canvas 470 62 398 308 10; +#X obj 46 119 filecopy; +#X obj 46 154 sel 0 1; +#X msg 65 179 set copied; +#X msg 46 209 set failed; +#X symbolatom 46 250 10 0 0 0 - - -, f 10; +#X msg 46 62 list /source/path /destination/path; +#X text 42 21 [filecopy] copy file from source path to destination path +; +#X connect 0 0 1 0; +#X connect 1 0 3 0; +#X connect 1 1 2 0; +#X connect 2 0 4 0; +#X connect 3 0 4 0; +#X connect 5 0 0 0; diff --git a/filecopy/filecopy.c b/filecopy/filecopy.c new file mode 100644 index 0000000..af239b8 --- /dev/null +++ b/filecopy/filecopy.c @@ -0,0 +1,180 @@ +/* filecopy - filecopy a file from one path to another preserving permissions + * + * Author: Jamie Bullock <jamie@jamiebullock.com> + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to filecopy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize filecopyright laws, the author or authors + * of this software dedicate any and all filecopyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under filecopyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * For more information, please refer to <http://unlicense.org/> + */ + +#include "m_pd.h" + +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/stat.h> + +#ifdef __APPLE__ +#define O_BINARY 0 +#endif + +#ifdef WIN32 +#define open _open +#define close _close +#define fdopen _fdopen +#define fdclose _fdclose +#endif + +#define CONSOLE_PREFIX "[filecopy]: " + +typedef struct _filecopy +{ + t_object x_obj; + t_outlet *outlet; +} +t_filecopy; + +t_class *filecopy_class; + +static int do_copy(const char *source, const char *target); + +void *filecopy_new(t_symbol *s, int argc, t_atom *argv) +{ + t_filecopy *x = (t_filecopy *)pd_new(filecopy_class); + x->outlet = outlet_new(&x->x_obj, &s_float); + post(CONSOLE_PREFIX "copy file from source path to destination path"); + return (void *)x; +} + +static void filecopy_list(t_filecopy *x, t_symbol *s, int ac, t_atom *av) +{ + char source[MAXPDSTRING]; + char target[MAXPDSTRING]; + int rv; + + if(ac != 2 || (av[0].a_type != A_SYMBOL && av[1].a_type != A_SYMBOL)) + { + pd_error(x, "expected a list containing <source path> <destination path>"); + } + + atom_string(&av[0], source, MAXPDSTRING); + atom_string(&av[1], target, MAXPDSTRING); + + rv = do_copy(source, target); + rv++; + + if(rv) + { + post(CONSOLE_PREFIX "%s successfully copied to %s", source, target); + } + + outlet_float(x->outlet, (t_float)rv); +} + +void filecopy_setup(void) +{ + filecopy_class = class_new(gensym("filecopy"), + (t_newmethod)filecopy_new, + 0, sizeof(t_filecopy), 0, + A_GIMME, 0); + class_addlist(filecopy_class, filecopy_list); +} + + +static int copy_data(FILE *source, FILE *target) +{ + char buffer[BUFSIZ]; + size_t n; + + while ((n = fread(buffer, sizeof(char), sizeof(buffer), source)) > 0) + { + if (fwrite(buffer, sizeof(char), n, target) != n) + { + error("write failed"); + return -1; + } + } + + return 0; +} + + +static int do_copy(const char *source, const char *target) +{ + struct stat info; + int rv; + int rv2; + int fdtarget; + int fdsource; + FILE *fsource; + FILE *ftarget; + + fdsource = open(source, O_RDONLY|O_BINARY, 0); + + if (fdsource == -1) + { + error(CONSOLE_PREFIX "invalid input"); + return -1; + } + + rv = fstat(fdsource, &info); + + if(rv == -1) + { + error(CONSOLE_PREFIX "stat failed\n"); + return -1; + } + + fdtarget = open(target, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, info.st_mode); + + if (fdtarget == -1) + { + error(CONSOLE_PREFIX "invalid output\n"); + close(fdsource); + return -1; + } + + fsource = fdopen(fdsource, "rb"); + ftarget = fdopen(fdtarget, "wb"); + + rv = copy_data(fsource, ftarget); + + if (rv == -1) + { + error(CONSOLE_PREFIX "filecopy failed"); + } + + rv = fclose(fsource); + rv2 = fclose(ftarget); + + if (rv || rv2) + { + error(CONSOLE_PREFIX "file close failed"); + rv = -1; + } + + return rv; +} |