aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--filecopy/Makefile58
-rw-r--r--filecopy/filecopy-help.pd15
-rw-r--r--filecopy/filecopy.c180
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;
+}