├── pkg └── .keepme ├── test └── .keepme ├── .obj ├── fuse │ └── .keepme └── xar │ └── .keepme ├── .gitignore ├── fuse ├── .cvsignore ├── mount_util.h ├── ulockmgr.h ├── fuse_common_compat.h ├── fuse_loop.c ├── fuse_i.h ├── fuse_misc.h ├── fuse_signals.c ├── fuse_kern_chan.c ├── fuse_mt.c ├── fuse_versionscript ├── fuse_session.c └── fuse_loop_mt.c ├── signal_handler.h ├── bombsquad.c ├── vfs_fuse.h ├── mk ├── ccache.mk ├── clean.mk ├── distcc.mk ├── lib.mk ├── indent.mk ├── bin.mk ├── fuse.mk ├── config.mk └── xar.mk ├── vfs_inotify.h ├── LICENSE ├── thread_pool.h ├── timestr.h ├── xar ├── b64.h ├── ea.h ├── script.h ├── fbsdattr.h ├── linuxattr.h ├── ext2.h ├── data.h ├── darwinattr.h ├── lzmaxar.h ├── zxar.h ├── bzxar.h ├── stat.h ├── util.h ├── macho.h ├── hash.h ├── arcmod.h ├── signature.h ├── subdoc.h ├── asprintf.h ├── err.c ├── script.c ├── appledouble.h ├── io.h ├── archive.h ├── ea.c ├── strmode.h ├── filetree.h ├── arcmod.c └── b64.c ├── evt.h ├── TODO ├── logger.h ├── util.h ├── inode.h ├── Makefile ├── fs-pkg.cf ├── db_sqlite.h ├── signal_handler.c ├── README ├── BUGS ├── evt.c ├── support.h ├── db.h ├── thread_pool.c ├── conf.h ├── str.h ├── vfs.h ├── config.h ├── memory.h ├── pkg_map.c ├── atomicio.h ├── pkg.h ├── inode.c ├── balloc.h ├── atomicio.c ├── vfs.c ├── timestr.c ├── logger.c ├── dlink.h ├── main.c ├── ev_config.h ├── support.c ├── libfspkg.c ├── vfs_spill.h ├── vfs_fuse.c ├── conf.c ├── ev_wrap.h ├── ev_poll.c ├── dlink.c ├── dictionary.h ├── vfs_inotify.c ├── vfs_pkg.h └── ev_port.c /pkg/.keepme: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/.keepme: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.obj/fuse/.keepme: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.obj/xar/.keepme: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | pkg/*.pkg 2 | -------------------------------------------------------------------------------- /fuse/.cvsignore: -------------------------------------------------------------------------------- 1 | Makefile.in 2 | Makefile 3 | .deps 4 | .libs 5 | *.lo 6 | *.la 7 | -------------------------------------------------------------------------------- /signal_handler.h: -------------------------------------------------------------------------------- 1 | extern void signal_init(void); 2 | extern void goodbye(void); /* from main.c */ 3 | -------------------------------------------------------------------------------- /bombsquad.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /* hashing functions */ 8 | -------------------------------------------------------------------------------- /vfs_fuse.h: -------------------------------------------------------------------------------- 1 | extern struct fuse_args vfs_fuse_args; 2 | extern void *fuse_thr(void *unused); 3 | extern void vfs_fuse_fini(void); 4 | extern void vfs_fuse_init(void); 5 | -------------------------------------------------------------------------------- /mk/ccache.mk: -------------------------------------------------------------------------------- 1 | 2 | CCACHE := /usr/bin/ccache 3 | 4 | # Try to use ccache, if available 5 | ifeq (${CCACHE}, $(wildcard ${CCACHE})) 6 | CC := ${CCACHE} ${CC} 7 | endif 8 | -------------------------------------------------------------------------------- /vfs_inotify.h: -------------------------------------------------------------------------------- 1 | extern int vfs_watch_init(void); 2 | extern void vfs_watch_fini(void); 3 | extern vfs_watch_t *vfs_watch_add(const char *path); 4 | extern int vfs_watch_remove(vfs_watch_t * watch); 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | My code is MIT license. 2 | 3 | External code: 4 | fuse/ LGPL, libfuse embedded 5 | xar/ BSD-license, libxar 6 | 7 | -- If you have a decently new libfuse already, you can avoid 8 | -- embedding fuse/ 9 | -------------------------------------------------------------------------------- /mk/clean.mk: -------------------------------------------------------------------------------- 1 | 2 | extra_clean += ${bin}.log 3 | extra_clean += ${bin}.db 4 | extra_clean += ${bin}.db-journal 5 | 6 | clean: 7 | ${RM} ${objs} ${bin} ${extra_clean} ${libs} ${lib_objs} 8 | 9 | distclean: 10 | @${MAKE} clean 11 | -------------------------------------------------------------------------------- /mk/distcc.mk: -------------------------------------------------------------------------------- 1 | DISTCC := /usr/bin/distcc 2 | # Is DISTCC_HOSTS set? 3 | ifneq (y${DISTCC_HOSTS}, y) 4 | # Try to use distcc, if available 5 | ifeq (${DISTCC}, $(wildcard ${DISTCC})) 6 | CC := ${DISTCC} 7 | endif 8 | endif 9 | 10 | export DISTCC_HOSTS 11 | -------------------------------------------------------------------------------- /mk/lib.mk: -------------------------------------------------------------------------------- 1 | libs += libfspkg.so 2 | lib_objs += .obj/libfspkg.o 3 | 4 | libfspkg.so:${lib_objs} 5 | @echo "[LD] $^ => $@" 6 | @${LD} -lc ${lib_ldflags} -o $@ $^ 7 | 8 | .objs/%.o:%.c 9 | @echo "[CC] $< => $@" 10 | @${CC} ${warn_flags} ${lib_cflags} -o $@ -c $< 11 | -------------------------------------------------------------------------------- /thread_pool.h: -------------------------------------------------------------------------------- 1 | #include 2 | typedef struct thread_t { 3 | pthread_t pth; 4 | pthread_attr_t *pa; 5 | int refcnt; /* Reference count */ 6 | } thread_t; 7 | 8 | extern thread_t *thr_create(void *cb, void *arg, size_t stack_size); 9 | -------------------------------------------------------------------------------- /timestr.h: -------------------------------------------------------------------------------- 1 | #if !defined(NN2_TIMESTRING) 2 | #define NN2_TIMESTRING 3 | #include 4 | extern time_t nn2_timestr_to_time(const char *str, const time_t def); 5 | extern char *nn2_time_to_timestr(time_t itime); 6 | #endif /* !defined(NN2_TIMESTRING) */ 7 | -------------------------------------------------------------------------------- /xar/b64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Rob Braun 3 | * 1-Oct-2004 4 | * Copyright (c) 2004 Rob Braun. All rights reserved. 5 | */ 6 | 7 | #ifndef _XAR_BASE64_H_ 8 | #define _XAR_BASE64_H_ 9 | 10 | unsigned char* xar_from_base64(const unsigned char* input, int len); 11 | 12 | #endif /* _XAR_BASE64_H_ */ 13 | -------------------------------------------------------------------------------- /evt.h: -------------------------------------------------------------------------------- 1 | #include "ev.h" 2 | extern struct ev_loop *evt_loop; 3 | extern void evt_init(void); 4 | extern ev_timer *evt_timer_add_periodic(void *callback, const char *name, int interval); 5 | /* MAKE DAMN SURE YOUR CALLBACK DOES A mem_free() ON TIMER!!! */ 6 | extern ev_timer *evt_timer_add_oneshot(void *callback, const char *name, int timeout); 7 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Work on a library (LD_PRELOAD) method. 2 | * Needs read-only package database and a daemon to fill it 3 | * Needs way to disable inotify, etc 4 | * Needs way to disable fuse build 5 | * Add a pass-through mode 6 | - Try pkgdb 7 | [noent] try spillover 8 | [noent] try real fs 9 | * Add in-place decompression (at least libz) 10 | - To file 11 | - To buffer 12 | -------------------------------------------------------------------------------- /logger.h: -------------------------------------------------------------------------------- 1 | #if !defined(NN2_LOGGER) 2 | #define NN2_LOGGER 3 | #include 4 | #define __logger_h 5 | #include "conf.h" 6 | 7 | #if !defined(NN2_LOGGER_FP) 8 | extern FILE *log_fp; 9 | #endif 10 | 11 | extern FILE *log_open(const char *path); 12 | extern void log_close(FILE * fp); 13 | extern void Log(enum log_priority priority, const char *fmt, ...); 14 | #endif /* !defined(NN2_LOGGER) */ 15 | -------------------------------------------------------------------------------- /util.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | static __inline int is_dir(const char *path) { 4 | struct stat sb; 5 | 6 | stat(path, &sb); 7 | 8 | if (S_ISDIR(sb.st_mode)) 9 | return 1; 10 | 11 | return 0; 12 | } 13 | 14 | static __inline int file_exists(const char *path) { 15 | struct stat sb; 16 | stat(path, &sb); 17 | 18 | if (errno == ENOENT) 19 | return 0; 20 | 21 | return 1; 22 | } 23 | -------------------------------------------------------------------------------- /xar/ea.h: -------------------------------------------------------------------------------- 1 | #ifndef _XAR_EA_H_ 2 | #define _XAR_EA_H_ 3 | 4 | #include "xar.h" 5 | #include "filetree.h" 6 | 7 | typedef struct __xar_ea_t *xar_ea_t; 8 | 9 | xar_ea_t xar_ea_new(xar_file_t f, const char *name); 10 | int32_t xar_ea_pset(xar_file_t f, xar_ea_t e, const char *key, const char *value); 11 | int32_t xar_ea_pget(xar_ea_t e, const char *key, const char **value); 12 | xar_prop_t xar_ea_root(xar_ea_t e); 13 | xar_prop_t xar_ea_find(xar_file_t f, const char *name); 14 | 15 | #endif /* _XAR_EA_H_ */ 16 | -------------------------------------------------------------------------------- /inode.h: -------------------------------------------------------------------------------- 1 | #if !defined(inode_h) 2 | #define inode_h 3 | 4 | #include "balloc.h" 5 | struct pkg_inode { 6 | u_int32_t st_ino; 7 | mode_t st_mode; 8 | off_t st_size; 9 | off_t st_off; 10 | uid_t st_uid; 11 | gid_t st_gid; 12 | time_t st_time; 13 | }; 14 | 15 | typedef struct pkg_inode pkg_inode_t; 16 | 17 | BlockHeap *inode_heap; 18 | 19 | extern void inode_init(void); 20 | extern void inode_fini(void); 21 | 22 | #endif /* !defined(inode_h) */ 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: world 2 | 3 | include mk/config.mk 4 | include mk/distcc.mk 5 | include mk/ccache.mk 6 | include mk/fuse.mk 7 | include mk/indent.mk 8 | include mk/xar.mk 9 | include mk/bin.mk 10 | include mk/lib.mk 11 | include mk/clean.mk 12 | 13 | ifeq (${CONFIG_DEBUG}, y) 14 | CONFIG_STRIP_BINS=n 15 | CFLAGS += -DCONFIG_DEBUG 16 | endif 17 | 18 | world:${bin} ${libs} 19 | 20 | testpkg: 21 | xar --compression=none -c -f pkg/irssi.pkg /usr/bin/irssi /usr/lib/irssi /usr/share/irssi \ 22 | /usr/share/irssi /usr/share/man/man1/irssi.1.gz 23 | -------------------------------------------------------------------------------- /mk/indent.mk: -------------------------------------------------------------------------------- 1 | 2 | id_blanks := -nbad -bap -nbbb -sob -hnl 3 | id_comments := -lc110 -fc1 -c40 -cd40 -cp40 -cdb -sc -d0 -nfc1 4 | id_statements := -br -ce -cdw -cli3 -npcs -ss -ncs -nbs -saf 5 | id_statements += -sai -saw -nprs 6 | id_declr := -di12 -nbc -nbfda -nbfde -npsl -brs -brf 7 | id_misc := -lp -ip0 -nlps -ppi0 -il3 -nbbo -i3 -ci4 -l100 8 | id_misc += -ts3 -i3 -nut 9 | 10 | indent: 11 | @for i in *.[ch]; do \ 12 | echo "* indenting $$i"; \ 13 | indent ${id_blanks} ${id_comments} ${id_statements} ${id_declr} ${id_misc} $$i; \ 14 | ${RM} $$i~; \ 15 | done 16 | -------------------------------------------------------------------------------- /fs-pkg.cf: -------------------------------------------------------------------------------- 1 | ; log.level [debug|info|warning|error|fatal|hack] 2 | log.level=debug 3 | ;path.db=:memory: 4 | path.db=fs-pkg.db 5 | ; This will be added soon, allowing saving database 6 | ; between restarts for faster loading 7 | ;path.db.persistant=/.pkgdb 8 | ;path.log=fs-pkg.log 9 | path.mountpoint=test 10 | path.pkg=pkg 11 | sys.daemonize=false 12 | ; these should be fairly reasonable... 13 | tuning.heap.inode=128 14 | tuning.heap.node=128 15 | tuning.heap.pkg=128 16 | tuning.heap.vfs_handle=512 17 | tuning.heap.vfs_watch=32 18 | tuning.timer.blockheap_gc=60 19 | tuning.timer.pkg_gc=60 20 | tuning.toc.gz.buffer=1310720 21 | -------------------------------------------------------------------------------- /db_sqlite.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include "inode.h" 3 | 4 | extern void *db_query(enum db_query_res_type type, const char *fmt, ...); 5 | extern int db_sqlite_open(const char *path); 6 | extern void db_sqlite_close(void); 7 | extern void db_sqlite_close(void); 8 | extern int db_pkg_add(const char *path); 9 | extern int db_file_add(int pkg, const char *path, const char type, 10 | uid_t owner, gid_t grp, size_t size, off_t offset, time_t ctime); 11 | extern int db_pkg_remove(const char *path); 12 | extern int db_file_remove(int pkg, const char *path); 13 | extern void db_begin(void); 14 | extern void db_commit(void); 15 | extern void db_rollback(void); 16 | -------------------------------------------------------------------------------- /fuse/mount_util.h: -------------------------------------------------------------------------------- 1 | /* 2 | FUSE: Filesystem in Userspace 3 | Copyright (C) 2001-2007 Miklos Szeredi 4 | 5 | This program can be distributed under the terms of the GNU LGPLv2. 6 | See the file COPYING.LIB. 7 | */ 8 | 9 | #include 10 | 11 | int fuse_mnt_add_mount(const char *progname, const char *fsname, 12 | const char *mnt, const char *type, const char *opts); 13 | int fuse_mnt_umount(const char *progname, const char *mnt, int lazy); 14 | char *fuse_mnt_resolve_path(const char *progname, const char *orig); 15 | int fuse_mnt_check_empty(const char *progname, const char *mnt, 16 | mode_t rootmode, off_t rootsize); 17 | int fuse_mnt_check_fuseblk(void); 18 | -------------------------------------------------------------------------------- /signal_handler.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "conf.h" 3 | #include "evt.h" 4 | #include "signal_handler.h" 5 | static ev_signal signal_die; 6 | static ev_signal signal_reload; 7 | 8 | static void signal_handler_die(struct ev_loop *loop, ev_signal * w, int revents) { 9 | conf.dying = 1; 10 | goodbye(); 11 | } 12 | 13 | static void signal_handler_reload(struct ev_loop *loop, ev_signal * w, int revents) { 14 | } 15 | 16 | void signal_init(void) { 17 | ev_signal_init(&signal_die, signal_handler_die, SIGINT); 18 | ev_signal_init(&signal_die, signal_handler_die, SIGQUIT); 19 | ev_signal_init(&signal_die, signal_handler_die, SIGTERM); 20 | ev_signal_init(&signal_reload, signal_handler_reload, SIGHUP); 21 | signal(SIGPIPE, SIG_IGN); 22 | } 23 | -------------------------------------------------------------------------------- /fuse/ulockmgr.h: -------------------------------------------------------------------------------- 1 | /* 2 | libulockmgr: Userspace Lock Manager Library 3 | Copyright (C) 2006 Miklos Szeredi 4 | 5 | This program can be distributed under the terms of the GNU LGPLv2. 6 | See the file COPYING.LIB. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | /** 14 | * Perform POSIX locking operation 15 | * 16 | * @param fd the file descriptor 17 | * @param cmd the locking command (F_GETFL, F_SETLK or F_SETLKW) 18 | * @param lock the lock parameters 19 | * @param owner the lock owner ID cookie 20 | * @param owner_len length of the lock owner ID cookie 21 | * @return 0 on success -errno on error 22 | */ 23 | int ulockmgr_op(int fd, int cmd, struct flock *lock, const void *owner, 24 | size_t owner_len); 25 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This shit is a bit of mess right now... 2 | Keep tracking the git, it'll clean up fairly quickly. Feel free to send patches! 3 | 4 | We are trying to make things as modular as possible without depending on dlfcn... 5 | Patches to: dev-fspkg@nn2.us 6 | 7 | - bk@nn2.us 8 | 9 | 10 | --- If anyone wants an example of using fuse with libev, 11 | --- take a look in vfs_fuse.c:vfs_fuse_init and 12 | --- vfs_fuse.c:vfs_fuse_read_cb 13 | 14 | * We use a slightly trimmed down libfuse, however the original lib 15 | * should work just fine- if you dont mind the extra bloat 16 | -- This is needed because a lot of systems complain that 17 | -- libfuse is out of date using the native libfuse. 18 | 19 | ---------- 20 | * We are working libbombsquad- MIT licensed stuff for interacting with 21 | with libfuse. What a pain in the ass... 22 | -------------------------------------------------------------------------------- /fuse/fuse_common_compat.h: -------------------------------------------------------------------------------- 1 | /* 2 | FUSE: Filesystem in Userspace 3 | Copyright (C) 2001-2007 Miklos Szeredi 4 | 5 | This program can be distributed under the terms of the GNU LGPLv2. 6 | See the file COPYING.LIB. 7 | */ 8 | 9 | /* these definitions provide source compatibility to prior versions. 10 | Do not include this file directly! */ 11 | 12 | struct fuse_file_info_compat { 13 | int flags; 14 | unsigned long fh; 15 | int writepage; 16 | unsigned int direct_io : 1; 17 | unsigned int keep_cache : 1; 18 | }; 19 | 20 | int fuse_mount_compat25(const char *mountpoint, struct fuse_args *args); 21 | 22 | int fuse_mount_compat22(const char *mountpoint, const char *opts); 23 | 24 | int fuse_mount_compat1(const char *mountpoint, const char *args[]); 25 | 26 | void fuse_unmount_compat22(const char *mountpoint); 27 | -------------------------------------------------------------------------------- /BUGS: -------------------------------------------------------------------------------- 1 | We handle Xar Table Of Contents in a particularly ugly way right now... 2 | pkg.c:pkg_import(): Calls pkg_toc_extract 3 | pkg_toc.c:pkg_toc_extract(): Extracts TOC to /pkg/$pkg.toc 4 | pkg_toc.c:pkg_toc_load(): Parses the XML Table of Contents into db 5 | pkg.c:pkg_import(): unlink(/pkg/$pkg.XXXXXX) where XXXXXX is random 6 | 7 | We need to look at extracting each TOC into a buffer then processing it. 8 | This shouldn't be too hard since we know the uncompressed TOC size. 9 | 10 | We need to use errno more and add more error checking. 11 | 12 | 13 | Probably should try to modify dictionary to be type-generic 14 | * If we do this, why not use it for package cache? 15 | - This should reduce some of the mess which 16 | overhead of the cache versus using dlists. -bk 17 | - I still think the cache will be a win either way -jld 18 | -------------------------------------------------------------------------------- /mk/bin.mk: -------------------------------------------------------------------------------- 1 | ifeq (${CONFIG_TOC_LIBXML2}, y) 2 | CFLAGS += -DCONFIG_TOC_LIBXML2 3 | endif 4 | 5 | bin := fs-pkg 6 | objs += .obj/atomicio.o 7 | objs += .obj/balloc.o 8 | objs += .obj/bombsquad.o 9 | objs += .obj/conf.o 10 | objs += .obj/db_sqlite.o 11 | objs += .obj/dictionary.o 12 | objs += .obj/dlink.o 13 | objs += .obj/ev.o 14 | objs += .obj/evt.o 15 | objs += .obj/inode.o 16 | objs += .obj/logger.o 17 | objs += .obj/main.o 18 | objs += .obj/pkg.o 19 | objs += .obj/pkg_map.o 20 | objs += .obj/pkg_toc.o 21 | objs += .obj/signal_handler.o 22 | objs += .obj/str.o 23 | objs += .obj/support.o 24 | objs += .obj/thread_pool.o 25 | objs += .obj/timestr.o 26 | objs += .obj/vfs.o 27 | objs += .obj/vfs_inotify.o 28 | 29 | ${bin}: ${objs} 30 | @${CC} -o $@ ${LDFLAGS} ${extra_libs} $^ 31 | ifeq (${CONFIG_STRIP_BINS}, y) 32 | @echo "[STRIP] $@" 33 | @strip $@ 34 | endif 35 | 36 | .obj/%.o:%.c 37 | @echo "[CC] $< => $@" 38 | @${CC} ${warn_flags} ${CFLAGS} -o $@ -c $< 39 | -------------------------------------------------------------------------------- /evt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * evt.[ch]: Utility functions to make using libevent a bit more 'friendly' for neo-ircd 3 | * Copyright (C) 2008 N2 Networks LLC, Released under the BSD license. 4 | */ 5 | #include 6 | #include "ev.h" 7 | #include "memory.h" 8 | 9 | struct ev_loop *evt_loop = NULL; 10 | 11 | void evt_init(void) { 12 | evt_loop = ev_default_loop(0); 13 | } 14 | 15 | ev_timer *evt_timer_add_periodic(void *callback, const char *name, int interval) { 16 | ev_timer *timer = mem_alloc(sizeof(ev_timer)); 17 | ev_timer_init(timer, callback, 0, interval); 18 | ev_timer_start(evt_loop, timer); 19 | return timer; 20 | } 21 | 22 | /* MAKE DAMN SURE YOUR CALLBACK DOES A mem_free() ON TIMER!!! */ 23 | ev_timer *evt_timer_add_oneshot(void *callback, const char *name, int timeout) { 24 | ev_timer *timer = mem_alloc(sizeof(ev_timer)); 25 | ev_timer_init(timer, callback, timeout, 0); 26 | ev_timer_start(evt_loop, timer); 27 | return timer; 28 | } 29 | -------------------------------------------------------------------------------- /mk/fuse.mk: -------------------------------------------------------------------------------- 1 | ifeq (${CONFIG_VFS_FUSE}, y) 2 | CFLAGS += -DCONFIG_VFS_FUSE 3 | objs += .obj/vfs_fuse.o 4 | objs += .obj/fuse/fuse.o 5 | objs += .obj/fuse/fuse_kern_chan.o 6 | objs += .obj/fuse/fuse_loop.o 7 | objs += .obj/fuse/fuse_loop_mt.o 8 | objs += .obj/fuse/fuse_lowlevel.o 9 | objs += .obj/fuse/fuse_mt.o 10 | objs += .obj/fuse/fuse_opt.o 11 | objs += .obj/fuse/fuse_session.o 12 | objs += .obj/fuse/fuse_signals.o 13 | objs += .obj/fuse/helper.o 14 | objs += .obj/fuse/mount.o 15 | objs += .obj/fuse/mount_util.o 16 | endif 17 | 18 | # Until i figure out how to work around these, let them throw warnings but dont abort comile.... 19 | .obj/fuse/%.o:fuse/%.c 20 | @echo "[CC] $< => $@" 21 | @${CC} ${warn_noerror} ${CFLAGS} -DFUSE_USE_VERSION=26 -DPACKAGE_VERSION="\"2.8.0-pre1\"" -DFUSERMOUNT_DIR="\"/bin\"" -DFUSERMOUNT_BIN="\"fusermount\"" -o $@ -c $< 22 | .obj/vfs_fuse.o:vfs_fuse.c vfs_fuse.h vfs_pkg.h vfs_spill.h 23 | @echo "[CC] $< => $@" 24 | @${CC} ${warn_noerror} ${CFLAGS} -o $@ -c $< 25 | -------------------------------------------------------------------------------- /support.h: -------------------------------------------------------------------------------- 1 | /* Sentinel - IRC Statistical and Operator Services 2 | ** support.h - For systems that do not provide these functions 3 | ** 4 | ** Copyright W. Campbell and others. See README for more details 5 | ** Some code Copyright: Jonathan George, Kai Seidler, ircd-hybrid Team, 6 | ** IRCnet IRCD developers. 7 | ** 8 | ** $Id: support.h,v 1.3 2003/09/29 17:09:29 wcampbel Exp $ 9 | */ 10 | 11 | #ifndef SUPPORT_H 12 | #define SUPPORT_H 13 | #include 14 | /* Fixes for broken operating systems */ 15 | #ifndef HAVE_STRLCAT 16 | size_t strlcat(char *, const char *, size_t); 17 | #endif 18 | 19 | #ifndef HAVE_STRLCPY 20 | size_t strlcpy(char *, const char *, size_t); 21 | #endif 22 | 23 | #ifndef HAVE_INET_PTON 24 | int inet_pton(int, const char *, void *); 25 | #endif 26 | 27 | #ifndef HAVE_INET_NTOP 28 | const char *inet_ntop(int, const void *, char *, size_t); 29 | #endif 30 | 31 | #if 0 32 | #ifndef AF_INET6 33 | #define AF_INET6 28 34 | #endif 35 | #endif 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /fuse/fuse_loop.c: -------------------------------------------------------------------------------- 1 | /* 2 | FUSE: Filesystem in Userspace 3 | Copyright (C) 2001-2007 Miklos Szeredi 4 | 5 | This program can be distributed under the terms of the GNU LGPLv2. 6 | See the file COPYING.LIB 7 | */ 8 | 9 | #include "fuse_lowlevel.h" 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | int fuse_session_loop(struct fuse_session *se) 16 | { 17 | int res = 0; 18 | struct fuse_chan *ch = fuse_session_next_chan(se, NULL); 19 | size_t bufsize = fuse_chan_bufsize(ch); 20 | char *buf = (char *) malloc(bufsize); 21 | if (!buf) { 22 | fprintf(stderr, "fuse: failed to allocate read buffer\n"); 23 | return -1; 24 | } 25 | 26 | while (!fuse_session_exited(se)) { 27 | struct fuse_chan *tmpch = ch; 28 | res = fuse_chan_recv(&tmpch, buf, bufsize); 29 | if (res == -EINTR) 30 | continue; 31 | if (res <= 0) 32 | break; 33 | fuse_session_process(se, buf, res, tmpch); 34 | } 35 | 36 | free(buf); 37 | fuse_session_reset(se); 38 | return res < 0 ? -1 : 0; 39 | } 40 | -------------------------------------------------------------------------------- /mk/config.mk: -------------------------------------------------------------------------------- 1 | # enable more debugging output (slower, noisier) 2 | CONFIG_DEBUG=y 3 | 4 | # debug block allocator? should be unneeded 5 | CONFIG_DEBUG_BALLOC=n 6 | 7 | # strip binaries? (debug disables, makes smaller) 8 | CONFIG_STRIP_BINS=y 9 | 10 | # strip libraries (debug disable, not recommended) 11 | CONFIG_STRIP_LIBS=n 12 | 13 | # use libxml2 to parse the TOC? (broken) 14 | CONFIG_TOC_LIBXML2=n 15 | 16 | # use libxar to parse the TOC? (slower) 17 | CONFIG_TOC_LIBXAR=y 18 | 19 | # use libfuse for VFS? (broken) 20 | CONFIG_VFS_FUSE=n 21 | 22 | # use LD_PRELOAD (doesn't support setuid) 23 | CONFIG_VFS_LDPRELOAD=y 24 | 25 | 26 | #################### 27 | # Compiler options # 28 | #################### 29 | CFLAGS += -Os -g -pipe 30 | CFLAGS += -I. -I./fuse -I/usr/include/libxml2 31 | CFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC 32 | warn_noerror := -Wall -Wno-unused -Wno-strict-aliasing -ansi -std=c99 33 | warn_flags := ${warn_noerror} #-Werror 34 | LDFLAGS := -lxml2 -lz -lcrypto -pthread -lrt -lsqlite3 35 | lib_ldflags += -shared -ldl 36 | -------------------------------------------------------------------------------- /mk/xar.mk: -------------------------------------------------------------------------------- 1 | # NEED_XAR is misleading, we always need xar.... 2 | ifeq (${CONFIG_TOC_LIBXAR}, y) 3 | CFLAGS += -DCONFIG_TOC_LIBXAR 4 | NEED_XAR=y 5 | endif 6 | ifeq (${CONFIG_VFS_FUSE}, y) 7 | CFLAGS += -DCONFIG_VFS_FUSE 8 | NEED_XAR=y 9 | endif 10 | 11 | ifeq (${NEED_XAR}, y) 12 | objs += .obj/xar/archive.o 13 | objs += .obj/xar/arcmod.o 14 | objs += .obj/xar/b64.o 15 | objs += .obj/xar/bzxar.o 16 | objs += .obj/xar/darwinattr.o 17 | objs += .obj/xar/data.o 18 | objs += .obj/xar/ea.o 19 | objs += .obj/xar/err.o 20 | objs += .obj/xar/ext2.o 21 | objs += .obj/xar/fbsdattr.o 22 | objs += .obj/xar/filetree.o 23 | objs += .obj/xar/hash.o 24 | objs += .obj/xar/io.o 25 | objs += .obj/xar/linuxattr.o 26 | objs += .obj/xar/lzmaxar.o 27 | objs += .obj/xar/macho.o 28 | objs += .obj/xar/script.o 29 | objs += .obj/xar/signature.o 30 | objs += .obj/xar/stat.o 31 | objs += .obj/xar/subdoc.o 32 | objs += .obj/xar/util.o 33 | objs += .obj/xar/zxar.o 34 | else 35 | LDFLAGS += -lxar 36 | endif 37 | 38 | .obj/xar/%.o:xar/%.c 39 | @echo "[CC] $< => $@" 40 | @${CC} ${warn_flags} ${CFLAGS} -o $@ -c $< 41 | -------------------------------------------------------------------------------- /db.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Database abstration layer 3 | * 4 | * Provides support for sqlite and berkeley DB 5 | */ 6 | enum db_query_res_type { 7 | QUERY_NULL = 0, /* no result */ 8 | QUERY_INT, /* integer result */ 9 | QUERY_CHAR, /* char result */ 10 | QUERY_INODE, /* pkgfs_inode result */ 11 | }; 12 | 13 | struct db_connector { 14 | /* 15 | * internal properties 16 | */ 17 | void *hndl; /* database handle */ 18 | pthread_mutex_t mutex; /* mutex */ 19 | u_int16_t error; /* error return */ 20 | 21 | /* 22 | * semi-private methods 23 | */ 24 | void (*begin) (void); 25 | void (*commit) (void); 26 | void (*rollback) (void); 27 | 28 | /* 29 | * public methods 30 | */ 31 | void *(*db_query) (enum db_query_res_type type, const char *fmt, ...); 32 | int (*db_open) (const char *path); 33 | void (*db_destroy) (void); 34 | }; 35 | 36 | #include "db_sqlite.h" 37 | -------------------------------------------------------------------------------- /fuse/fuse_i.h: -------------------------------------------------------------------------------- 1 | /* 2 | FUSE: Filesystem in Userspace 3 | Copyright (C) 2001-2007 Miklos Szeredi 4 | 5 | This program can be distributed under the terms of the GNU LGPLv2. 6 | See the file COPYING.LIB 7 | */ 8 | 9 | #include "fuse.h" 10 | 11 | struct fuse_session; 12 | struct fuse_chan; 13 | struct fuse_lowlevel_ops; 14 | struct fuse_req; 15 | 16 | struct fuse_cmd { 17 | char *buf; 18 | size_t buflen; 19 | struct fuse_chan *ch; 20 | }; 21 | 22 | struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args, 23 | const struct fuse_operations *op, 24 | size_t op_size, void *user_data, int compat); 25 | 26 | int fuse_sync_compat_args(struct fuse_args *args); 27 | 28 | struct fuse_chan *fuse_kern_chan_new(int fd); 29 | 30 | struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args, 31 | const struct fuse_lowlevel_ops *op, 32 | size_t op_size, void *userdata); 33 | 34 | void fuse_kern_unmount_compat22(const char *mountpoint); 35 | void fuse_kern_unmount(const char *mountpoint, int fd); 36 | int fuse_kern_mount(const char *mountpoint, struct fuse_args *args); 37 | -------------------------------------------------------------------------------- /thread_pool.c: -------------------------------------------------------------------------------- 1 | /* 2 | * XXX: This needs finished, it works but its very incomplete... 3 | * XXX: we should support other forms of threading and maybe 4 | * XXX: even a fork() based model for things too small for 5 | * XXX: pthreads lib, anyone have a use for that? 6 | * XXX; - jld 20081102 [bug: 33] 7 | */ 8 | #include 9 | #include 10 | #include "thread_pool.h" 11 | #include "memory.h" 12 | 13 | thread_t *thr_create(void *cb, void *arg, size_t stack_size) { 14 | thread_t *ret = mem_alloc(sizeof(thread_t)); 15 | 16 | if (!ret || (ret->pa = mem_alloc(sizeof(pthread_attr_t))) == NULL) 17 | raise(SIGTERM); 18 | 19 | if (pthread_attr_init(ret->pa) != 0) { 20 | Log(LOG_ERROR, "%s:pthread_attr_init %d:%s", __FUNCTION__, errno, strerror(errno)); 21 | mem_free(ret); 22 | return NULL; 23 | } 24 | 25 | if (stack_size > 0) 26 | pthread_attr_setstacksize(ret->pa, stack_size); 27 | 28 | if (pthread_create(&ret->pth, ret->pa, cb, arg) != 0) { 29 | Log(LOG_ERROR, "%s:pthread_create %d:%s", __FUNCTION__, errno, strerror(errno)); 30 | mem_free(ret); 31 | return NULL; 32 | } 33 | 34 | return ret; 35 | } 36 | -------------------------------------------------------------------------------- /conf.h: -------------------------------------------------------------------------------- 1 | #if !defined(NN2_DCONF) 2 | #define NN2_DCONF 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "dictionary.h" 9 | #include "timestr.h" 10 | 11 | enum log_priority { 12 | LOG_DEBUG = 0, 13 | LOG_INFO, 14 | LOG_HACK, 15 | LOG_WARNING, 16 | LOG_ERROR, 17 | LOG_FATAL 18 | }; 19 | 20 | struct conf { 21 | FILE *log_fp; 22 | enum log_priority log_level; 23 | char *mountpoint; 24 | int dying; 25 | dictionary *dict; 26 | time_t born; 27 | time_t now; 28 | }; 29 | 30 | extern struct conf conf; 31 | 32 | extern void dconf_init(const char *file); 33 | extern void dconf_fini(void); 34 | extern int dconf_get_bool(const char *key, const int def); 35 | extern double dconf_get_double(const char *key, const double def); 36 | extern int dconf_get_int(const char *key, const int def); 37 | extern char *dconf_get_str(const char *key, const char *def); 38 | extern time_t dconf_get_time(const char *key, const time_t def); 39 | extern int dconf_set(const char *key, const char *val); 40 | extern void dconf_unset(const char *key); 41 | #define NN2_DCONF_DICT conf.dict 42 | 43 | #endif /* !defined(NN2_DCONF) */ 44 | -------------------------------------------------------------------------------- /str.h: -------------------------------------------------------------------------------- 1 | /* Sentinel - IRC Statistical and Operator Services 2 | ** s_string.h - String management functions 3 | ** 4 | ** Copyright W. Campbell and others. See README for more details 5 | ** Some code Copyright: Jonathan George, Kai Seidler, ircd-hybrid Team, 6 | ** IRCnet IRCD developers. 7 | ** 8 | ** $Id: s_string.h,v 1.3 2003/11/06 20:41:53 wcampbel Exp $ 9 | */ 10 | #ifndef S_STRING_H 11 | #define S_STRING_H 12 | 13 | #define MAXPARA 15 /* The maximum number of parameters in an IRC message */ 14 | 15 | #ifndef TRUE 16 | #define TRUE 1 17 | #endif 18 | 19 | #ifndef FALSE 20 | #define FALSE 0 21 | #endif 22 | 23 | extern char *str_ctime(time_t); 24 | extern int str_tokenize(char *, char **); 25 | extern int str_tokenize_generic(char, int, char *, char **); 26 | extern void str_parv_expand(char *, int, int, int, char **); 27 | extern int str_islower(char *); 28 | extern void str_strip(char *); 29 | extern char *str_dup(const char *str); 30 | extern void str_tohex(char *dst, const char *src, unsigned int length); 31 | extern time_t dhms_to_sec(const char *str, int def); 32 | extern char *sec_to_dhms(time_t itime); 33 | extern char *str_unquote(char *str); 34 | extern char *str_whitespace_skip(char *str); 35 | extern char *str_tolower(char *s); 36 | #endif 37 | -------------------------------------------------------------------------------- /vfs.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "balloc.h" 7 | 8 | struct vfs_handle { 9 | char pkg_file[PATH_MAX]; /* package path */ 10 | off_t pkg_offset; /* offset within package */ 11 | char file[PATH_MAX]; /* file name */ 12 | size_t len; /* length of file */ 13 | off_t offset; /* current offset in file */ 14 | char *maddr; /* mmap()'d region of package */ 15 | }; 16 | 17 | struct vfs_watch { 18 | u_int32_t mask; 19 | int fd; 20 | char path[PATH_MAX]; 21 | }; 22 | 23 | struct vfs_fake_stat { 24 | u_int32_t st_ino; 25 | mode_t st_mode; 26 | off_t st_size; 27 | uid_t st_uid; 28 | gid_t st_gid; 29 | time_t st_time; 30 | char path[PATH_MAX]; 31 | }; 32 | 33 | typedef struct vfs_handle vfs_handle_t; 34 | typedef struct vfs_watch vfs_watch_t; 35 | 36 | extern int vfs_dir_walk(void); 37 | 38 | extern BlockHeap *vfs_handle_heap; 39 | extern BlockHeap *vfs_watch_heap; 40 | extern u_int32_t vfs_root_inode; 41 | extern dlink_list vfs_watch_list; 42 | 43 | #include "vfs_fuse.h" 44 | #include "vfs_inotify.h" 45 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | /* this should be suitable for linux... */ 2 | 3 | #define HAVE_SYS_STATFS_H 1 4 | /* #undef HAVE_SYS_XATTR_H */ 5 | /* #undef HAVE_SYS_EXTATTR_H */ 6 | /* #undef HAVE_SYS_PARAM_H 1 */ 7 | /* #undef HAVE_LGETXATTR */ 8 | /* #undef HAVE_LSETXATTR */ 9 | /* #undef HAVE_GETXATTR */ 10 | /* #undef HAVE_SETXATTR */ 11 | /* #undef HAVE_GETATTRLIST */ 12 | /* #undef HAVE_SETATTRLIST */ 13 | /* #undef HAVE_CHFLAGS */ 14 | #define HAVE_STATVFS 1 15 | #define HAVE_STATFS 1 16 | #define HAVE_EXT2FS_EXT2_FS_H 1 17 | /* #undef HAVE_STRUCT_STAT_ST_FLAGS */ 18 | /* #undef HAVE_STRUCT_STATVFS_F_FSTYPENAME */ 19 | /* #undef HAVE_STRUCT_STATFS_F_FSTYPENAME */ 20 | /* #undef HAVE_SYS_ACL_H */ 21 | /* #undef HAVE_LIBUTIL_H */ 22 | #define HAVE_ASPRINTF 1 23 | /* #undef HAVE_LIBBZ2 */ 24 | /* #undef HAVE_LIBLZMA */ 25 | #define HAVE_LCHOWN 1 26 | /* #undef HAVE_LCHMOD */ 27 | /* #undef HAVE_STRMODE */ 28 | #define UID_STRING RId32 29 | #define UID_CAST (uint32_t) 30 | #define GID_STRING PRId32 31 | #define GID_CAST (uint32_t) 32 | #define INO_STRING PRId64 33 | #define INO_HEXSTRING PRIx64 34 | #define INO_CAST (uint64_t) 35 | #define DEV_STRING PRId64 36 | #define DEV_HEXSTRING PRIx64 37 | #define DEV_CAST (uint64_t) 38 | 39 | /* Once spillover files are ready for use */ 40 | #undef SPILLOVER 41 | #define SQLITE_OMIT_LOAD_EXTENSION 42 | #define SQLITE_THREADSAFE 1 43 | #define SQLITE_OMIT_SHARED_CACHE 44 | -------------------------------------------------------------------------------- /memory.h: -------------------------------------------------------------------------------- 1 | #if !defined(NN2_MEMORY) 2 | #define NN2_MEMORY 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "logger.h" 9 | /* 10 | * memory allocation wrappers 11 | * These are lightweight and should catch the common allocation problems 12 | * -- One could add pretty easily hooks to a debugging malloc in here 13 | * -- or a garbage collector. ;) 14 | */ 15 | static __inline void *mem_alloc(size_t size) { 16 | register void *ptr; 17 | 18 | if ((ptr = malloc(size)) == NULL) 19 | Log(LOG_ERROR, "%s:malloc %d:%s", __FUNCTION__, errno, strerror(errno)); 20 | 21 | memset(ptr, 0, size); 22 | 23 | return ptr; 24 | } 25 | 26 | static __inline void *mem_realloc(void *ptr, size_t size) { 27 | register void *nptr; 28 | 29 | if ((nptr = realloc(ptr, size)) == NULL) 30 | Log(LOG_ERROR, "%s:realloc %d:%s", __FUNCTION__, errno, strerror(errno)); 31 | 32 | return nptr; 33 | } 34 | 35 | static __inline void mem_free(void *ptr) { 36 | /* 37 | * Force a crash if double free or a NULL ptr, should aid debugging 38 | */ 39 | assert(ptr != NULL); 40 | free(ptr); 41 | ptr = NULL; 42 | 43 | return; 44 | } 45 | 46 | static __inline void *mem_calloc(size_t nmemb, size_t size) { 47 | register void *p; 48 | 49 | assert(nmemb != 0); 50 | assert(size != 0); 51 | 52 | if ((p = calloc(nmemb, size)) == NULL) 53 | Log(LOG_ERROR, "%s:calloc %d:%s", __FUNCTION__, errno, strerror(errno)); 54 | 55 | return p; 56 | } 57 | #endif /* !defined(NN2_MEMORY) */ 58 | -------------------------------------------------------------------------------- /pkg_map.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "balloc.h" 10 | #include "dlink.h" 11 | #include "logger.h" 12 | #include "memory.h" 13 | #include "pkg.h" 14 | #include "str.h" 15 | 16 | /* This seems to be a BSD thing- it's not fatal if missing, so stub it */ 17 | #if !defined(MAP_NOSYNC) 18 | #define MAP_NOSYNC 0 19 | #endif /* !defined(MAP_NOSYNC) */ 20 | 21 | static BlockHeap *pkg_file_mapping_heap = NULL; 22 | 23 | void pkg_unmap_file(struct pkg_file_mapping *p) { 24 | if (p->addr != NULL && p->addr != MAP_FAILED) 25 | munmap(p->addr, p->len); 26 | 27 | if (p->pkg != NULL) 28 | mem_free(p->pkg); 29 | 30 | if (p->fd > 0) 31 | close(p->fd); 32 | 33 | blockheap_free(pkg_file_mapping_heap, p); 34 | p = NULL; 35 | } 36 | 37 | struct pkg_file_mapping *pkg_map_file(const char *path, size_t len, off_t offset) { 38 | struct pkg_file_mapping *p; 39 | 40 | p = blockheap_alloc(pkg_file_mapping_heap); 41 | 42 | p->pkg = str_dup(path); 43 | p->len = len; 44 | p->offset = offset; 45 | 46 | if (!(p->fd = open(p->pkg, O_RDONLY)) == -1) { 47 | Log(LOG_ERROR, "%s:open:%s %d:%s", __FUNCTION__, p->pkg, errno, strerror(errno)); 48 | pkg_unmap_file(p); 49 | return NULL; 50 | } 51 | 52 | if ((p->addr = 53 | mmap(0, len, PROT_READ | PROT_EXEC, MAP_NOSYNC | MAP_PRIVATE, 54 | p->fd, offset)) == MAP_FAILED) { 55 | Log(LOG_ERROR, "%s:mmap: %d:%s", __FUNCTION__, errno, strerror(errno)); 56 | pkg_unmap_file(p); 57 | } 58 | 59 | return p; 60 | } 61 | -------------------------------------------------------------------------------- /atomicio.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: atomicio.h,v 1.4 2001/06/26 06:32:46 itojun Exp $ */ 2 | 3 | /* 4 | * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /* 29 | * Ensure all of data on socket comes through. f==read || f==write 30 | */ 31 | #if !defined(NN2_ATOMICIO) 32 | #include 33 | #define NN2_ATOMICIO 34 | ssize_t atomicio(ssize_t(*)(), int, void *, size_t); 35 | #endif /* !defined(NN2_ATOMICIO) */ 36 | -------------------------------------------------------------------------------- /pkg.h: -------------------------------------------------------------------------------- 1 | struct pkg_handle { 2 | int fd; /* file descriptor for mmap() */ 3 | int refcnt; /* references to this package */ 4 | time_t otime; /* open time (for garbage collector) */ 5 | char *name; /* package name */ 6 | u_int32_t id; /* package ID */ 7 | }; 8 | 9 | struct pkg_object { 10 | u_int32_t pkg; 11 | char *name; 12 | char type; 13 | uid_t owner; 14 | gid_t grp; 15 | size_t size; 16 | off_t offset; 17 | time_t ctime; 18 | u_int32_t inode; 19 | }; 20 | 21 | struct pkg_file_mapping { 22 | char *pkg; /* package file */ 23 | size_t len; /* length of subfile */ 24 | off_t offset; /* offset of subfile */ 25 | int fd; /* file descriptor for mmap */ 26 | void *addr; /* mmap return address */ 27 | }; 28 | 29 | /* Initialize package handling/caching subsystem */ 30 | extern void pkg_init(void); 31 | 32 | /* Open a package */ 33 | extern struct pkg_handle *pkg_open(const char *path); 34 | 35 | /* Release our instance of package a*/ 36 | extern void pkg_close(struct pkg_handle *pkg); 37 | 38 | /* 'discover' a package, called by vfs watcher */ 39 | extern int pkg_import(const char *path); 40 | 41 | /* 'forget' a package, called by vfs_watcher */ 42 | extern int pkg_forget(const char *path); 43 | 44 | /* pkg_map.c */ 45 | extern void pkg_unmap_file(struct pkg_file_mapping *p); 46 | extern struct pkg_file_mapping *pkg_map_file(const char *path, size_t len, off_t offset); 47 | 48 | /* pkg_toc.c */ 49 | extern size_t pkg_toc_zbufsize; 50 | extern char *pkg_toc_extract(const char *path); 51 | extern int pkg_toc_process(const char *path, const char *toc); 52 | -------------------------------------------------------------------------------- /fuse/fuse_misc.h: -------------------------------------------------------------------------------- 1 | /* 2 | FUSE: Filesystem in Userspace 3 | Copyright (C) 2001-2007 Miklos Szeredi 4 | 5 | This program can be distributed under the terms of the GNU LGPLv2. 6 | See the file COPYING.LIB 7 | */ 8 | 9 | #include "config.h" 10 | #include 11 | 12 | /* Versioned symbols confuse the dynamic linker in uClibc */ 13 | #ifndef __UCLIBC__ 14 | #define FUSE_SYMVER(x) __asm__(x) 15 | #else 16 | #define FUSE_SYMVER(x) 17 | #endif 18 | 19 | #ifndef USE_UCLIBC 20 | #define fuse_mutex_init(mut) pthread_mutex_init(mut, NULL) 21 | #else 22 | /* Is this hack still needed? */ 23 | static inline void fuse_mutex_init(pthread_mutex_t *mut) 24 | { 25 | pthread_mutexattr_t attr; 26 | pthread_mutexattr_init(&attr); 27 | pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); 28 | pthread_mutex_init(mut, &attr); 29 | pthread_mutexattr_destroy(&attr); 30 | } 31 | #endif 32 | 33 | #ifdef HAVE_STRUCT_STAT_ST_ATIM 34 | /* Linux */ 35 | #define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atim.tv_nsec) 36 | #define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctim.tv_nsec) 37 | #define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtim.tv_nsec) 38 | #define ST_ATIM_NSEC_SET(stbuf, val) (stbuf)->st_atim.tv_nsec = (val) 39 | #define ST_MTIM_NSEC_SET(stbuf, val) (stbuf)->st_mtim.tv_nsec = (val) 40 | #elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC) 41 | /* FreeBSD */ 42 | #define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atimespec.tv_nsec) 43 | #define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctimespec.tv_nsec) 44 | #define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtimespec.tv_nsec) 45 | #define ST_ATIM_NSEC_SET(stbuf, val) (stbuf)->st_atimespec.tv_nsec = (val) 46 | #define ST_MTIM_NSEC_SET(stbuf, val) (stbuf)->st_mtimespec.tv_nsec = (val) 47 | #else 48 | #define ST_ATIM_NSEC(stbuf) 0 49 | #define ST_CTIM_NSEC(stbuf) 0 50 | #define ST_MTIM_NSEC(stbuf) 0 51 | #define ST_ATIM_NSEC_SET(stbuf, val) do { } while (0) 52 | #define ST_MTIM_NSEC_SET(stbuf, val) do { } while (0) 53 | #endif 54 | -------------------------------------------------------------------------------- /fuse/fuse_signals.c: -------------------------------------------------------------------------------- 1 | /* 2 | FUSE: Filesystem in Userspace 3 | Copyright (C) 2001-2007 Miklos Szeredi 4 | 5 | This program can be distributed under the terms of the GNU LGPLv2. 6 | See the file COPYING.LIB 7 | */ 8 | 9 | #include "fuse_lowlevel.h" 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | static struct fuse_session *fuse_instance; 16 | 17 | static void exit_handler(int sig) 18 | { 19 | (void) sig; 20 | if (fuse_instance) 21 | fuse_session_exit(fuse_instance); 22 | } 23 | 24 | static int set_one_signal_handler(int sig, void (*handler)(int)) 25 | { 26 | struct sigaction sa; 27 | struct sigaction old_sa; 28 | 29 | memset(&sa, 0, sizeof(struct sigaction)); 30 | sa.sa_handler = handler; 31 | sigemptyset(&(sa.sa_mask)); 32 | sa.sa_flags = 0; 33 | 34 | if (sigaction(sig, NULL, &old_sa) == -1) { 35 | perror("fuse: cannot get old signal handler"); 36 | return -1; 37 | } 38 | 39 | if (old_sa.sa_handler == SIG_DFL && 40 | sigaction(sig, &sa, NULL) == -1) { 41 | perror("fuse: cannot set signal handler"); 42 | return -1; 43 | } 44 | return 0; 45 | } 46 | 47 | int fuse_set_signal_handlers(struct fuse_session *se) 48 | { 49 | if (set_one_signal_handler(SIGHUP, exit_handler) == -1 || 50 | set_one_signal_handler(SIGINT, exit_handler) == -1 || 51 | set_one_signal_handler(SIGTERM, exit_handler) == -1 || 52 | set_one_signal_handler(SIGPIPE, SIG_IGN) == -1) 53 | return -1; 54 | 55 | fuse_instance = se; 56 | return 0; 57 | } 58 | 59 | void fuse_remove_signal_handlers(struct fuse_session *se) 60 | { 61 | if (fuse_instance != se) 62 | fprintf(stderr, 63 | "fuse: fuse_remove_signal_handlers: unknown session\n"); 64 | else 65 | fuse_instance = NULL; 66 | 67 | set_one_signal_handler(SIGHUP, SIG_DFL); 68 | set_one_signal_handler(SIGINT, SIG_DFL); 69 | set_one_signal_handler(SIGTERM, SIG_DFL); 70 | set_one_signal_handler(SIGPIPE, SIG_DFL); 71 | } 72 | 73 | -------------------------------------------------------------------------------- /inode.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "conf.h" 4 | #include "db.h" 5 | #include "inode.h" 6 | #include "logger.h" 7 | BlockHeap *inode_heap; 8 | 9 | #if 0 10 | void fill_statbuf(ext2_ino_t ino, pkg_inode_t * inode, struct stat *st) { 11 | /* 12 | * st_dev 13 | */ 14 | st->st_ino = ino; 15 | st->st_mode = inode->i_mode; 16 | st->st_nlink = inode->i_links_count; 17 | st->st_uid = inode->i_uid; /* add in uid_high */ 18 | st->st_gid = inode->i_gid; /* add in gid_high */ 19 | /* 20 | * st_rdev 21 | */ 22 | st->st_size = inode->i_size; 23 | st->st_blksize = EXT2_BLOCK_SIZE(fs->super); 24 | st->st_blocks = inode->i_blocks; 25 | 26 | /* 27 | * We don't have to implement nanosecs, fs's which don't can return 28 | * * 0 here 29 | */ 30 | /* 31 | * Using _POSIX_C_SOURCE might also work 32 | */ 33 | #ifdef __APPLE__ 34 | st->st_atimespec.tv_sec = inode->i_atime; 35 | st->st_mtimespec.tv_sec = inode->i_mtime; 36 | st->st_ctimespec.tv_sec = inode->i_ctime; 37 | st->st_atimespec.tv_nsec = 0; 38 | st->st_mtimespec.tv_nsec = 0; 39 | st->st_ctimespec.tv_nsec = 0; 40 | #else 41 | st->st_atime = inode->i_atime; 42 | st->st_mtime = inode->i_mtime; 43 | st->st_ctime = inode->i_ctime; 44 | #ifdef __FreeBSD__ 45 | st->st_atimespec.tv_nsec = 0; 46 | st->st_mtimespec.tv_nsec = 0; 47 | st->st_ctimespec.tv_nsec = 0; 48 | #else 49 | st->st_atim.tv_nsec = 0; 50 | st->st_mtim.tv_nsec = 0; 51 | st->st_ctim.tv_nsec = 0; 52 | #endif 53 | #endif 54 | } 55 | #endif 56 | 57 | void inode_init(void) { 58 | if (! 59 | (inode_heap = 60 | blockheap_create(sizeof(struct pkg_inode), 61 | dconf_get_int("tuning.heap.inode", 128), "pkg"))) { 62 | Log(LOG_FATAL, "inode_init(): block allocator failed"); 63 | raise(SIGTERM); 64 | } 65 | } 66 | 67 | void inode_fini(void) { 68 | blockheap_destroy(inode_heap); 69 | } 70 | -------------------------------------------------------------------------------- /balloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005 William Pitcock, et al. 3 | * Rights to this code are as documented in doc/LICENSE. 4 | * 5 | * Data structures for the block allocator. 6 | * 7 | * $Id: balloc.h 7779 2007-03-03 13:55:42Z pippijn $ 8 | */ 9 | 10 | #ifndef NN2_BALLOC 11 | #define NN2_BALLOC 12 | #include 13 | #include 14 | #include "dlink.h" 15 | struct Block { 16 | size_t alloc_size; 17 | struct Block *next; /* Next in our chain of blocks */ 18 | void *elems; /* Points to allocated memory */ 19 | dlink_list free_list; 20 | dlink_list used_list; 21 | }; 22 | typedef struct Block Block; 23 | 24 | struct MemBlock { 25 | #ifdef DEBUG_BALLOC 26 | unsigned long magic; 27 | #endif 28 | dlink_node self; 29 | Block *block; /* Which block we belong to */ 30 | }; 31 | 32 | typedef struct MemBlock MemBlock; 33 | 34 | /* information for the root node of the heap */ 35 | struct BlockHeap { 36 | dlink_node hlist; 37 | char name[64]; /* heap name */ 38 | size_t elemSize; /* Size of each element to be stored */ 39 | unsigned long elemsPerBlock; /* Number of elements per block */ 40 | unsigned long blocksAllocated; /* Number of blocks allocated */ 41 | unsigned long freeElems; /* Number of free elements */ 42 | Block *base; /* Pointer to first block */ 43 | }; 44 | typedef struct BlockHeap BlockHeap; 45 | 46 | extern int blockheap_free(BlockHeap * bh, void *ptr); 47 | extern void *blockheap_alloc(BlockHeap * bh); 48 | 49 | extern BlockHeap *blockheap_create(size_t elemsize, int elemsperblock, const char *name); 50 | extern int blockheap_destroy(BlockHeap * bh); 51 | 52 | extern void blockheap_init(void); 53 | extern void blockheap_usage(BlockHeap * bh, size_t * bused, size_t * bfree, size_t * bmemusage); 54 | 55 | #endif /* !defined(NN2_BALLOC) */ 56 | -------------------------------------------------------------------------------- /xar/script.h: -------------------------------------------------------------------------------- 1 | /* 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 3. Neither the name of Apple nor the names of any contributors 13 | * may be used to endorse or promote products derived from this software 14 | * without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | /* 29 | * Portions Copyright 2006, Apple Computer, Inc. 30 | * Christopher Ryan 31 | */ 32 | 33 | #ifndef _SCRIPT_H_ 34 | #define _SCRIPT_H_ 35 | 36 | int32_t xar_script_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); 37 | int32_t xar_script_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); 38 | 39 | #endif /* _SCRIPT_H_ */ 40 | -------------------------------------------------------------------------------- /atomicio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #include 27 | #include 28 | #include "atomicio.h" 29 | 30 | /* 31 | * ensure all of data on socket comes through. f==read || f==write 32 | */ 33 | ssize_t atomicio(ssize_t(*f) (), int fd, void *_s, size_t n) { 34 | char *s = _s; 35 | ssize_t res, pos = 0; 36 | 37 | while (n > pos) { 38 | res = (f) (fd, s + pos, n - pos); 39 | switch (res) { 40 | case -1: 41 | if (errno == EINTR || errno == EAGAIN) 42 | continue; 43 | case 0: 44 | return (res); 45 | default: 46 | pos += res; 47 | } 48 | } 49 | return (pos); 50 | } 51 | -------------------------------------------------------------------------------- /vfs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "balloc.h" 9 | #include "conf.h" 10 | #include "logger.h" 11 | #include "pkg.h" 12 | #include "util.h" 13 | #include "vfs.h" 14 | 15 | u_int32_t vfs_root_inode; 16 | 17 | BlockHeap *vfs_handle_heap = NULL; 18 | BlockHeap *vfs_watch_heap = NULL; 19 | dlink_list vfs_watch_list; 20 | 21 | /* We do not want to infinitely recurse... */ 22 | #define MAX_RECURSE 16 23 | 24 | static void vfs_dir_walk_recurse(const char *path, int depth) { 25 | DIR *d; 26 | struct dirent *r; 27 | char *ext; 28 | char buf[PATH_MAX]; 29 | 30 | if ((d = opendir(path)) == NULL) { 31 | Log(LOG_ERROR, "opendir %s failed, skipping", path); 32 | return; 33 | } 34 | 35 | while ((r = readdir(d)) != NULL) { 36 | /* 37 | * Skip over hidden/disabled items 38 | */ 39 | if (r->d_name[0] == '.') 40 | continue; 41 | memset(buf, 0, PATH_MAX); 42 | snprintf(buf, PATH_MAX - 1, "%s/%s", path, r->d_name); 43 | 44 | if (is_dir(buf)) { 45 | if (++depth < MAX_RECURSE) 46 | vfs_dir_walk_recurse(buf, depth); 47 | else 48 | Log(LOG_INFO, "%s: reached maximum depth (%d) in %s", __FUNCTION__, MAX_RECURSE, path); 49 | } else { 50 | ext = strrchr(buf, '.'); 51 | if (strncmp(ext, ".pkg", 4) && strncmp(ext, ".xar", 4)) 52 | return; 53 | pkg_import(buf); 54 | } 55 | } 56 | 57 | closedir(d); 58 | } 59 | 60 | #undef MAX_RECURSE 61 | 62 | int vfs_dir_walk(void) { 63 | char buf[PATH_MAX]; 64 | char *p; 65 | 66 | memcpy(buf, dconf_get_str("path.pkg", "/pkg"), PATH_MAX); 67 | 68 | /* 69 | * recurse each part of the optionally ':' seperated list 70 | */ 71 | for (p = strtok(buf, ":\n"); p; p = strtok(NULL, ":\n")) { 72 | /* 73 | * Run the recursive walker 74 | */ 75 | vfs_dir_walk_recurse(p, 1); 76 | } 77 | return EXIT_SUCCESS; 78 | } 79 | -------------------------------------------------------------------------------- /xar/fbsdattr.h: -------------------------------------------------------------------------------- 1 | /* All rights reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 1. Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * 2. Redistributions in binary form must reproduce the above copyright 9 | * notice, this list of conditions and the following disclaimer in the 10 | * documentation and/or other materials provided with the distribution. 11 | * 3. Neither the name of Apple nor the names of any contributors 12 | * may be used to endorse or promote products derived from this software 13 | * without specific prior written permission. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 | * POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | /* 28 | * Rob Braun 29 | * 26-Oct-2004 30 | * Copyright (c) 2004 Rob Braun. All rights reserved. 31 | */ 32 | /* 33 | * Portions Copyright 2006, Apple Computer, Inc. 34 | * Christopher Ryan 35 | */ 36 | 37 | #ifndef _XAR_FBSDATTR_H_ 38 | #define _XAR_FBSDATTR_H_ 39 | int32_t xar_fbsdattr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); 40 | int32_t xar_fbsdattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); 41 | #endif /* _XAR_FBSDATTR_H_ */ 42 | -------------------------------------------------------------------------------- /xar/linuxattr.h: -------------------------------------------------------------------------------- 1 | /* All rights reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 1. Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * 2. Redistributions in binary form must reproduce the above copyright 9 | * notice, this list of conditions and the following disclaimer in the 10 | * documentation and/or other materials provided with the distribution. 11 | * 3. Neither the name of Apple nor the names of any contributors 12 | * may be used to endorse or promote products derived from this software 13 | * without specific prior written permission. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 | * POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | /* 28 | * Rob Braun 29 | * 26-Oct-2004 30 | * Copyright (c) 2004 Rob Braun. All rights reserved. 31 | */ 32 | /* 33 | * Portions Copyright 2006, Apple Computer, Inc. 34 | * Christopher Ryan 35 | */ 36 | 37 | #ifndef _XAR_LINUXATTR_H_ 38 | #define _XAR_LINUXATTR_H_ 39 | int32_t xar_linuxattr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); 40 | int32_t xar_linuxattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); 41 | #endif /* _XAR_LINUXATTR_H_ */ 42 | -------------------------------------------------------------------------------- /xar/ext2.h: -------------------------------------------------------------------------------- 1 | /* All rights reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 1. Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * 2. Redistributions in binary form must reproduce the above copyright 9 | * notice, this list of conditions and the following disclaimer in the 10 | * documentation and/or other materials provided with the distribution. 11 | * 3. Neither the name of Apple nor the names of any contributors 12 | * may be used to endorse or promote products derived from this software 13 | * without specific prior written permission. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 | * POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | /* 28 | * Rob Braun 29 | * 26-Oct-2004 30 | * Copyright (c) 2004 Rob Braun. All rights reserved. 31 | */ 32 | /* 33 | * Portions Copyright 2006, Apple Computer, Inc. 34 | * Christopher Ryan 35 | */ 36 | 37 | #ifndef _XAR_EXT2_H_ 38 | #define _XAR_EXT2_H_ 39 | #define XAR_ATTR_FORK "attribute" 40 | int xar_ext2attr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); 41 | int xar_ext2attr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); 42 | #endif /* _XAR_EXT2_H_ */ 43 | -------------------------------------------------------------------------------- /timestr.c: -------------------------------------------------------------------------------- 1 | #define _BSD_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "timestr.h" 9 | /* these two are used to convert from/to a formatted time string. the string 10 | * should be of the format [Xd][Xh][Xm][X][s]. e.g. 3600 is 3600s, or 1h. 11 | * either lower or upper case is acceptable. */ 12 | time_t nn2_timestr_to_time(const char *str, const time_t def) { 13 | char *s; 14 | char *s2; 15 | time_t ret = 0; 16 | 17 | if (str == NULL) 18 | return def; 19 | 20 | s = s2 = strdup(str); 21 | while (*s2 != '\0') { 22 | *s2 = tolower(*s2); 23 | s2++; 24 | } 25 | 26 | s2 = strchr(s, 'd'); 27 | if (s2 != NULL) { 28 | *s2 = '\0'; 29 | ret += strtol(s, NULL, 0) * 86400; /* days */ 30 | s = s2 + 1; 31 | } 32 | s2 = strchr(s, 'h'); 33 | if (s2 != NULL) { 34 | *s2 = '\0'; 35 | ret += strtol(s, NULL, 0) * 3600; /* hours */ 36 | s = s2 + 1; 37 | } 38 | s2 = strchr(s, 'm'); 39 | if (s2 != NULL) { 40 | *s2 = '\0'; 41 | ret += strtol(s, NULL, 0) * 60; /* minutes */ 42 | s = s2 + 1; 43 | } 44 | ret += strtol(s, NULL, 0); /* seconds */ 45 | 46 | return ret; 47 | } 48 | 49 | char *nn2_time_to_timestr(time_t itime) { 50 | int d, h, m, s; 51 | static char rbuf[64]; 52 | int rlen = 0; 53 | 54 | d = itime / 86400; /* days */ 55 | itime %= 86400; 56 | h = itime / 3600; /* hours */ 57 | itime %= 3600; 58 | m = itime / 60; /* minutes */ 59 | itime %= 60; 60 | s = itime; 61 | 62 | if (d) 63 | rlen += snprintf(rbuf + rlen, 64, "%dd", d); 64 | if (h) 65 | rlen += snprintf(rbuf + rlen, 64, "%dh", h); 66 | if (m) 67 | rlen += snprintf(rbuf + rlen, 64, "%dm", m); 68 | if (s) 69 | rlen += snprintf(rbuf + rlen, 64, "%ds", s); 70 | if (!rlen) { /* if we haven't added anything, it's 0s */ 71 | rbuf[0] = '0'; 72 | rbuf[1] = 's'; 73 | rbuf[2] = '\0'; 74 | } 75 | 76 | return rbuf; 77 | } 78 | -------------------------------------------------------------------------------- /xar/data.h: -------------------------------------------------------------------------------- 1 | /* 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 3. Neither the name of Apple nor the names of any contributors 13 | * may be used to endorse or promote products derived from this software 14 | * without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | /* 29 | * Rob Braun 30 | * 21-Apr-2004 31 | * Copyright (c) 2004 Rob Braun. All rights reserved. 32 | */ 33 | /* 34 | * Portions Copyright 2006, Apple Computer, Inc. 35 | * Christopher Ryan 36 | */ 37 | 38 | #ifndef _XAR_DATA_H_ 39 | #define _XAR_DATA_H_ 40 | int32_t xar_data_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); 41 | int32_t xar_data_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); 42 | 43 | int32_t xar_data_verify(xar_t x, xar_file_t f); 44 | #endif /* _XAR_DATA_H_ */ 45 | -------------------------------------------------------------------------------- /xar/darwinattr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 3. Neither the name of Apple nor the names of any contributors 13 | * may be used to endorse or promote products derived from this software 14 | * without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | /* 29 | * Rob Braun 30 | * 23-Apr-2005 31 | * Copyright (c) 2004 Rob Braun. All rights reserved. 32 | */ 33 | /* 34 | * Portions Copyright 2006, Apple Computer, Inc. 35 | * Christopher Ryan 36 | */ 37 | 38 | #ifndef _XAR_DARWINATTR_H_ 39 | #define _XAR_DARWINATTR_H_ 40 | xar_file_t xar_underbar_check(xar_t x, xar_file_t f, const char* file); 41 | int32_t xar_darwinattr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); 42 | int32_t xar_darwinattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); 43 | #endif /* _XAR_DARWINATTR_H_ */ 44 | -------------------------------------------------------------------------------- /xar/lzmaxar.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005 Rob Braun 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of Rob Braun nor the names of his contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | /* 30 | * 31 | * DRI: 32 | */ 33 | /* 34 | * Portions Copyright 2006, Apple Computer, Inc. 35 | * Christopher Ryan 36 | */ 37 | 38 | #ifndef _XAR_LZMA_H_ 39 | #define _XAR_LZMA_H_ 40 | 41 | int xar_lzma_fromheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); 42 | int xar_lzma_fromheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); 43 | 44 | int32_t xar_lzma_toheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); 45 | int xar_lzma_toheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); 46 | 47 | #endif /* _XAR_LZMA_H_ */ 48 | -------------------------------------------------------------------------------- /xar/zxar.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2007 Rob Braun 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of Rob Braun nor the names of his contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | /* 30 | * 03-Apr-2005 31 | * DRI: Rob Braun 32 | */ 33 | /* 34 | * Portions Copyright 2006, Apple Computer, Inc. 35 | * Christopher Ryan 36 | */ 37 | 38 | #ifndef _XAR_ZLIB_H_ 39 | #define _XAR_ZLIB_H_ 40 | 41 | int xar_gzip_fromheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); 42 | int xar_gzip_fromheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); 43 | 44 | int32_t xar_gzip_toheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); 45 | int xar_gzip_toheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); 46 | #endif /* _XAR_ZLIB_H_ */ 47 | -------------------------------------------------------------------------------- /xar/bzxar.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2007 Rob Braun 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of Rob Braun nor the names of his contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | /* 30 | * 03-Apr-2005 31 | * DRI: Rob Braun 32 | */ 33 | /* 34 | * Portions Copyright 2006, Apple Computer, Inc. 35 | * Christopher Ryan 36 | */ 37 | 38 | #ifndef _XAR_BZLIB_H_ 39 | #define _XAR_BZLIB_H_ 40 | 41 | int xar_bzip_fromheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); 42 | int xar_bzip_fromheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); 43 | 44 | int32_t xar_bzip_toheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); 45 | int xar_bzip_toheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); 46 | 47 | #endif /* _XAR_BZLIB_H_ */ 48 | -------------------------------------------------------------------------------- /xar/stat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2007 Rob Braun 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of Rob Braun nor the names of his contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | /* 30 | * 03-Apr-2005 31 | * DRI: Rob Braun 32 | */ 33 | /* 34 | * Portions Copyright 2006, Apple Computer, Inc. 35 | * Christopher Ryan 36 | */ 37 | 38 | #ifndef _XAR_STAT_H_ 39 | #define _XAR_STAT_H_ 40 | 41 | #include "xar.h" 42 | 43 | int32_t xar_stat_archive(xar_t x, xar_file_t f, const char *file, const char *buffer, size_t len); 44 | int32_t xar_stat_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len); 45 | int32_t xar_set_perm(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len); 46 | int32_t xar_flags_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len); 47 | 48 | #endif /* _XAR_STAT_H_ */ 49 | -------------------------------------------------------------------------------- /xar/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2007 Rob Braun 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of Rob Braun nor the names of his contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | /* 30 | * 03-Apr-2005 31 | * DRI: Rob Braun 32 | */ 33 | /* 34 | * Portions Copyright 2006, Apple Computer, Inc. 35 | * Christopher Ryan 36 | */ 37 | 38 | #ifndef _XAR_UTIL_H_ 39 | #define _XAR_UTIL_H_ 40 | 41 | #include 42 | #include "xar.h" 43 | 44 | 45 | uint64_t xar_ntoh64(uint64_t num); 46 | uint32_t xar_swap32(uint32_t num); 47 | char *xar_get_path(xar_file_t f); 48 | off_t xar_get_heap_offset(xar_t x); 49 | ssize_t xar_read_fd(int fd, void * buffer, size_t nbytes); 50 | ssize_t xar_write_fd(int fd, void * buffer, size_t nbytes); 51 | dev_t xar_makedev(uint32_t major, uint32_t minor); 52 | void xar_devmake(dev_t dev, uint32_t *major, uint32_t *minor); 53 | 54 | #endif /* _XAR_UTIL_H_ */ 55 | -------------------------------------------------------------------------------- /logger.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "conf.h" 7 | #include "logger.h" 8 | 9 | FILE *log_open(const char *path) { 10 | FILE *fp; 11 | char *lvl; 12 | 13 | lvl = dconf_get_str("log.level", 0); 14 | 15 | /* 16 | * parse the debug level 17 | */ 18 | if (!strcasecmp(lvl, "debug")) 19 | conf.log_level = LOG_DEBUG; 20 | else if (!strcasecmp(lvl, "info")) 21 | conf.log_level = LOG_INFO; 22 | else if (!strcasecmp(lvl, "hack")) 23 | conf.log_level = LOG_HACK; 24 | else if (!strcasecmp(lvl, "warning")) 25 | conf.log_level = LOG_WARNING; 26 | else if (!strcasecmp(lvl, "error")) 27 | conf.log_level = LOG_ERROR; 28 | else if (!strcasecmp(lvl, "fatal")) 29 | conf.log_level = LOG_FATAL; 30 | 31 | if ((fp = fopen(path, "w")) == NULL) { 32 | Log(LOG_ERROR, "Unable to open log file %s: %d (%s)", path, errno, strerror(errno)); 33 | return NULL; 34 | } 35 | 36 | return fp; 37 | } 38 | 39 | void log_close(FILE * fp) { 40 | if (fp != NULL) { 41 | fclose(fp); 42 | fp = NULL; 43 | } 44 | } 45 | 46 | void Log(enum log_priority priority, const char *fmt, ...) { 47 | va_list ap; 48 | char timestamp[64]; 49 | time_t t; 50 | struct tm *tm; 51 | char *level = NULL; 52 | 53 | if (priority < conf.log_level) { 54 | return; 55 | } 56 | 57 | if (!conf.log_fp) 58 | conf.log_fp = stdout; 59 | 60 | va_start(ap, fmt); 61 | t = time(NULL); 62 | tm = localtime(&t); 63 | 64 | switch (priority) { 65 | case LOG_DEBUG: 66 | level = "debug"; 67 | break; 68 | case LOG_INFO: 69 | level = "info"; 70 | break; 71 | case LOG_WARNING: 72 | level = "warning"; 73 | break; 74 | case LOG_ERROR: 75 | level = "error"; 76 | break; 77 | case LOG_FATAL: 78 | level = "critical"; 79 | break; 80 | case LOG_HACK: 81 | level = "hack"; 82 | break; 83 | default: 84 | level = "unknown"; 85 | break; 86 | } 87 | 88 | strftime(timestamp, sizeof(timestamp) - 1, "%Y/%m/%d %H:%M:%S", tm); 89 | fprintf(conf.log_fp, "[%s] %s: ", timestamp, level); 90 | vfprintf(conf.log_fp, fmt, ap); 91 | fprintf(conf.log_fp, "\n"); 92 | fflush(conf.log_fp); 93 | 94 | va_end(ap); 95 | } 96 | -------------------------------------------------------------------------------- /fuse/fuse_kern_chan.c: -------------------------------------------------------------------------------- 1 | /* 2 | FUSE: Filesystem in Userspace 3 | Copyright (C) 2001-2007 Miklos Szeredi 4 | 5 | This program can be distributed under the terms of the GNU LGPLv2. 6 | See the file COPYING.LIB 7 | */ 8 | 9 | #include "fuse_lowlevel.h" 10 | #include "fuse_kernel.h" 11 | #include "fuse_i.h" 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | static int fuse_kern_chan_receive(struct fuse_chan **chp, char *buf, 19 | size_t size) 20 | { 21 | struct fuse_chan *ch = *chp; 22 | int err; 23 | ssize_t res; 24 | struct fuse_session *se = fuse_chan_session(ch); 25 | assert(se != NULL); 26 | 27 | restart: 28 | res = read(fuse_chan_fd(ch), buf, size); 29 | err = errno; 30 | 31 | if (fuse_session_exited(se)) 32 | return 0; 33 | if (res == -1) { 34 | /* ENOENT means the operation was interrupted, it's safe 35 | to restart */ 36 | if (err == ENOENT) 37 | goto restart; 38 | 39 | if (err == ENODEV) { 40 | fuse_session_exit(se); 41 | return 0; 42 | } 43 | /* Errors occuring during normal operation: EINTR (read 44 | interrupted), EAGAIN (nonblocking I/O), ENODEV (filesystem 45 | umounted) */ 46 | if (err != EINTR && err != EAGAIN) 47 | perror("fuse: reading device"); 48 | return -err; 49 | } 50 | if ((size_t) res < sizeof(struct fuse_in_header)) { 51 | fprintf(stderr, "short read on fuse device\n"); 52 | return -EIO; 53 | } 54 | return res; 55 | } 56 | 57 | static int fuse_kern_chan_send(struct fuse_chan *ch, const struct iovec iov[], 58 | size_t count) 59 | { 60 | if (iov) { 61 | ssize_t res = writev(fuse_chan_fd(ch), iov, count); 62 | int err = errno; 63 | 64 | if (res == -1) { 65 | struct fuse_session *se = fuse_chan_session(ch); 66 | 67 | assert(se != NULL); 68 | 69 | /* ENOENT means the operation was interrupted */ 70 | if (!fuse_session_exited(se) && err != ENOENT) 71 | perror("fuse: writing device"); 72 | return -err; 73 | } 74 | } 75 | return 0; 76 | } 77 | 78 | static void fuse_kern_chan_destroy(struct fuse_chan *ch) 79 | { 80 | close(fuse_chan_fd(ch)); 81 | } 82 | 83 | #define MIN_BUFSIZE 0x21000 84 | 85 | struct fuse_chan *fuse_kern_chan_new(int fd) 86 | { 87 | struct fuse_chan_ops op = { 88 | .receive = fuse_kern_chan_receive, 89 | .send = fuse_kern_chan_send, 90 | .destroy = fuse_kern_chan_destroy, 91 | }; 92 | size_t bufsize = getpagesize() + 0x1000; 93 | bufsize = bufsize < MIN_BUFSIZE ? MIN_BUFSIZE : bufsize; 94 | return fuse_chan_new(&op, fd, bufsize, NULL); 95 | } 96 | -------------------------------------------------------------------------------- /xar/macho.h: -------------------------------------------------------------------------------- 1 | /* All rights reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 1. Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * 2. Redistributions in binary form must reproduce the above copyright 9 | * notice, this list of conditions and the following disclaimer in the 10 | * documentation and/or other materials provided with the distribution. 11 | * 3. Neither the name of Apple nor the names of any contributors 12 | * may be used to endorse or promote products derived from this software 13 | * without specific prior written permission. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 | * POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | /* 28 | * Portions Copyright 2006, Apple Computer, Inc. 29 | * Christopher Ryan 30 | */ 31 | 32 | #ifndef _MACHO_H_ 33 | #define _MACHO_H_ 34 | 35 | #include "xar.h" 36 | #include "filetree.h" 37 | 38 | struct mach_header { 39 | uint32_t magic; 40 | uint32_t cputype; 41 | uint32_t cpusubtype; 42 | uint32_t filetype; 43 | uint32_t ncmds; 44 | uint32_t sizeofcmds; 45 | uint32_t flags; 46 | }; 47 | 48 | struct lc { 49 | uint32_t cmd; 50 | uint32_t cmdsize; 51 | }; 52 | 53 | struct fat_header { 54 | uint32_t magic; 55 | uint32_t nfat_arch; 56 | }; 57 | 58 | struct fat_arch { 59 | uint32_t cputype; 60 | uint32_t cpusubtype; 61 | uint32_t offset; 62 | uint32_t size; 63 | uint32_t alighn; 64 | }; 65 | 66 | int32_t xar_macho_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); 67 | int32_t xar_macho_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); 68 | 69 | #endif /* _MACHO_H_ */ 70 | -------------------------------------------------------------------------------- /xar/hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2007 Rob Braun 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of Rob Braun nor the names of his contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | /* 30 | * 03-Apr-2005 31 | * DRI: Rob Braun 32 | */ 33 | /* 34 | * Portions Copyright 2006, Apple Computer, Inc. 35 | * Christopher Ryan 36 | */ 37 | 38 | #ifndef _XAR_HASH_H_ 39 | #define _XAR_HASH_H_ 40 | 41 | #include "filetree.h" 42 | 43 | int32_t xar_hash_archived(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); 44 | int32_t xar_hash_archived_in(xar_t x, xar_file_t f, xar_prop_t p, void *in, size_t inlen, void **context); 45 | 46 | int32_t xar_hash_unarchived(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); 47 | int32_t xar_hash_unarchived_out(xar_t x, xar_file_t f, xar_prop_t p, void *in, size_t inlen, void **context); 48 | 49 | int32_t xar_hash_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); 50 | int32_t xar_hash_out_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); 51 | 52 | #endif /* _XAR_HASH_H_ */ 53 | -------------------------------------------------------------------------------- /xar/arcmod.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2007 Rob Braun 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of Rob Braun nor the names of his contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | /* 30 | * 03-Apr-2005 31 | * DRI: Rob Braun 32 | */ 33 | /* 34 | * Portions Copyright 2006, Apple Computer, Inc. 35 | * Christopher Ryan 36 | */ 37 | 38 | 39 | #ifndef _XAR_ARCMOD_H_ 40 | #define _XAR_ARCMOD_H_ 41 | #include "xar.h" 42 | #include "filetree.h" 43 | 44 | 45 | typedef int32_t (*arcmod_archive)(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); 46 | typedef int32_t (*arcmod_extract)(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); 47 | 48 | struct arcmod { 49 | arcmod_archive archive; 50 | arcmod_extract extract; 51 | }; 52 | 53 | int32_t xar_arcmod_archive(xar_t x, xar_file_t f, const char *file, const char *buffer, size_t len); 54 | int32_t xar_arcmod_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len); 55 | 56 | int32_t xar_arcmod_verify(xar_t x, xar_file_t f); 57 | int32_t xar_check_prop(xar_t x, const char *name); 58 | 59 | #endif /* _XAR_ARCMOD_H_ */ 60 | -------------------------------------------------------------------------------- /xar/signature.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006 Apple Computer, Inc. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of Apple nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | /* 30 | * 6-July-2006 31 | * DRI: Christopher Ryan 32 | */ 33 | 34 | #ifndef _XAR_SIGNATURE_H_ 35 | #define _XAR_SIGNATURE_H_ 36 | 37 | #include "xar.h" 38 | 39 | struct __xar_x509cert_t{ 40 | uint8_t *content; 41 | int32_t len; 42 | struct __xar_x509cert_t *next; 43 | }; 44 | 45 | struct __xar_signature_t { 46 | char *type; 47 | int32_t len; 48 | off_t offset; 49 | int32_t x509cert_count; 50 | struct __xar_x509cert_t *x509certs; 51 | struct __xar_signature_t *next; 52 | xar_signer_callback signer_callback; /* callback for signing */ 53 | void *callback_context; /* context for callback */ 54 | xar_t x; 55 | }; 56 | 57 | #define XAR_SIGNATURE(x) ((struct __xar_signature_t *)(x)) 58 | 59 | int32_t xar_signature_serialize(xar_signature_t sig, xmlTextWriterPtr writer); 60 | xar_signature_t xar_signature_unserialize(xar_t x, xmlTextReaderPtr reader); 61 | 62 | 63 | /* deallocates the link list of xar signatures */ 64 | void xar_signature_remove(xar_signature_t sig); 65 | 66 | #endif /* _XAR_SIGNATURE_H_ */ 67 | -------------------------------------------------------------------------------- /xar/subdoc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2007 Rob Braun 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of Rob Braun nor the names of his contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | /* 30 | * 03-Apr-2005 31 | * DRI: Rob Braun 32 | */ 33 | 34 | #ifndef _XAR_SUBDOC_H_ 35 | #define _XAR_SUBDOC_H_ 36 | 37 | #include "xar.h" 38 | #include "filetree.h" 39 | 40 | struct __xar_subdoc_t { 41 | struct __xar_prop_t *props; 42 | struct __xar_attr_t *attrs; 43 | const char *prefix; 44 | const char *ns; 45 | const char *blank1; /* filler for xar_file_t compatibility */ 46 | const char *blank2; /* filler for xar_file_t compatibility */ 47 | const char blank3; /* filler for xar_file_t compatibility */ 48 | const char *name; 49 | struct __xar_subdoc_t *next; 50 | const char *value; /* a subdoc should very rarely have a value */ 51 | xar_t x; 52 | }; 53 | 54 | #define XAR_SUBDOC(x) ((struct __xar_subdoc_t *)(x)) 55 | 56 | void xar_subdoc_unserialize(xar_subdoc_t s, xmlTextReaderPtr reader); 57 | void xar_subdoc_serialize(xar_subdoc_t s, xmlTextWriterPtr writer, int wrap); 58 | void xar_subdoc_free(xar_subdoc_t s); 59 | xar_subdoc_t xar_subdoc_find(xar_t x, const char *name); 60 | 61 | #endif /* _XAR_SUBDOC_H_ */ 62 | -------------------------------------------------------------------------------- /dlink.h: -------------------------------------------------------------------------------- 1 | /* Sentinel - IRC Statistical and Operator Services 2 | ** dlink.h - Hybrid/Squid derived doubly linked list library 3 | ** 4 | ** Copyright W. Campbell and others. See README for more details 5 | ** Some code Copyright: Jonathan George, Kai Seidler, ircd-hybrid Team, 6 | ** IRCnet IRCD developers. 7 | ** 8 | ** $Id: dlink.h,v 1.1 2003/09/11 14:37:19 wcampbel Exp $ 9 | */ 10 | 11 | /* Original Header: */ 12 | 13 | /* #Id: tools.h,v 1.5 2002/09/11 17:55:38 db Exp # */ 14 | #ifndef NN2_DLINK 15 | #define NN2_DLINK 16 | 17 | typedef struct _dlink_node dlink_node; 18 | 19 | typedef struct _dlink_list dlink_list; 20 | 21 | struct _dlink_node { 22 | void *data; 23 | dlink_node *next; 24 | dlink_node *prev; 25 | }; 26 | 27 | struct _dlink_list { 28 | dlink_node *head; 29 | dlink_node *tail; 30 | unsigned long length; 31 | }; 32 | 33 | extern int dlink_count; 34 | extern dlink_node *dlink_create(void); 35 | extern void dlink_free(dlink_node * m); 36 | extern void dlink_add(void *data, dlink_node * m, dlink_list * list); 37 | extern void dlink_add_before(dlink_node * b, void *data, dlink_node * m, dlink_list * list); 38 | extern void dlink_add_tail(void *data, dlink_node * m, dlink_list * list); 39 | extern void dlink_delete(dlink_node * m, dlink_list * list); 40 | extern dlink_node *dlink_find(void *data, dlink_list * list); 41 | extern dlink_node *dlink_find_delete(void *data, dlink_list * list); 42 | extern int dlink_length(dlink_list * list); 43 | extern void dlink_move(dlink_node * m, dlink_list * oldlist, dlink_list * newlist); 44 | extern void dlink_init(void); 45 | extern void dlink_fini(void); 46 | 47 | /* These macros are basically swiped from the linux kernel 48 | * they are simple yet effective 49 | */ 50 | 51 | /* 52 | * Walks forward of a list. 53 | * pos is your node 54 | * head is your list head 55 | */ 56 | #define DLINK_FOREACH(pos, head) for (pos = (head); pos != NULL; pos = pos->next) 57 | 58 | /* 59 | * Walks forward of a list safely while removing nodes 60 | * pos is your node 61 | * n is another list head for temporary storage 62 | * head is your list head 63 | */ 64 | #define DLINK_FOREACH_SAFE(pos, n, head) for (pos = (head), n = pos ? pos->next : NULL; pos != NULL; pos = n, n = pos ? pos->next : NULL) 65 | 66 | #define DLINK_FOREACH_PREV(pos, head) for (pos = (head); pos != NULL; pos = pos->prev) 67 | #define DLINK_LENGTH(list) (list)->length 68 | #define dlink_add_tail_alloc(data, list) dlink_add_tail(data, dlink_create(), list) 69 | #define dlink_add_alloc(data, list) dlink_add(data, dlink_create(), list) 70 | #define dlink_destroy(node, list) do { dlink_delete(node, list); dlink_free(node); } while(0) 71 | #endif /* !defined(NN2_DLINK) */ 72 | -------------------------------------------------------------------------------- /fuse/fuse_mt.c: -------------------------------------------------------------------------------- 1 | /* 2 | FUSE: Filesystem in Userspace 3 | Copyright (C) 2001-2007 Miklos Szeredi 4 | 5 | This program can be distributed under the terms of the GNU LGPLv2. 6 | See the file COPYING.LIB. 7 | */ 8 | 9 | #include "fuse_i.h" 10 | #include "fuse_misc.h" 11 | #include "fuse_lowlevel.h" 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | struct procdata { 20 | struct fuse *f; 21 | struct fuse_chan *prevch; 22 | struct fuse_session *prevse; 23 | fuse_processor_t proc; 24 | void *data; 25 | }; 26 | 27 | static void mt_session_proc(void *data, const char *buf, size_t len, 28 | struct fuse_chan *ch) 29 | { 30 | struct procdata *pd = (struct procdata *) data; 31 | struct fuse_cmd *cmd = *(struct fuse_cmd **) buf; 32 | 33 | (void) len; 34 | (void) ch; 35 | pd->proc(pd->f, cmd, pd->data); 36 | } 37 | 38 | static void mt_session_exit(void *data, int val) 39 | { 40 | struct procdata *pd = (struct procdata *) data; 41 | if (val) 42 | fuse_session_exit(pd->prevse); 43 | else 44 | fuse_session_reset(pd->prevse); 45 | } 46 | 47 | static int mt_session_exited(void *data) 48 | { 49 | struct procdata *pd = (struct procdata *) data; 50 | return fuse_session_exited(pd->prevse); 51 | } 52 | 53 | static int mt_chan_receive(struct fuse_chan **chp, char *buf, size_t size) 54 | { 55 | struct fuse_cmd *cmd; 56 | struct procdata *pd = (struct procdata *) fuse_chan_data(*chp); 57 | 58 | assert(size >= sizeof(cmd)); 59 | 60 | cmd = fuse_read_cmd(pd->f); 61 | if (cmd == NULL) 62 | return 0; 63 | 64 | *(struct fuse_cmd **) buf = cmd; 65 | 66 | return sizeof(cmd); 67 | } 68 | 69 | int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data) 70 | { 71 | int res; 72 | struct procdata pd; 73 | struct fuse_session *prevse = fuse_get_session(f); 74 | struct fuse_session *se; 75 | struct fuse_chan *prevch = fuse_session_next_chan(prevse, NULL); 76 | struct fuse_chan *ch; 77 | struct fuse_session_ops sop = { 78 | .exit = mt_session_exit, 79 | .exited = mt_session_exited, 80 | .process = mt_session_proc, 81 | }; 82 | struct fuse_chan_ops cop = { 83 | .receive = mt_chan_receive, 84 | }; 85 | 86 | pd.f = f; 87 | pd.prevch = prevch; 88 | pd.prevse = prevse; 89 | pd.proc = proc; 90 | pd.data = data; 91 | 92 | se = fuse_session_new(&sop, &pd); 93 | if (se == NULL) 94 | return -1; 95 | 96 | ch = fuse_chan_new(&cop, fuse_chan_fd(prevch), 97 | sizeof(struct fuse_cmd *), &pd); 98 | if (ch == NULL) { 99 | fuse_session_destroy(se); 100 | return -1; 101 | } 102 | fuse_session_add_chan(se, ch); 103 | res = fuse_session_loop_mt(se); 104 | fuse_session_destroy(se); 105 | return res; 106 | } 107 | 108 | int fuse_loop_mt(struct fuse *f) 109 | { 110 | if (f == NULL) 111 | return -1; 112 | 113 | return fuse_session_loop_mt(fuse_get_session(f)); 114 | } 115 | 116 | FUSE_SYMVER(".symver fuse_loop_mt_proc,__fuse_loop_mt@"); 117 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #if defined(USE_FUSE) 7 | #define FUSE_USE_VERSION 26 8 | #include "fuse/fuse.h" 9 | #include "fuse/fuse_opt.h" 10 | #include "fuse/fuse_lowlevel.h" 11 | #endif 12 | 13 | #include "conf.h" 14 | #include "db.h" 15 | #include "evt.h" 16 | #include "inode.h" 17 | #include "logger.h" 18 | #include "pkg.h" 19 | #include "signal_handler.h" 20 | #include "thread_pool.h" 21 | #include "vfs.h" 22 | #define VERSION "0.0.1" 23 | 24 | struct conf conf; 25 | 26 | void goodbye(void) { 27 | Log(LOG_INFO, "shutting down..."); 28 | dconf_fini(); 29 | vfs_watch_fini(); 30 | #if defined(USE_FUSE) 31 | vfs_fuse_fini(); 32 | umount(conf.mountpoint); 33 | #endif 34 | inode_fini(); 35 | dlink_fini(); 36 | log_close(conf.log_fp); 37 | exit(EXIT_SUCCESS); 38 | } 39 | 40 | int main(int argc, char **argv) { 41 | int fd; 42 | #if defined(USE_FUSE) 43 | struct fuse_args margs = FUSE_ARGS_INIT(0, NULL); 44 | #endif 45 | conf.born = time(NULL); 46 | umask(0); 47 | 48 | atexit(goodbye); 49 | 50 | signal_init(); 51 | evt_init(); 52 | blockheap_init(); 53 | dconf_init("fs-pkg.cf"); 54 | dlink_init(); 55 | pkg_init(); 56 | inode_init(); 57 | 58 | if (dconf_get_bool("sys.daemonize", 0) == 1) { 59 | fprintf(stdout, "going bg, bye!\n"); 60 | /* 61 | * XXX: add daemon crud 62 | */ 63 | } 64 | 65 | /* 66 | * open log file, if its valid, otherwise assume debug mode and use stdout 67 | */ 68 | if ((conf.log_fp = log_open(dconf_get_str("path.log", NULL))) == NULL) 69 | conf.log_fp = stdout; 70 | 71 | Log(LOG_INFO, "%s %s starting up...", argv[0], VERSION); 72 | 73 | if (!conf.mountpoint) 74 | conf.mountpoint = dconf_get_str("path.mountpoint", "/test"); 75 | 76 | #if defined(USE_FUSE) 77 | /* 78 | * only way to make gcc happy...argh;) -bk 79 | */ 80 | vfs_fuse_args = margs; 81 | 82 | /* 83 | * The fuse_mount() options get modified, so we always rebuild it 84 | */ 85 | if ((fuse_opt_add_arg(&vfs_fuse_args, argv[0]) == -1 || 86 | fuse_opt_add_arg(&vfs_fuse_args, "-o") == -1 || 87 | fuse_opt_add_arg(&vfs_fuse_args, "nonempty,allow_other") == -1)) 88 | Log(LOG_ERROR, "Failed to set FUSE options.\n"); 89 | 90 | umount(conf.mountpoint); 91 | vfs_fuse_init(); 92 | #endif 93 | 94 | Log(LOG_DEBUG, "Opening database %s", dconf_get_str("path.db", ":memory")); 95 | db_sqlite_open(dconf_get_str("path.db", ":memory")); 96 | 97 | /* 98 | * set up the watch subsystem 99 | */ 100 | vfs_watch_init(); 101 | 102 | /* 103 | * walk the package dirs and import all existing packages 104 | */ 105 | vfs_dir_walk(); 106 | 107 | /* 108 | * the big event loop 109 | */ 110 | while (!conf.dying) { 111 | ev_loop(evt_loop, 0); 112 | } 113 | 114 | /* 115 | * shouldnt be reached... 116 | */ 117 | return EXIT_SUCCESS; 118 | } 119 | -------------------------------------------------------------------------------- /ev_config.h: -------------------------------------------------------------------------------- 1 | /* config.h. Generated from config.h.in by configure. */ 2 | /* config.h.in. Generated from configure.ac by autoheader. */ 3 | 4 | /* Define to 1 if you have the `clock_gettime' function. */ 5 | /* #undef HAVE_CLOCK_GETTIME */ 6 | 7 | /* "use syscall interface for clock_gettime" */ 8 | #define HAVE_CLOCK_SYSCALL 1 9 | 10 | /* Define to 1 if you have the header file. */ 11 | #define HAVE_DLFCN_H 1 12 | 13 | /* Define to 1 if you have the `epoll_ctl' function. */ 14 | #define HAVE_EPOLL_CTL 1 15 | 16 | /* Define to 1 if you have the `eventfd' function. */ 17 | #define HAVE_EVENTFD 1 18 | 19 | /* Define to 1 if you have the `inotify_init' function. */ 20 | #define HAVE_INOTIFY_INIT 1 21 | 22 | /* Define to 1 if you have the header file. */ 23 | #define HAVE_INTTYPES_H 1 24 | 25 | /* Define to 1 if you have the `kqueue' function. */ 26 | /* #undef HAVE_KQUEUE */ 27 | 28 | /* Define to 1 if you have the `m' library (-lm). */ 29 | #define HAVE_LIBM 1 30 | 31 | /* Define to 1 if you have the `rt' library (-lrt). */ 32 | /* #undef HAVE_LIBRT */ 33 | 34 | /* Define to 1 if you have the header file. */ 35 | #define HAVE_MEMORY_H 1 36 | 37 | /* Define to 1 if you have the `nanosleep' function. */ 38 | /* #undef HAVE_NANOSLEEP */ 39 | 40 | /* Define to 1 if you have the `poll' function. */ 41 | #define HAVE_POLL 1 42 | 43 | /* Define to 1 if you have the header file. */ 44 | #define HAVE_POLL_H 1 45 | 46 | /* Define to 1 if you have the `port_create' function. */ 47 | /* #undef HAVE_PORT_CREATE */ 48 | 49 | /* Define to 1 if you have the header file. */ 50 | /* #undef HAVE_PORT_H */ 51 | 52 | /* Define to 1 if you have the `select' function. */ 53 | #define HAVE_SELECT 1 54 | 55 | /* Define to 1 if you have the header file. */ 56 | #define HAVE_STDINT_H 1 57 | 58 | /* Define to 1 if you have the header file. */ 59 | #define HAVE_STDLIB_H 1 60 | 61 | /* Define to 1 if you have the header file. */ 62 | #define HAVE_STRINGS_H 1 63 | 64 | /* Define to 1 if you have the header file. */ 65 | #define HAVE_STRING_H 1 66 | 67 | /* Define to 1 if you have the header file. */ 68 | #define HAVE_SYS_EPOLL_H 1 69 | 70 | /* Define to 1 if you have the header file. */ 71 | #define HAVE_SYS_EVENTFD_H 1 72 | 73 | /* Define to 1 if you have the header file. */ 74 | /* #undef HAVE_SYS_EVENT_H */ 75 | 76 | /* Define to 1 if you have the header file. */ 77 | #define HAVE_SYS_INOTIFY_H 1 78 | 79 | /* Define to 1 if you have the header file. */ 80 | #define HAVE_SYS_QUEUE_H 1 81 | 82 | /* Define to 1 if you have the header file. */ 83 | #define HAVE_SYS_SELECT_H 1 84 | 85 | /* Define to 1 if you have the header file. */ 86 | #define HAVE_SYS_STAT_H 1 87 | 88 | /* Define to 1 if you have the header file. */ 89 | #define HAVE_SYS_TYPES_H 1 90 | 91 | /* Define to 1 if you have the header file. */ 92 | #define HAVE_UNISTD_H 1 93 | 94 | /* Define to 1 if you have the ANSI C header files. */ 95 | #define STDC_HEADERS 1 96 | -------------------------------------------------------------------------------- /xar/asprintf.h: -------------------------------------------------------------------------------- 1 | //============================================================================== 2 | // 3 | // Copyright (C) 2005 Jason Evans . All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice(s), 9 | // this list of conditions and the following disclaimer unmodified other than 10 | // the allowable addition of one or more copyright notices. 11 | // 12 | // 2. Redistributions in binary form must reproduce the above copyright 13 | // notice(s), this list of conditions and the following disclaimer in the 14 | // documentation and/or other materials provided with the distribution. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) `AS IS' AND ANY EXPRESS 17 | // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 19 | // NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 22 | // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 25 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | // 27 | //============================================================================== 28 | // 29 | // Emulate vasprintf() and asprintf(). 30 | // 31 | //============================================================================== 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | static inline int 38 | vasprintf(char **rResult, const char *aFormat, va_list aAp) 39 | { 40 | int rVal; 41 | char *result; 42 | va_list ap; 43 | #define XarAsprintfStartLen 16 44 | 45 | result = (char *) malloc(XarAsprintfStartLen); 46 | if (result == NULL) 47 | { 48 | rVal = -1; 49 | goto RETURN; 50 | } 51 | 52 | va_copy(ap, aAp); 53 | rVal = vsnprintf(result, XarAsprintfStartLen, aFormat, ap); 54 | va_end(ap); 55 | 56 | if (rVal == -1) 57 | { 58 | goto RETURN; 59 | } 60 | else if (rVal >= XarAsprintfStartLen) 61 | { 62 | free(result); 63 | result = (char *) malloc(rVal + 1); 64 | if (result == NULL) 65 | { 66 | rVal = -1; 67 | goto RETURN; 68 | } 69 | 70 | va_copy(ap, aAp); 71 | rVal = vsnprintf(result, rVal + 1, aFormat, aAp); 72 | va_end(ap); 73 | } 74 | 75 | *rResult = result; 76 | RETURN: 77 | #undef XarAsprintfStartLen 78 | return rVal; 79 | } 80 | 81 | static int 82 | asprintf(char **rResult, const char *aFormat, ...) 83 | { 84 | int rVal; 85 | va_list ap; 86 | 87 | va_start(ap, aFormat); 88 | rVal = vasprintf(rResult, aFormat, ap); 89 | va_end(ap); 90 | 91 | return rVal; 92 | } 93 | -------------------------------------------------------------------------------- /support.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "support.h" 3 | 4 | /* 5 | * strlcat and strlcpy extracted from ircd-hybrid, originally taken 6 | * from the FreeBSD source. This copy fixes a bug. 7 | * 8 | * They had the following Copyright info: 9 | * 10 | * 11 | * Copyright (c) 1998 Todd C. Miller 12 | * All rights reserved. 13 | * 14 | * Redistribution and use in source and binary forms, with or without 15 | * modification, are permitted provided that the following conditions 16 | * are met: 17 | * 1. Redistributions of source code must retain the above copyright 18 | * notice, this list of conditions and the following disclaimer. 19 | * 2. Redistributions in binary form must reproduce the above copyright 20 | * notice, this list of conditions and the following disclaimer in the 21 | * documentation and/or other materials provided with the distribution. 22 | * 3. The name of the author may not be used to endorse or promote products 23 | * derived from this software without specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 26 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 27 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 28 | * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 31 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 32 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 33 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 34 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef HAVE_STRLCAT 38 | size_t strlcat(char *dst, const char *src, size_t siz) { 39 | char *d = dst; 40 | 41 | const char *s = src; 42 | 43 | size_t n = siz, dlen; 44 | 45 | while (n-- != 0 && *d != '\0') 46 | d++; 47 | dlen = d - dst; 48 | n = siz - dlen; 49 | 50 | if (n == 0) 51 | return (dlen + strlen(s)); 52 | while (*s != '\0') { 53 | if (n != 1) { 54 | *d++ = *s; 55 | n--; 56 | } 57 | s++; 58 | } 59 | *d = '\0'; 60 | return (dlen + (s - src)); /* count does not include NULL */ 61 | } 62 | #endif 63 | 64 | #ifndef HAVE_STRLCPY 65 | size_t strlcpy(char *dst, const char *src, size_t siz) { 66 | char *d = dst; 67 | 68 | const char *s = src; 69 | 70 | size_t n = siz; 71 | 72 | /* 73 | * Copy as many bytes as will fit 74 | */ 75 | if (n != 0 && --n != 0) { 76 | do { 77 | if ((*d++ = *s++) == 0) 78 | break; 79 | } 80 | while (--n != 0); 81 | } 82 | /* 83 | * Not enough room in dst, add NULL and traverse rest of src 84 | */ 85 | if (n == 0) { 86 | if (siz != 0) 87 | *d = '\0'; /* NULL-terminate dst */ 88 | while (*s++) ; 89 | } 90 | 91 | return (s - src - 1); /* count does not include NULL */ 92 | } 93 | #endif 94 | -------------------------------------------------------------------------------- /xar/err.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2007 Rob Braun 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of Rob Braun nor the names of his contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | /* 30 | * 03-Apr-2005 31 | * DRI: Rob Braun 32 | */ 33 | 34 | #include 35 | #include 36 | #include 37 | #include "xar.h" 38 | #include "archive.h" 39 | 40 | #define ECTX(x) ((struct errctx *)(x)) 41 | 42 | void xar_register_errhandler(xar_t x, err_handler callback, void *usrctx) { 43 | ECTX(&XAR(x)->errctx)->x = x; 44 | ECTX(&XAR(x)->errctx)->usrctx = usrctx; 45 | XAR(x)->ercallback = callback; 46 | return; 47 | } 48 | 49 | xar_t xar_err_get_archive(xar_errctx_t ctx) { 50 | return ECTX(ctx)->x; 51 | } 52 | 53 | xar_file_t xar_err_get_file(xar_errctx_t ctx) { 54 | return ECTX(ctx)->file; 55 | } 56 | 57 | void xar_err_set_file(xar_t x, xar_file_t f) { 58 | XAR(x)->errctx.file = f; 59 | return; 60 | } 61 | 62 | const char *xar_err_get_string(xar_errctx_t ctx) { 63 | return ECTX(ctx)->str; 64 | } 65 | 66 | void xar_err_set_string(xar_t x, const char *str) { 67 | XAR(x)->errctx.str = str; 68 | return; 69 | } 70 | 71 | int xar_err_get_errno(xar_errctx_t ctx) { 72 | return ECTX(ctx)->saved_errno; 73 | } 74 | 75 | void xar_err_set_errno(xar_t x, int e) { 76 | XAR(x)->errctx.saved_errno = e; 77 | return; 78 | } 79 | 80 | void xar_err_new(xar_t x) { 81 | memset(&XAR(x)->errctx, 0, sizeof(struct errctx)); 82 | XAR(x)->errctx.saved_errno = errno; 83 | return; 84 | } 85 | 86 | int32_t xar_err_callback(xar_t x, int32_t sev, int32_t err) { 87 | if( XAR(x)->ercallback ) 88 | return XAR(x)->ercallback(sev, err, &XAR(x)->errctx, ECTX(&XAR(x)->errctx)->usrctx); 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /libfspkg.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | struct file_op { 13 | /* 14 | * file ops 15 | */ 16 | int (*open) (const char *pathname, int flags, ...); 17 | int (*close) (int fd); 18 | ssize_t(*readlink) (const char *path, char *buf, size_t bufsiz); 19 | ssize_t(*read) (int fd, void *buf, size_t count); 20 | 21 | /* 22 | * file ops: spillover 23 | */ 24 | 25 | /* 26 | * access ops 27 | */ 28 | int (*access) (const char *pathname, int mode); 29 | int (*statfs) (const char *path, struct statfs * buf); 30 | 31 | /* 32 | * access ops: spillover 33 | */ 34 | 35 | /* 36 | * directory ops 37 | */ 38 | DIR *(*opendir) (const char *name); 39 | struct dirent *(*readdir) (DIR * dirp); 40 | int (*closedir) (DIR * dirp); 41 | 42 | /* 43 | * directory ops: spillover 44 | */ 45 | }; 46 | 47 | struct file_op real_ops; 48 | struct file_op pkg_ops; 49 | 50 | #define FAIL { \ 51 | fprintf(stderr, "%s:%d:%s failed loading real symbol", __FILE__, __LINE__, __FUNCTION__); \ 52 | abort(); \ 53 | } 54 | static void _init_lib(void) { 55 | if (!(real_ops.open = dlsym(RTLD_DEFAULT, "open"))) 56 | FAIL; 57 | if (!(real_ops.close = dlsym(RTLD_DEFAULT, "close"))) 58 | FAIL; 59 | if (!(real_ops.readlink = dlsym(RTLD_DEFAULT, "readlink"))) 60 | FAIL; 61 | if (!(real_ops.read = dlsym(RTLD_DEFAULT, "read"))) 62 | FAIL; 63 | if (!(real_ops.access = dlsym(RTLD_DEFAULT, "access"))) 64 | FAIL; 65 | if (!(real_ops.statfs = dlsym(RTLD_DEFAULT, "statfs"))) 66 | FAIL; 67 | if (!(real_ops.opendir = dlsym(RTLD_DEFAULT, "opendir"))) 68 | FAIL; 69 | if (!(real_ops.readdir = dlsym(RTLD_DEFAULT, "readdir"))) 70 | FAIL; 71 | if (!(real_ops.closedir = dlsym(RTLD_DEFAULT, "closedir"))) 72 | FAIL; 73 | } 74 | 75 | static void _init(void) { 76 | fprintf(stderr, "_init called\n"); 77 | _init_lib(); 78 | } 79 | 80 | int open(const char *pathname, int flags, ...) { 81 | return real_ops.open(pathname, flags); 82 | } 83 | 84 | int close(int fd) { 85 | return real_ops.close(fd); 86 | } 87 | 88 | ssize_t readlink(const char *path, char *buf, size_t bufsiz) { 89 | return real_ops.readlink(path, buf, bufsiz); 90 | } 91 | 92 | ssize_t read(int fd, void *buf, size_t count) { 93 | return real_ops.read(fd, buf, count); 94 | } 95 | 96 | int access(const char *path, int mode) { 97 | return real_ops.access(path, mode); 98 | } 99 | 100 | int statfs(const char *path, struct statfs *buf) { 101 | return real_ops.statfs(path, buf); 102 | } 103 | 104 | DIR *opendir(const char *name) { 105 | return real_ops.opendir(name); 106 | } 107 | 108 | struct dirent *readdir(DIR * dirp) { 109 | return real_ops.readdir(dirp); 110 | } 111 | 112 | int closedir(DIR * dirp) { 113 | return real_ops.closedir(dirp); 114 | } 115 | -------------------------------------------------------------------------------- /vfs_spill.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FUSE VFS Spillover file support 3 | * 4 | * This file should NEVER be included directly outside 5 | * of vfs_fuse.c, in fact we throw an error if this 6 | * is done 7 | */ 8 | #if !defined(VFS_FUSE_C) 9 | #error never include vfs_fuse_spill.h outside vfs_fuse.c 10 | #error this file is for internal use only 11 | #endif 12 | #include "timestr.h" 13 | /* Write-type operations which should return EROFS */ 14 | static void vfs_fuse_setattr(fuse_req_t req, fuse_ino_t ino, 15 | struct stat *attr, int to_set, struct fuse_file_info *fi) { 16 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 17 | fuse_reply_err(req, EROFS); 18 | } 19 | 20 | static void vfs_fuse_mknod(fuse_req_t req, fuse_ino_t ino, 21 | const char *name, mode_t mode, dev_t rdev) { 22 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 23 | fuse_reply_err(req, EROFS); 24 | } 25 | 26 | static void vfs_fuse_mkdir(fuse_req_t req, fuse_ino_t ino, const char *name, mode_t mode) { 27 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 28 | fuse_reply_err(req, EROFS); 29 | } 30 | 31 | static void vfs_fuse_symlink(fuse_req_t req, const char *link, fuse_ino_t parent, const char *name) { 32 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 33 | fuse_reply_err(req, EROFS); 34 | } 35 | 36 | static void vfs_fuse_unlink(fuse_req_t req, fuse_ino_t ino, const char *name) { 37 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 38 | fuse_reply_err(req, EROFS); 39 | } 40 | 41 | static void vfs_fuse_rmdir(fuse_req_t req, fuse_ino_t ino, const char *namee) { 42 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 43 | fuse_reply_err(req, EROFS); 44 | } 45 | 46 | static void vfs_fuse_rename(fuse_req_t req, fuse_ino_t parent, const char *name, 47 | fuse_ino_t newparent, const char *newname) { 48 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 49 | fuse_reply_err(req, EROFS); 50 | } 51 | 52 | static void vfs_fuse_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent, const char *newname) { 53 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 54 | fuse_reply_err(req, EROFS); 55 | } 56 | 57 | static void vfs_fuse_write(fuse_req_t req, fuse_ino_t ino, const char *buf, 58 | size_t size, off_t off, struct fuse_file_info *fi) { 59 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 60 | fuse_reply_err(req, EROFS); 61 | } 62 | 63 | static void vfs_fuse_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name, 64 | const char *value, size_t size, int flags) { 65 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 66 | fuse_reply_err(req, ENOTSUP); 67 | } 68 | 69 | static void vfs_fuse_removexattr(fuse_req_t req, fuse_ino_t ino, const char *name) { 70 | /* 71 | * XXX: which is proper: ENOSUP, EACCES, ENOATTR? 72 | */ 73 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 74 | fuse_reply_err(req, ENOTSUP); 75 | } 76 | 77 | static void vfs_fuse_create(fuse_req_t req, fuse_ino_t ino, const char *name, 78 | mode_t mode, struct fuse_file_info *fi) { 79 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 80 | fuse_reply_err(req, EROFS); 81 | } 82 | -------------------------------------------------------------------------------- /xar/script.c: -------------------------------------------------------------------------------- 1 | /* 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 3. Neither the name of Apple nor the names of any contributors 13 | * may be used to endorse or promote products derived from this software 14 | * without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | /* 29 | * Portions Copyright 2006, Apple Computer, Inc. 30 | * Christopher Ryan 31 | */ 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include "config.h" 40 | #ifndef HAVE_ASPRINTF 41 | #include "asprintf.h" 42 | #endif 43 | #include "xar.h" 44 | #include "filetree.h" 45 | #include "arcmod.h" 46 | 47 | struct _script_context{ 48 | int initted; 49 | }; 50 | 51 | #define SCRIPT_CONTEXT(x) ((struct _script_context*)(*x)) 52 | 53 | int32_t xar_script_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context) { 54 | char *buf = *in; 55 | xar_prop_t tmpp; 56 | 57 | if(!SCRIPT_CONTEXT(context)){ 58 | *context = calloc(1,sizeof(struct _script_context)); 59 | } 60 | 61 | if( SCRIPT_CONTEXT(context)->initted ) 62 | return 0; 63 | 64 | if( !xar_check_prop(x, "contents") ) 65 | return 0; 66 | 67 | /* Sanity check *inlen, which really shouldn't be more than a 68 | * few kbytes... 69 | */ 70 | if( *inlen > INT_MAX ) 71 | return 0; 72 | 73 | /*We only run on the begining of the file, so once we init, we don't run again*/ 74 | SCRIPT_CONTEXT(context)->initted = 1; 75 | 76 | if( (*inlen > 2) && (buf[0] == '#') && (buf[1] == '!') ) { 77 | char *exe; 78 | int i; 79 | 80 | exe = malloc(*inlen); 81 | if( !exe ) 82 | return -1; 83 | memset(exe, 0, *inlen); 84 | 85 | for(i = 2; (i < *inlen) && (buf[i] != '\0') && (buf[i] != '\n') && (buf[i] != ' '); ++i) { 86 | exe[i-2] = buf[i]; 87 | } 88 | 89 | tmpp = xar_prop_pset(f, p, "contents", NULL); 90 | if( tmpp ) { 91 | xar_prop_pset(f, tmpp, "type", "script"); 92 | xar_prop_pset(f, tmpp, "interpreter", exe); 93 | } 94 | free(exe); 95 | } 96 | return 0; 97 | } 98 | 99 | int32_t xar_script_done(xar_t x, xar_file_t f, xar_prop_t p, void **context) { 100 | 101 | if(!SCRIPT_CONTEXT(context)){ 102 | return 0; 103 | } 104 | 105 | if( *context ){ 106 | free(*context); 107 | *context = NULL; 108 | } 109 | 110 | return 0; 111 | } 112 | -------------------------------------------------------------------------------- /xar/appledouble.h: -------------------------------------------------------------------------------- 1 | /* Information pulled from: 2 | * "AppleSingle/AppleDouble Formats for Foreign Files Developer's Note" 3 | * (c) Apple Computer 1990 4 | * File assembled by Rob Braun (bbraun@synack.net) 5 | */ 6 | 7 | #ifndef __APPLEDOUBLE__ 8 | #define __APPLEDOUBLE__ 9 | 10 | #include 11 | #include 12 | 13 | /* Structure of an AppleSingle file: 14 | * ---------------------- 15 | * | AppleSingleHeader | 16 | * |--------------------| 17 | * | ASH.entries # of | 18 | * | AppleSingleEntry | 19 | * | Descriptors | 20 | * | 1 | 21 | * | . | 22 | * | . | 23 | * | n | 24 | * |--------------------| 25 | * | Datablock 1 | 26 | * |--------------------| 27 | * | Datablock 2 | 28 | * |--------------------| 29 | * | Datablock n | 30 | * ---------------------- 31 | */ 32 | 33 | struct AppleSingleHeader { 34 | uint32_t magic; /* Magic Number (0x00051600 for AS) */ 35 | uint32_t version; /* Version #. 0x00020000 */ 36 | char filler[16]; /* All zeros */ 37 | uint16_t entries; /* Number of entries in the file */ 38 | }; 39 | 40 | #define XAR_ASH_SIZE 26 /* sizeof(struct AppleSingleHeader) will be wrong 41 | * due to padding. */ 42 | 43 | #define APPLESINGLE_MAGIC 0x00051600 44 | #define APPLEDOUBLE_MAGIC 0x00051607 45 | 46 | #define APPLESINGLE_VERSION 0x00020000 47 | #define APPLEDOUBLE_VERSION 0x00020000 48 | 49 | struct AppleSingleEntry { 50 | uint32_t entry_id; /* What the entry is. See defines below */ 51 | uint32_t offset; /* offset of data, offset beginning of file */ 52 | uint32_t length; /* length of data. can be 0 */ 53 | }; 54 | 55 | /* Valid entry_id values */ 56 | /* Entries 1, 3, and 8 are typically created for all files. 57 | * Macintosh Icon entries are rare, since those are typically in the resource 58 | * fork. 59 | */ 60 | #define AS_ID_DATA 1 /* Data fork */ 61 | #define AS_ID_RESOURCE 2 /* Resource fork */ 62 | #define AS_ID_NAME 3 /* Name of the file */ 63 | #define AS_ID_COMMENT 4 /* Standard Macintosh comment */ 64 | #define AS_ID_BWICON 5 /* Standard Macintosh B&W icon */ 65 | #define AS_ID_COLORICON 6 /* Standard Macintosh Color icon */ 66 | /* There is no 7 */ 67 | #define AS_ID_DATES 8 /* File creation date, modification date, etc. */ 68 | #define AS_ID_FINDER 9 /* Finder Information */ 69 | #define AS_ID_MAC 10 /* Macintosh File information, attributes, etc. */ 70 | #define AS_ID_PRODOS 11 /* ProDOS file information */ 71 | #define AS_ID_MSDOS 12 /* MS-DOS file information */ 72 | #define AS_ID_SHORTNAME 13 /* AFP short name */ 73 | #define AS_ID_AFPINFO 14 /* AFP file information */ 74 | #define AS_ID_AFPDIR 15 /* AFP directory id */ 75 | /* 1-0x7FFFFFFF are reserved by Apple */ 76 | 77 | /* File Dates are stored as the # of seconds before or after 78 | * 12am Jan 1, 2000 GMT. The default value is 0x80000000. 79 | */ 80 | struct MacTimes { 81 | uint32_t creation; 82 | uint32_t modification; 83 | uint32_t backup; 84 | uint32_t access; 85 | }; 86 | 87 | /* Finder Information is two 16 byte quantities. 88 | * Newly created files have all 0's in both entries. 89 | */ 90 | 91 | /* Macintosh File Info entry (10) a 32 bit bitmask. */ 92 | 93 | /* Entries can be placed in any order, although Apple recommends: 94 | * Place the data block (1) last. 95 | * Finder Info, File Dates Info, and Macintosh File Info first. 96 | * Allocate resource for entries in 4K blocks. 97 | */ 98 | 99 | /* AppleDouble files are simply AppleSingle files without the data fork. 100 | * The magic number is different as a read optimization. 101 | */ 102 | 103 | #endif /* __APPLEDOUBLE__ */ 104 | -------------------------------------------------------------------------------- /xar/io.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2007 Rob Braun 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of Rob Braun nor the names of his contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | /* 30 | * 03-Apr-2005 31 | * DRI: Rob Braun 32 | */ 33 | /* 34 | * Portions Copyright 2006, Apple Computer, Inc. 35 | * Christopher Ryan 36 | */ 37 | 38 | #ifndef _XAR_IO_H_ 39 | #define _XAR_IO_H_ 40 | 41 | typedef int (*read_callback)(xar_t, xar_file_t, void *, size_t, void *context); 42 | typedef int (*write_callback)(xar_t, xar_file_t, void *, size_t, void *context); 43 | 44 | typedef int (*fromheap_in)(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); 45 | typedef int (*fromheap_out)(xar_t x, xar_file_t f, xar_prop_t p, void *in, size_t inlen, void **context); 46 | typedef int (*fromheap_done)(xar_t x, xar_file_t f, xar_prop_t p, void **context); 47 | 48 | typedef int (*toheap_in)(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); 49 | typedef int (*toheap_out)(xar_t x, xar_file_t f, xar_prop_t p, void *in, size_t inlen, void **context); 50 | typedef int (*toheap_done)(xar_t x, xar_file_t f, xar_prop_t p, void **context); 51 | 52 | struct datamod { 53 | fromheap_in fh_in; 54 | fromheap_out fh_out; 55 | fromheap_done fh_done; 56 | toheap_in th_in; 57 | toheap_out th_out; 58 | toheap_done th_done; 59 | }; 60 | 61 | typedef struct xar_stream_state { 62 | char *pending_buf; 63 | size_t pending_buf_size; 64 | 65 | void **modulecontext; 66 | int modulecount; 67 | size_t bsize; 68 | int64_t fsize; 69 | xar_t x; 70 | xar_file_t f; 71 | xar_prop_t p; 72 | } xar_stream_state_t; 73 | 74 | int32_t xar_attrcopy_to_heap(xar_t x, xar_file_t f, xar_prop_t p, read_callback rcb, void *context); 75 | int32_t xar_attrcopy_from_heap(xar_t x, xar_file_t f, xar_prop_t p, write_callback wcb, void *context); 76 | int32_t xar_attrcopy_from_heap_to_heap(xar_t xsource, xar_file_t fsource, xar_prop_t p, xar_t xdest, xar_file_t fdest); 77 | int32_t xar_attrcopy_from_heap_to_stream_init(xar_t x, xar_file_t f, xar_prop_t p, xar_stream *stream); 78 | int32_t xar_attrcopy_from_heap_to_stream(xar_stream *stream); 79 | int32_t xar_attrcopy_from_heap_to_stream_end(xar_stream *stream); 80 | 81 | int32_t xar_heap_to_archive(xar_t x); 82 | 83 | #endif /* _XAR_IO_H_ */ 84 | -------------------------------------------------------------------------------- /vfs_fuse.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define FUSE_USE_VERSION 26 4 | #include 5 | #include 6 | #include "conf.h" 7 | #include "db.h" 8 | #include "evt.h" 9 | #include "logger.h" 10 | #include "memory.h" 11 | #include "pkg.h" 12 | #include "vfs.h" 13 | #define VFS_FUSE_C /* required for vfs_fuse_spill.h */ 14 | #include "vfs_pkg.h" 15 | #include "vfs_spill.h" 16 | #undef VFS_FUSE_C 17 | 18 | static ev_io vfs_fuse_evt; 19 | static struct fuse_chan *vfs_fuse_chan = NULL; 20 | static struct fuse_session *vfs_fuse_sess = NULL; 21 | struct fuse_args vfs_fuse_args = { 0, NULL, 0 }; 22 | 23 | /* FUSE operations */ 24 | static struct fuse_lowlevel_ops vfs_fuse_ops = { 25 | /* File operations */ 26 | .lookup = vfs_fuse_lookup, 27 | .readlink = vfs_fuse_readlink, 28 | .open = vfs_fuse_open, 29 | .release = vfs_fuse_release, 30 | .read = vfs_fuse_read, 31 | /* Stat/permissions */ 32 | .getattr = vfs_fuse_getattr, 33 | .access = vfs_fuse_access, 34 | .statfs = vfs_fuse_statfs, 35 | .getxattr = vfs_fuse_getxattr, 36 | .listxattr = vfs_fuse_listxattr, 37 | /* Directory operations */ 38 | .opendir = vfs_fuse_opendir, 39 | .readdir = vfs_fuse_readdir, 40 | .releasedir = vfs_fuse_releasedir, 41 | /* Spillover operations, unsupported for now */ 42 | .create = vfs_fuse_create, 43 | .mknod = vfs_fuse_mknod, 44 | .mkdir = vfs_fuse_mkdir, 45 | .symlink = vfs_fuse_symlink, 46 | .unlink = vfs_fuse_unlink, 47 | .rmdir = vfs_fuse_rmdir, 48 | .rename = vfs_fuse_rename, 49 | .link = vfs_fuse_link, 50 | .write = vfs_fuse_write, 51 | .setxattr = vfs_fuse_setxattr, 52 | .removexattr = vfs_fuse_removexattr 53 | }; 54 | 55 | /* This is a hacked up version of fuse/fuse_loop.c, hope it works -bk */ 56 | static void vfs_fuse_read_cb(struct ev_loop *loop, ev_io * w, int revents) { 57 | int res = 0; 58 | struct fuse_chan *ch = fuse_session_next_chan(vfs_fuse_sess, NULL); 59 | struct fuse_chan *tmpch = ch; 60 | size_t bufsize = fuse_chan_bufsize(ch); 61 | char *buf; 62 | 63 | if (!(buf = mem_alloc(bufsize))) { 64 | Log(LOG_FATAL, "fuse: failed to allocate read buffer\n"); 65 | conf.dying = 1; 66 | return; 67 | } 68 | 69 | res = fuse_chan_recv(&tmpch, buf, bufsize); 70 | 71 | if (!(res == -EINTR || res <= 0)) 72 | fuse_session_process(vfs_fuse_sess, buf, res, tmpch); 73 | 74 | mem_free(buf); 75 | fuse_session_reset(vfs_fuse_sess); 76 | } 77 | 78 | void vfs_fuse_fini(void) { 79 | if (vfs_fuse_sess != NULL) 80 | fuse_session_destroy(vfs_fuse_sess); 81 | 82 | if (vfs_fuse_chan != NULL) { 83 | fuse_session_remove_chan(vfs_fuse_chan); 84 | fuse_unmount(dconf_get_str("path.mountpoint", "/"), vfs_fuse_chan); 85 | } 86 | 87 | if (vfs_fuse_args.allocated) 88 | fuse_opt_free_args(&vfs_fuse_args); 89 | } 90 | 91 | void vfs_fuse_init(void) { 92 | if ((vfs_fuse_chan = fuse_mount(conf.mountpoint, &vfs_fuse_args)) == NULL) { 93 | Log(LOG_FATAL, "FUSE: mount error"); 94 | conf.dying = 1; 95 | raise(SIGTERM); 96 | } 97 | 98 | if ((vfs_fuse_sess = fuse_lowlevel_new(&vfs_fuse_args, &vfs_fuse_ops, 99 | sizeof(vfs_fuse_ops), NULL)) != NULL) { 100 | fuse_session_add_chan(vfs_fuse_sess, vfs_fuse_chan); 101 | } else { 102 | Log(LOG_FATAL, "FUSE: unable to create session"); 103 | conf.dying = 1; 104 | raise(SIGTERM); 105 | } 106 | 107 | /* 108 | * Register an interest in events on the fuse fd 109 | */ 110 | ev_io_init(&vfs_fuse_evt, vfs_fuse_read_cb, fuse_chan_fd(vfs_fuse_chan), EV_READ); 111 | ev_io_start(evt_loop, &vfs_fuse_evt); 112 | 113 | /* 114 | * Set up our various blockheaps 115 | */ 116 | vfs_handle_heap = 117 | blockheap_create(sizeof(vfs_handle_t), 118 | dconf_get_int("tuning.heap.vfs_handle", 128), "vfs_handle"); 119 | } 120 | -------------------------------------------------------------------------------- /fuse/fuse_versionscript: -------------------------------------------------------------------------------- 1 | FUSE_2.2 { 2 | global: 3 | fuse_destroy; 4 | fuse_exit; 5 | fuse_exited; 6 | fuse_get_context; 7 | fuse_invalidate; 8 | fuse_is_lib_option; 9 | fuse_loop; 10 | fuse_loop_mt; 11 | fuse_loop_mt_proc; 12 | fuse_main; 13 | fuse_main_compat1; 14 | fuse_main_compat2; 15 | fuse_mount_compat1; 16 | fuse_new_compat1; 17 | fuse_new_compat2; 18 | fuse_process_cmd; 19 | fuse_read_cmd; 20 | fuse_set_getcontext_func; 21 | fuse_setup_compat2; 22 | }; 23 | 24 | FUSE_2.4 { 25 | global: 26 | fuse_add_dirent; 27 | fuse_chan_bufsize; 28 | fuse_chan_data; 29 | fuse_chan_destroy; 30 | fuse_chan_fd; 31 | fuse_chan_new; 32 | fuse_chan_receive; 33 | fuse_chan_send; 34 | fuse_chan_session; 35 | fuse_dirent_size; 36 | fuse_kern_chan_new; 37 | fuse_lowlevel_is_lib_option; 38 | fuse_reply_attr; 39 | fuse_reply_buf; 40 | fuse_reply_entry; 41 | fuse_reply_err; 42 | fuse_reply_none; 43 | fuse_reply_readlink; 44 | fuse_reply_write; 45 | fuse_reply_xattr; 46 | fuse_req_ctx; 47 | fuse_req_userdata; 48 | fuse_session_add_chan; 49 | fuse_session_destroy; 50 | fuse_session_exit; 51 | fuse_session_exited; 52 | fuse_session_loop; 53 | fuse_session_loop_mt; 54 | fuse_session_new; 55 | fuse_session_next_chan; 56 | fuse_session_process; 57 | fuse_session_reset; 58 | } FUSE_2.2; 59 | 60 | FUSE_2.5 { 61 | global: 62 | fuse_lowlevel_new_compat; 63 | fuse_main_real_compat22; 64 | fuse_mount_compat22; 65 | fuse_new_compat22; 66 | fuse_opt_parse; 67 | fuse_opt_add_opt; 68 | fuse_opt_add_arg; 69 | fuse_opt_free_args; 70 | fuse_opt_match; 71 | fuse_parse_cmdline; 72 | fuse_remove_signal_handlers; 73 | fuse_reply_create; 74 | fuse_reply_open; 75 | fuse_reply_open_compat; 76 | fuse_reply_statfs; 77 | fuse_reply_statfs_compat; 78 | fuse_setup_compat22; 79 | fuse_set_signal_handlers; 80 | } FUSE_2.4; 81 | 82 | FUSE_2.6 { 83 | global: 84 | fuse_add_direntry; 85 | fuse_chan_new; 86 | fuse_chan_new_compat24; 87 | fuse_chan_recv; 88 | fuse_daemonize; 89 | fuse_get_session; 90 | fuse_interrupted; 91 | fuse_lowlevel_new; 92 | fuse_lowlevel_new_compat25; 93 | fuse_main_real; 94 | fuse_main_real_compat25; 95 | fuse_mount; 96 | fuse_mount_compat25; 97 | fuse_new; 98 | fuse_new_compat25; 99 | fuse_opt_insert_arg; 100 | fuse_reply_lock; 101 | fuse_req_interrupt_func; 102 | fuse_req_interrupted; 103 | fuse_session_remove_chan; 104 | fuse_setup; 105 | fuse_setup_compat25; 106 | fuse_teardown; 107 | fuse_teardown_compat22; 108 | fuse_unmount; 109 | fuse_unmount_compat22; 110 | } FUSE_2.5; 111 | 112 | FUSE_2.7 { 113 | global: 114 | fuse_fs_access; 115 | fuse_fs_bmap; 116 | fuse_fs_chmod; 117 | fuse_fs_chown; 118 | fuse_fs_create; 119 | fuse_fs_destroy; 120 | fuse_fs_fgetattr; 121 | fuse_fs_flush; 122 | fuse_fs_fsync; 123 | fuse_fs_fsyncdir; 124 | fuse_fs_ftruncate; 125 | fuse_fs_getattr; 126 | fuse_fs_getxattr; 127 | fuse_fs_init; 128 | fuse_fs_link; 129 | fuse_fs_listxattr; 130 | fuse_fs_lock; 131 | fuse_fs_mkdir; 132 | fuse_fs_mknod; 133 | fuse_fs_new; 134 | fuse_fs_open; 135 | fuse_fs_opendir; 136 | fuse_fs_read; 137 | fuse_fs_readdir; 138 | fuse_fs_readlink; 139 | fuse_fs_release; 140 | fuse_fs_releasedir; 141 | fuse_fs_removexattr; 142 | fuse_fs_rename; 143 | fuse_fs_rmdir; 144 | fuse_fs_setxattr; 145 | fuse_fs_statfs; 146 | fuse_fs_symlink; 147 | fuse_fs_truncate; 148 | fuse_fs_unlink; 149 | fuse_fs_utimens; 150 | fuse_fs_write; 151 | fuse_register_module; 152 | fuse_reply_iov; 153 | fuse_version; 154 | } FUSE_2.6; 155 | 156 | FUSE_2.8 { 157 | global: 158 | fuse_fs_ioctl; 159 | fuse_fs_poll; 160 | fuse_lowlevel_notify_poll; 161 | fuse_notify_poll; 162 | fuse_opt_add_opt_escaped; 163 | fuse_pollhandle_destroy; 164 | fuse_reply_bmap; 165 | fuse_reply_ioctl; 166 | fuse_reply_ioctl_retry; 167 | fuse_reply_poll; 168 | 169 | local: 170 | *; 171 | } FUSE_2.7; 172 | -------------------------------------------------------------------------------- /conf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Dictionary based configuration lookup 3 | * Used for single-entry configurations 4 | * See lconf.[ch] for list-based configuration 5 | * suitable for ACLs and similar options. 6 | * 7 | * Copyright (C) 2008 N2 Networks LLC 8 | * 9 | * This code wouldn't be possible without N. Devillard's dictionary.[ch] 10 | * from the iniparser package. Thanks!! 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "conf.h" 18 | #include "dictionary.h" 19 | #include "logger.h" 20 | #include "str.h" 21 | 22 | void dconf_init(const char *file) { 23 | FILE *fp; 24 | char *p; 25 | char buf[512]; 26 | int in_comment = 0; 27 | int line = 0; 28 | char *key, *val; 29 | NN2_DCONF_DICT = dictionary_new(0); 30 | 31 | if (!(fp = fopen(file, "r"))) { 32 | Log(LOG_FATAL, "unable to open config file %s", file); 33 | raise(SIGTERM); 34 | } 35 | 36 | while (!feof(fp)) { 37 | line++; 38 | memset(buf, 0, 512); 39 | fgets(buf, sizeof(buf), fp); 40 | 41 | /* 42 | * did we get a line? 43 | */ 44 | if (buf == NULL) 45 | continue; 46 | 47 | p = buf; 48 | 49 | str_strip(p); 50 | p = str_whitespace_skip(p); 51 | 52 | /* 53 | * did we eat the whole line? 54 | */ 55 | if (strlen(p) == 0) 56 | continue; 57 | 58 | /* 59 | * fairly flexible comment handling 60 | */ 61 | if (p[0] == '*' && p[1] == '/') { 62 | in_comment = 0; /* end of block comment */ 63 | continue; 64 | } else if (p[0] == ';' || p[0] == '#' || (p[0] == '/' && p[1] == '/')) { 65 | continue; /* line comment */ 66 | } else if (p[0] == '/' && p[1] == '*') 67 | in_comment = 1; /* start of block comment */ 68 | 69 | if (in_comment) 70 | continue; /* ignored line, in block comment */ 71 | 72 | key = p; 73 | 74 | if ((val = strchr(p, '=')) != NULL) { 75 | *val = '\0'; 76 | val++; 77 | } 78 | 79 | val = str_unquote(val); 80 | dconf_set(key, val); 81 | } 82 | } 83 | 84 | void dconf_fini(void) { 85 | dictionary_del(NN2_DCONF_DICT); 86 | NN2_DCONF_DICT = NULL; 87 | } 88 | 89 | int dconf_get_bool(const char *key, const int def) { 90 | char *tmp; 91 | int rv = 0; 92 | 93 | if ((tmp = dconf_get_str(key, NULL)) == NULL) 94 | return def; 95 | else if (strcasecmp(tmp, "true") == 0 || strcasecmp(tmp, "on") == 0 || 96 | strcasecmp(tmp, "yes") == 0 || (int)strtol(tmp, NULL, 0) == 1) 97 | rv = 1; 98 | else if (strcasecmp(tmp, "false") == 0 || strcasecmp(tmp, "off") == 0 || 99 | strcasecmp(tmp, "no") == 0 || (int)strtol(tmp, NULL, 0) == 0) 100 | rv = 0; 101 | 102 | return rv; 103 | } 104 | 105 | double dconf_get_double(const char *key, const double def) { 106 | char *tmp; 107 | 108 | if ((tmp = dconf_get_str(key, NULL)) == NULL) 109 | return def; 110 | 111 | return atof(tmp); 112 | } 113 | 114 | int dconf_get_int(const char *key, const int def) { 115 | char *tmp; 116 | 117 | if ((tmp = dconf_get_str(key, NULL)) == NULL) 118 | return def; 119 | 120 | return (int)strtol(tmp, NULL, 0); 121 | } 122 | 123 | char *dconf_get_str(const char *key, const char *def) { 124 | if (NN2_DCONF_DICT == NULL || key == NULL) 125 | return NULL; 126 | 127 | return dictionary_get(NN2_DCONF_DICT, key, def); 128 | } 129 | 130 | time_t dconf_get_time(const char *key, const time_t def) { 131 | return (nn2_timestr_to_time(dconf_get_str(key, NULL), def)); 132 | } 133 | 134 | int dconf_set(const char *key, const char *val) { 135 | return dictionary_set(NN2_DCONF_DICT, key, val); 136 | } 137 | 138 | void dconf_unset(const char *key) { 139 | dictionary_unset(NN2_DCONF_DICT, key); 140 | } 141 | -------------------------------------------------------------------------------- /xar/archive.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2007 Rob Braun 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of Rob Braun nor the names of his contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | /* 30 | * 03-Apr-2005 31 | * DRI: Rob Braun 32 | */ 33 | /* 34 | * Portions Copyright 2006, Apple Computer, Inc. 35 | * Christopher Ryan 36 | */ 37 | 38 | 39 | #ifndef _XAR_ARCHIVE_H_ 40 | #define _XAR_ARCHIVE_H_ 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include "xar.h" 47 | #include "filetree.h" 48 | 49 | struct errctx { 50 | const char *str; 51 | int saved_errno; 52 | xar_file_t file; 53 | void *usrctx; 54 | xar_t x; 55 | }; 56 | 57 | struct __xar_t { 58 | xar_prop_t props; 59 | xar_attr_t attrs; /* archive options, such as rsize */ 60 | const char *prefix; 61 | const char *ns; 62 | const char *filler1; 63 | const char *filler2; 64 | xar_file_t files; /* file forest */ 65 | const char *filename; /* name of the archive we are operating on */ 66 | char *dirname; /* directory of the archive, used in creation */ 67 | int fd; /* open file descriptor for the archive */ 68 | int heap_fd; /* fd for tmp heap archive, used in creation */ 69 | off_t heap_offset; /* current offset within the heap */ 70 | off_t heap_len; /* current length of the heap */ 71 | xar_header_t header; /* header of the xar archive */ 72 | void *readbuf; /* buffer for reading/writing compressed toc */ 73 | size_t readbuf_len; /* length of readbuf */ 74 | size_t offset; /* offset into readbuf for keeping track 75 | * between callbacks. */ 76 | size_t toc_count; /* current bytes read of the toc */ 77 | z_stream zs; /* gz state for compressing/decompressing toc */ 78 | char *path_prefix; /* used for distinguishing absolute paths */ 79 | err_handler ercallback; /* callback for errors/warnings */ 80 | struct errctx errctx; /* error callback context */ 81 | xar_subdoc_t subdocs; /* linked list of subdocs */ 82 | xar_signature_t signatures; /* linked list of signatures */ 83 | uint64_t last_fileid; /* unique fileid's in the archive */ 84 | xmlHashTablePtr ino_hash; /* Hash for looking up hardlinked files (add)*/ 85 | xmlHashTablePtr link_hash; /* Hash for looking up hardlinked files (extract)*/ 86 | xmlHashTablePtr csum_hash; /* Hash for looking up checksums of files */ 87 | EVP_MD_CTX toc_ctx; 88 | int docksum; 89 | int skipwarn; 90 | struct stat sbcache; 91 | }; 92 | 93 | #define XAR(x) ((struct __xar_t *)(x)) 94 | 95 | #endif /* _XAR_ARCHIVE_H_ */ 96 | -------------------------------------------------------------------------------- /xar/ea.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008 Rob Braun 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of Rob Braun nor the names of his contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | #include "config.h" 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #ifndef HAVE_ASPRINTF 37 | #include "asprintf.h" 38 | #endif 39 | #include "xar.h" 40 | #include "filetree.h" 41 | #include "archive.h" 42 | #include "b64.h" 43 | #include "ea.h" 44 | 45 | struct __xar_ea_t { 46 | const struct __xar_prop_t *prop; 47 | const struct __xar_ea_t *next; 48 | }; 49 | 50 | #define XAR_EA(x) ((struct __xar_ea_t *)(x)) 51 | 52 | xar_ea_t xar_ea_new(xar_file_t f, const char *name) 53 | { 54 | xar_ea_t ret; 55 | 56 | ret = calloc(sizeof(struct __xar_ea_t), 1); 57 | if( !ret ) 58 | return NULL; 59 | 60 | XAR_EA(ret)->prop = xar_prop_new(f, NULL); 61 | if( !XAR_EA(ret)->prop ) { 62 | free(ret); 63 | return NULL; 64 | } 65 | 66 | xar_prop_setkey(XAR_EA(ret)->prop, "ea"); 67 | xar_prop_setvalue(XAR_EA(ret)->prop, NULL); 68 | XAR_PROP(XAR_EA(ret)->prop)->attrs = xar_attr_new(); 69 | XAR_ATTR(XAR_PROP(XAR_EA(ret)->prop)->attrs)->key = strdup("id"); 70 | asprintf((char **)&XAR_ATTR(XAR_PROP(XAR_EA(ret)->prop)->attrs)->value, "%lld", XAR_FILE(f)->nexteaid++); 71 | 72 | xar_prop_pset(f, XAR_EA(ret)->prop, "name", name); 73 | 74 | return ret; 75 | } 76 | 77 | int32_t xar_ea_pset(xar_file_t f, xar_ea_t e, const char *key, const char *value){ 78 | if( xar_prop_pset(f, XAR_EA(e)->prop, key, value) ) 79 | return 0; 80 | return -1; 81 | } 82 | 83 | int32_t xar_ea_pget(xar_ea_t e, const char *key, const char **value) { 84 | xar_prop_t r = xar_prop_find(XAR_EA(e)->prop, key); 85 | if( !r ) { 86 | if( value ) 87 | *value = NULL; 88 | return -1; 89 | } 90 | 91 | if(value) 92 | *value = XAR_PROP(r)->value; 93 | 94 | return 0; 95 | } 96 | 97 | xar_prop_t xar_ea_root(xar_ea_t e) { 98 | return XAR_EA(e)->prop; 99 | } 100 | 101 | xar_prop_t xar_ea_find(xar_file_t f, const char *name) 102 | { 103 | xar_prop_t p; 104 | 105 | for(p = xar_prop_pfirst(f); p; p = xar_prop_pnext(p)) { 106 | const char *tmp; 107 | xar_prop_t tmpp; 108 | 109 | tmp = xar_prop_getkey(p); 110 | if( strncmp(tmp, XAR_EA_FORK, strlen(XAR_EA_FORK)) != 0 ) 111 | continue; 112 | if( strlen(tmp) != strlen(XAR_EA_FORK) ) 113 | continue; 114 | 115 | tmpp = xar_prop_pget(p, "name"); 116 | if( !tmpp ) 117 | continue; 118 | tmp = xar_prop_getvalue(tmpp); 119 | if( !tmp ) 120 | continue; 121 | 122 | if( strcmp(tmp, name) == 0 ) 123 | return p; 124 | } 125 | 126 | return NULL; 127 | } 128 | -------------------------------------------------------------------------------- /xar/strmode.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 1990, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 4. Neither the name of the University nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | #ifndef HAVE_STRMODE 30 | #if defined(LIBC_SCCS) && !defined(lint) 31 | static char sccsid[] = "@(#)strmode.c 8.3 (Berkeley) 8/15/94"; 32 | #endif /* LIBC_SCCS and not lint */ 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | void 39 | strmode(mode, p) 40 | mode_t mode; 41 | char *p; 42 | { 43 | /* print type */ 44 | switch (mode & S_IFMT) { 45 | case S_IFDIR: /* directory */ 46 | *p++ = 'd'; 47 | break; 48 | case S_IFCHR: /* character special */ 49 | *p++ = 'c'; 50 | break; 51 | case S_IFBLK: /* block special */ 52 | *p++ = 'b'; 53 | break; 54 | case S_IFREG: /* regular */ 55 | *p++ = '-'; 56 | break; 57 | case S_IFLNK: /* symbolic link */ 58 | *p++ = 'l'; 59 | break; 60 | case S_IFSOCK: /* socket */ 61 | *p++ = 's'; 62 | break; 63 | #ifdef S_IFIFO 64 | case S_IFIFO: /* fifo */ 65 | *p++ = 'p'; 66 | break; 67 | #endif 68 | #ifdef S_IFWHT 69 | case S_IFWHT: /* whiteout */ 70 | *p++ = 'w'; 71 | break; 72 | #endif 73 | default: /* unknown */ 74 | *p++ = '?'; 75 | break; 76 | } 77 | /* usr */ 78 | if (mode & S_IRUSR) 79 | *p++ = 'r'; 80 | else 81 | *p++ = '-'; 82 | if (mode & S_IWUSR) 83 | *p++ = 'w'; 84 | else 85 | *p++ = '-'; 86 | switch (mode & (S_IXUSR | S_ISUID)) { 87 | case 0: 88 | *p++ = '-'; 89 | break; 90 | case S_IXUSR: 91 | *p++ = 'x'; 92 | break; 93 | case S_ISUID: 94 | *p++ = 'S'; 95 | break; 96 | case S_IXUSR | S_ISUID: 97 | *p++ = 's'; 98 | break; 99 | } 100 | /* group */ 101 | if (mode & S_IRGRP) 102 | *p++ = 'r'; 103 | else 104 | *p++ = '-'; 105 | if (mode & S_IWGRP) 106 | *p++ = 'w'; 107 | else 108 | *p++ = '-'; 109 | switch (mode & (S_IXGRP | S_ISGID)) { 110 | case 0: 111 | *p++ = '-'; 112 | break; 113 | case S_IXGRP: 114 | *p++ = 'x'; 115 | break; 116 | case S_ISGID: 117 | *p++ = 'S'; 118 | break; 119 | case S_IXGRP | S_ISGID: 120 | *p++ = 's'; 121 | break; 122 | } 123 | /* other */ 124 | if (mode & S_IROTH) 125 | *p++ = 'r'; 126 | else 127 | *p++ = '-'; 128 | if (mode & S_IWOTH) 129 | *p++ = 'w'; 130 | else 131 | *p++ = '-'; 132 | switch (mode & (S_IXOTH | S_ISVTX)) { 133 | case 0: 134 | *p++ = '-'; 135 | break; 136 | case S_IXOTH: 137 | *p++ = 'x'; 138 | break; 139 | case S_ISVTX: 140 | *p++ = 'T'; 141 | break; 142 | case S_IXOTH | S_ISVTX: 143 | *p++ = 't'; 144 | break; 145 | } 146 | *p++ = ' '; /* will be a '+' if ACL's implemented */ 147 | *p = '\0'; 148 | } 149 | #endif /* HAVE_STRMODE */ 150 | -------------------------------------------------------------------------------- /ev_wrap.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT, automatically generated by update_ev_wrap */ 2 | #ifndef EV_WRAP_H 3 | #define EV_WRAP_H 4 | #define now_floor ((loop)->now_floor) 5 | #define mn_now ((loop)->mn_now) 6 | #define rtmn_diff ((loop)->rtmn_diff) 7 | #define io_blocktime ((loop)->io_blocktime) 8 | #define timeout_blocktime ((loop)->timeout_blocktime) 9 | #define backend ((loop)->backend) 10 | #define activecnt ((loop)->activecnt) 11 | #define loop_count ((loop)->loop_count) 12 | #define backend_fd ((loop)->backend_fd) 13 | #define backend_fudge ((loop)->backend_fudge) 14 | #define backend_modify ((loop)->backend_modify) 15 | #define backend_poll ((loop)->backend_poll) 16 | #define evfd ((loop)->evfd) 17 | #define evpipe ((loop)->evpipe) 18 | #define pipeev ((loop)->pipeev) 19 | #define curpid ((loop)->curpid) 20 | #define postfork ((loop)->postfork) 21 | #define vec_ri ((loop)->vec_ri) 22 | #define vec_ro ((loop)->vec_ro) 23 | #define vec_wi ((loop)->vec_wi) 24 | #define vec_wo ((loop)->vec_wo) 25 | #define vec_eo ((loop)->vec_eo) 26 | #define vec_max ((loop)->vec_max) 27 | #define polls ((loop)->polls) 28 | #define pollmax ((loop)->pollmax) 29 | #define pollcnt ((loop)->pollcnt) 30 | #define pollidxs ((loop)->pollidxs) 31 | #define pollidxmax ((loop)->pollidxmax) 32 | #define epoll_events ((loop)->epoll_events) 33 | #define epoll_eventmax ((loop)->epoll_eventmax) 34 | #define kqueue_changes ((loop)->kqueue_changes) 35 | #define kqueue_changemax ((loop)->kqueue_changemax) 36 | #define kqueue_changecnt ((loop)->kqueue_changecnt) 37 | #define kqueue_events ((loop)->kqueue_events) 38 | #define kqueue_eventmax ((loop)->kqueue_eventmax) 39 | #define port_events ((loop)->port_events) 40 | #define port_eventmax ((loop)->port_eventmax) 41 | #define anfds ((loop)->anfds) 42 | #define anfdmax ((loop)->anfdmax) 43 | #define pendings ((loop)->pendings) 44 | #define pendingmax ((loop)->pendingmax) 45 | #define pendingcnt ((loop)->pendingcnt) 46 | #define fdchanges ((loop)->fdchanges) 47 | #define fdchangemax ((loop)->fdchangemax) 48 | #define fdchangecnt ((loop)->fdchangecnt) 49 | #define timers ((loop)->timers) 50 | #define timermax ((loop)->timermax) 51 | #define timercnt ((loop)->timercnt) 52 | #define periodics ((loop)->periodics) 53 | #define periodicmax ((loop)->periodicmax) 54 | #define periodiccnt ((loop)->periodiccnt) 55 | #define idles ((loop)->idles) 56 | #define idlemax ((loop)->idlemax) 57 | #define idlecnt ((loop)->idlecnt) 58 | #define idleall ((loop)->idleall) 59 | #define prepares ((loop)->prepares) 60 | #define preparemax ((loop)->preparemax) 61 | #define preparecnt ((loop)->preparecnt) 62 | #define checks ((loop)->checks) 63 | #define checkmax ((loop)->checkmax) 64 | #define checkcnt ((loop)->checkcnt) 65 | #define forks ((loop)->forks) 66 | #define forkmax ((loop)->forkmax) 67 | #define forkcnt ((loop)->forkcnt) 68 | #define gotasync ((loop)->gotasync) 69 | #define asyncs ((loop)->asyncs) 70 | #define asyncmax ((loop)->asyncmax) 71 | #define asynccnt ((loop)->asynccnt) 72 | #define fs_fd ((loop)->fs_fd) 73 | #define fs_w ((loop)->fs_w) 74 | #define fs_2625 ((loop)->fs_2625) 75 | #define fs_hash ((loop)->fs_hash) 76 | #else 77 | #undef EV_WRAP_H 78 | #undef now_floor 79 | #undef mn_now 80 | #undef rtmn_diff 81 | #undef io_blocktime 82 | #undef timeout_blocktime 83 | #undef backend 84 | #undef activecnt 85 | #undef loop_count 86 | #undef backend_fd 87 | #undef backend_fudge 88 | #undef backend_modify 89 | #undef backend_poll 90 | #undef evfd 91 | #undef evpipe 92 | #undef pipeev 93 | #undef curpid 94 | #undef postfork 95 | #undef vec_ri 96 | #undef vec_ro 97 | #undef vec_wi 98 | #undef vec_wo 99 | #undef vec_eo 100 | #undef vec_max 101 | #undef polls 102 | #undef pollmax 103 | #undef pollcnt 104 | #undef pollidxs 105 | #undef pollidxmax 106 | #undef epoll_events 107 | #undef epoll_eventmax 108 | #undef kqueue_changes 109 | #undef kqueue_changemax 110 | #undef kqueue_changecnt 111 | #undef kqueue_events 112 | #undef kqueue_eventmax 113 | #undef port_events 114 | #undef port_eventmax 115 | #undef anfds 116 | #undef anfdmax 117 | #undef pendings 118 | #undef pendingmax 119 | #undef pendingcnt 120 | #undef fdchanges 121 | #undef fdchangemax 122 | #undef fdchangecnt 123 | #undef timers 124 | #undef timermax 125 | #undef timercnt 126 | #undef periodics 127 | #undef periodicmax 128 | #undef periodiccnt 129 | #undef idles 130 | #undef idlemax 131 | #undef idlecnt 132 | #undef idleall 133 | #undef prepares 134 | #undef preparemax 135 | #undef preparecnt 136 | #undef checks 137 | #undef checkmax 138 | #undef checkcnt 139 | #undef forks 140 | #undef forkmax 141 | #undef forkcnt 142 | #undef gotasync 143 | #undef asyncs 144 | #undef asyncmax 145 | #undef asynccnt 146 | #undef fs_fd 147 | #undef fs_w 148 | #undef fs_2625 149 | #undef fs_hash 150 | #endif 151 | -------------------------------------------------------------------------------- /ev_poll.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libev poll fd activity backend 3 | * 4 | * Copyright (c) 2007,2008 Marc Alexander Lehmann 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without modifica- 8 | * tion, are permitted provided that the following conditions are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- 19 | * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 20 | * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- 21 | * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- 25 | * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | * OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | * Alternatively, the contents of this file may be used under the terms of 29 | * the GNU General Public License ("GPL") version 2 or any later version, 30 | * in which case the provisions of the GPL are applicable instead of 31 | * the above. If you wish to allow the use of your version of this file 32 | * only under the terms of the GPL and not to allow others to use your 33 | * version of this file under the BSD license, indicate your decision 34 | * by deleting the provisions above and replace them with the notice 35 | * and other provisions required by the GPL. If you do not delete the 36 | * provisions above, a recipient may use your version of this file under 37 | * either the BSD or the GPL. 38 | */ 39 | 40 | #include 41 | 42 | void inline_size pollidx_init(int *base, int count) { 43 | /* 44 | * consider using memset (.., -1, ...), which is pratically guarenteed 45 | * * to work on all systems implementing poll 46 | */ 47 | while (count--) 48 | *base++ = -1; 49 | } 50 | 51 | static void poll_modify(EV_P_ int fd, int oev, int nev) { 52 | int idx; 53 | 54 | if (oev == nev) 55 | return; 56 | 57 | array_needsize(int, pollidxs, pollidxmax, fd + 1, pollidx_init); 58 | 59 | idx = pollidxs[fd]; 60 | 61 | if (idx < 0) { /* need to allocate a new pollfd */ 62 | pollidxs[fd] = idx = pollcnt++; 63 | array_needsize(struct pollfd, polls, pollmax, pollcnt, EMPTY2); 64 | polls[idx].fd = fd; 65 | } 66 | 67 | assert(polls[idx].fd == fd); 68 | 69 | if (nev) 70 | polls[idx].events = (nev & EV_READ ? POLLIN : 0) 71 | | (nev & EV_WRITE ? POLLOUT : 0); 72 | else { /* remove pollfd */ 73 | 74 | pollidxs[fd] = -1; 75 | 76 | if (expect_true(idx < --pollcnt)) { 77 | polls[idx] = polls[pollcnt]; 78 | pollidxs[polls[idx].fd] = idx; 79 | } 80 | } 81 | } 82 | 83 | static void poll_poll(EV_P_ ev_tstamp timeout) { 84 | struct pollfd *p; 85 | int res = poll(polls, pollcnt, (int)ceil(timeout * 1000.)); 86 | 87 | if (expect_false(res < 0)) { 88 | if (errno == EBADF) 89 | fd_ebadf(EV_A); 90 | else if (errno == ENOMEM && !syserr_cb) 91 | fd_enomem(EV_A); 92 | else if (errno != EINTR) 93 | ev_syserr("(libev) poll"); 94 | } else 95 | for (p = polls; res; ++p) 96 | if (expect_false(p->revents)) { /* this expect is debatable */ 97 | --res; 98 | 99 | if (expect_false(p->revents & POLLNVAL)) 100 | fd_kill(EV_A_ p->fd); 101 | else 102 | fd_event(EV_A_ p->fd, (p->revents & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0) 103 | | (p->revents & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0) 104 | ); 105 | } 106 | } 107 | 108 | int inline_size poll_init(EV_P_ int flags) { 109 | backend_fudge = 0.; /* posix says this is zero */ 110 | backend_modify = poll_modify; 111 | backend_poll = poll_poll; 112 | 113 | pollidxs = 0; 114 | pollidxmax = 0; 115 | polls = 0; 116 | pollmax = 0; 117 | pollcnt = 0; 118 | 119 | return EVBACKEND_POLL; 120 | } 121 | 122 | void inline_size poll_destroy(EV_P) { 123 | ev_free(pollidxs); 124 | ev_free(polls); 125 | } 126 | -------------------------------------------------------------------------------- /dlink.c: -------------------------------------------------------------------------------- 1 | /* Sentinel - IRC Statistical and Operator Services 2 | ** dlink.c - Hybrid derived doubly linked list library 3 | ** 4 | ** Copyright W. Campbell and others. See README for more details 5 | ** Some code Copyright: Jonathan George, Kai Seidler, ircd-hybrid Team, 6 | ** IRCnet IRCD developers. 7 | ** 8 | ** $Id: dlink.c,v 1.2 2003/09/11 14:56:34 wcampbel Exp $ 9 | */ 10 | 11 | /* Original header */ 12 | 13 | /* tcm-hybrid/src/tools.c by fl_ 14 | * Copyright (C) 2002 ircd-hybrid development team 15 | * 16 | * #Id: tools.c,v 1.6 2002/06/24 16:21:51 leeh Exp # 17 | */ 18 | #include 19 | #include "balloc.h" 20 | #include "conf.h" 21 | #include "dlink.h" 22 | #include "logger.h" 23 | int dlink_count = 0; 24 | BlockHeap *node_heap; 25 | 26 | void dlink_init(void) { 27 | if (! 28 | (node_heap = 29 | blockheap_create(sizeof(dlink_node), 30 | dconf_get_int("tuning.heap.node", 1024), "dlink_node"))) { 31 | Log(LOG_FATAL, "dlink_init(): block allocator failed"); 32 | raise(SIGTERM); 33 | } 34 | } 35 | 36 | void dlink_fini(void) { 37 | blockheap_destroy(node_heap); 38 | } 39 | 40 | dlink_node *dlink_create(void) { 41 | dlink_node *m; 42 | m = (dlink_node *) blockheap_alloc(node_heap); 43 | m->data = m->next = m->prev = NULL; 44 | 45 | dlink_count++; 46 | 47 | return m; 48 | } 49 | 50 | /* XXX - macro? */ 51 | void dlink_free(dlink_node * m) { 52 | dlink_count--; 53 | blockheap_free(node_heap, m); 54 | } 55 | 56 | void dlink_add(void *data, dlink_node * m, dlink_list * list) { 57 | m->data = data; 58 | m->next = list->head; 59 | m->prev = NULL; 60 | 61 | if (list->head != NULL) 62 | list->head->prev = m; 63 | else if (list->tail == NULL) 64 | list->tail = m; 65 | 66 | list->head = m; 67 | list->length++; 68 | } 69 | 70 | void dlink_add_before(dlink_node * b, void *data, dlink_node * m, dlink_list * list) { 71 | /* 72 | * Shortcut - if its the first one, call dlinkAdd only 73 | */ 74 | if (b == list->head) { 75 | dlink_add(data, m, list); 76 | } else { 77 | m->data = data; 78 | b->prev->next = m; 79 | m->prev = b->prev; 80 | b->prev = m; 81 | m->next = b; 82 | list->length++; 83 | } 84 | } 85 | 86 | void dlink_add_tail(void *data, dlink_node * m, dlink_list * list) { 87 | m->data = data; 88 | m->next = NULL; 89 | m->prev = list->tail; 90 | 91 | if (list->head == NULL) 92 | list->head = m; 93 | else if (list->tail != NULL) 94 | list->tail->next = m; 95 | 96 | list->tail = m; 97 | list->length++; 98 | } 99 | 100 | void dlink_delete(dlink_node * m, dlink_list * list) { 101 | /* 102 | * item is at head 103 | */ 104 | if (m->prev == NULL) 105 | list->head = m->next; 106 | else 107 | m->prev->next = m->next; 108 | 109 | /* 110 | * item is at tail 111 | */ 112 | if (m->next == NULL) 113 | list->tail = m->prev; 114 | else 115 | m->next->prev = m->prev; 116 | 117 | list->length--; 118 | } 119 | 120 | dlink_node *dlink_find(void *data, dlink_list * list) { 121 | dlink_node *ptr; 122 | 123 | DLINK_FOREACH(ptr, list->head) { 124 | if (ptr->data == data) 125 | return ptr; 126 | } 127 | 128 | return NULL; 129 | } 130 | 131 | dlink_node *dlink_find_delete(void *data, dlink_list * list) { 132 | dlink_node *ptr; 133 | 134 | DLINK_FOREACH(ptr, list->head) { 135 | if (ptr->data != data) 136 | continue; 137 | 138 | if (ptr->next != NULL) 139 | ptr->next->prev = ptr->prev; 140 | else 141 | list->tail = ptr->prev; 142 | 143 | if (ptr->prev != NULL) 144 | ptr->prev->next = ptr->next; 145 | else 146 | list->head = ptr->next; 147 | 148 | ptr->next = ptr->prev = NULL; 149 | 150 | list->length--; 151 | 152 | return ptr; 153 | } 154 | 155 | return NULL; 156 | } 157 | 158 | int dlink_length(dlink_list * list) { 159 | return list->length; 160 | } 161 | 162 | void dlink_move(dlink_node * m, dlink_list * oldlist, dlink_list * newlist) { 163 | if (m == NULL || oldlist == NULL || newlist == NULL) 164 | return; 165 | 166 | /* 167 | * Assumption: If m->next == NULL, then list->tail == m 168 | * * and: If m->prev == NULL, then list->head == m 169 | */ 170 | if (m->next) 171 | m->next->prev = m->prev; 172 | else 173 | oldlist->tail = m->prev; 174 | 175 | if (m->prev) 176 | m->prev->next = m->next; 177 | else 178 | oldlist->head = m->next; 179 | 180 | m->prev = NULL; 181 | m->next = newlist->head; 182 | 183 | if (newlist->head != NULL) 184 | newlist->head->prev = m; 185 | else if (newlist->tail == NULL) 186 | newlist->tail = m; 187 | 188 | newlist->head = m; 189 | 190 | oldlist->length--; 191 | newlist->length++; 192 | } 193 | -------------------------------------------------------------------------------- /xar/filetree.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2007 Rob Braun 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of Rob Braun nor the names of his contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | /* 30 | * 03-Apr-2005 31 | * DRI: Rob Braun 32 | */ 33 | /* 34 | * Portions Copyright 2006, Apple Computer, Inc. 35 | * Christopher Ryan 36 | */ 37 | 38 | #ifndef _XAR_FILETREE_H_ 39 | #define _XAR_FILETREE_H_ 40 | 41 | #ifndef _FILE_OFFSET_BITS 42 | #define _FILE_OFFSET_BITS 64 43 | #endif 44 | 45 | #include 46 | #include 47 | 48 | struct __xar_attr_t { 49 | const char *key; 50 | const char *value; 51 | const char *ns; 52 | const struct __xar_attr_t *next; 53 | }; 54 | typedef const struct __xar_attr_t *xar_attr_t; 55 | 56 | struct __xar_prop_t { 57 | const char *key; 58 | const char *value; 59 | const struct __xar_prop_t *parent; 60 | const struct __xar_prop_t *children; 61 | const struct __xar_prop_t *next; 62 | const struct __xar_attr_t *attrs; 63 | const struct __xar_file_t *file; 64 | const char *prefix; 65 | const char *ns; 66 | }; 67 | typedef const struct __xar_prop_t *xar_prop_t; 68 | 69 | #include "ea.h" 70 | 71 | struct __xar_file_t { 72 | const struct __xar_prop_t *props; 73 | const struct __xar_attr_t *attrs; 74 | const char *prefix; 75 | const char *ns; 76 | const char *fspath; 77 | char parent_extracted; 78 | const struct __xar_file_t *parent; 79 | const struct __xar_file_t *children; 80 | const struct __xar_file_t *next; 81 | xar_ea_t eas; 82 | uint64_t nexteaid; 83 | }; 84 | 85 | #define XAR_ATTR(x) ((struct __xar_attr_t *)(x)) 86 | #define XAR_FILE(x) ((struct __xar_file_t *)(x)) 87 | #define XAR_PROP(x) ((struct __xar_prop_t *)(x)) 88 | 89 | void xar_file_free(xar_file_t f); 90 | xar_attr_t xar_attr_new(void); 91 | int32_t xar_attr_set(xar_file_t f, const char *prop, const char *key, const char *value); 92 | int32_t xar_attr_pset(xar_file_t f, xar_prop_t p, const char *key, const char *value); 93 | const char *xar_attr_get(xar_file_t f, const char *prop, const char *key); 94 | const char *xar_attr_pget(xar_file_t f, xar_prop_t p, const char *key); 95 | void xar_attr_free(xar_attr_t a); 96 | void xar_file_serialize(xar_file_t f, xmlTextWriterPtr writer); 97 | xar_file_t xar_file_unserialize(xar_t x, xar_file_t parent, xmlTextReaderPtr reader); 98 | xar_file_t xar_file_find(xar_file_t f, const char *path); 99 | xar_file_t xar_file_new(xar_file_t f); 100 | xar_file_t xar_file_replicate(xar_file_t original, xar_file_t newparent); 101 | void xar_file_free(xar_file_t f); 102 | 103 | void xar_prop_serialize(xar_prop_t p, xmlTextWriterPtr writer); 104 | int32_t xar_prop_unserialize(xar_file_t f, xar_prop_t parent, xmlTextReaderPtr reader); 105 | void xar_prop_free(xar_prop_t p); 106 | xar_prop_t xar_prop_new(xar_file_t f, xar_prop_t parent); 107 | xar_prop_t xar_prop_pset(xar_file_t f, xar_prop_t p, const char *key, const char *value); 108 | xar_prop_t xar_prop_find(xar_prop_t p, const char *key); 109 | xar_prop_t xar_prop_pget(xar_prop_t p, const char *key); 110 | const char *xar_prop_getkey(xar_prop_t p); 111 | const char *xar_prop_getvalue(xar_prop_t p); 112 | int32_t xar_prop_setkey(xar_prop_t p, const char *key); 113 | int32_t xar_prop_setvalue(xar_prop_t p, const char *value); 114 | xar_prop_t xar_prop_pfirst(xar_file_t f); 115 | xar_prop_t xar_prop_pnext(xar_prop_t p); 116 | void xar_prop_punset(xar_file_t f, xar_prop_t p); 117 | 118 | #endif /* _XAR_FILETREE_H_ */ 119 | -------------------------------------------------------------------------------- /fuse/fuse_session.c: -------------------------------------------------------------------------------- 1 | /* 2 | FUSE: Filesystem in Userspace 3 | Copyright (C) 2001-2007 Miklos Szeredi 4 | 5 | This program can be distributed under the terms of the GNU LGPLv2. 6 | See the file COPYING.LIB 7 | */ 8 | 9 | #include "fuse_lowlevel.h" 10 | #include "fuse_misc.h" 11 | #include "fuse_common_compat.h" 12 | #include "fuse_lowlevel_compat.h" 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | struct fuse_session { 21 | struct fuse_session_ops op; 22 | 23 | void *data; 24 | 25 | volatile int exited; 26 | 27 | struct fuse_chan *ch; 28 | }; 29 | 30 | struct fuse_chan { 31 | struct fuse_chan_ops op; 32 | 33 | struct fuse_session *se; 34 | 35 | int fd; 36 | 37 | size_t bufsize; 38 | 39 | void *data; 40 | 41 | int compat; 42 | }; 43 | 44 | struct fuse_session *fuse_session_new(struct fuse_session_ops *op, void *data) 45 | { 46 | struct fuse_session *se = (struct fuse_session *) malloc(sizeof(*se)); 47 | if (se == NULL) { 48 | fprintf(stderr, "fuse: failed to allocate session\n"); 49 | return NULL; 50 | } 51 | 52 | memset(se, 0, sizeof(*se)); 53 | se->op = *op; 54 | se->data = data; 55 | 56 | return se; 57 | } 58 | 59 | void fuse_session_add_chan(struct fuse_session *se, struct fuse_chan *ch) 60 | { 61 | assert(se->ch == NULL); 62 | assert(ch->se == NULL); 63 | se->ch = ch; 64 | ch->se = se; 65 | } 66 | 67 | void fuse_session_remove_chan(struct fuse_chan *ch) 68 | { 69 | struct fuse_session *se = ch->se; 70 | if (se) { 71 | assert(se->ch == ch); 72 | se->ch = NULL; 73 | ch->se = NULL; 74 | } 75 | } 76 | 77 | struct fuse_chan *fuse_session_next_chan(struct fuse_session *se, 78 | struct fuse_chan *ch) 79 | { 80 | assert(ch == NULL || ch == se->ch); 81 | if (ch == NULL) 82 | return se->ch; 83 | else 84 | return NULL; 85 | } 86 | 87 | void fuse_session_process(struct fuse_session *se, const char *buf, size_t len, 88 | struct fuse_chan *ch) 89 | { 90 | se->op.process(se->data, buf, len, ch); 91 | } 92 | 93 | void fuse_session_destroy(struct fuse_session *se) 94 | { 95 | if (se->op.destroy) 96 | se->op.destroy(se->data); 97 | if (se->ch != NULL) 98 | fuse_chan_destroy(se->ch); 99 | free(se); 100 | } 101 | 102 | void fuse_session_exit(struct fuse_session *se) 103 | { 104 | if (se->op.exit) 105 | se->op.exit(se->data, 1); 106 | se->exited = 1; 107 | } 108 | 109 | void fuse_session_reset(struct fuse_session *se) 110 | { 111 | if (se->op.exit) 112 | se->op.exit(se->data, 0); 113 | se->exited = 0; 114 | } 115 | 116 | int fuse_session_exited(struct fuse_session *se) 117 | { 118 | if (se->op.exited) 119 | return se->op.exited(se->data); 120 | else 121 | return se->exited; 122 | } 123 | 124 | static struct fuse_chan *fuse_chan_new_common(struct fuse_chan_ops *op, int fd, 125 | size_t bufsize, void *data, 126 | int compat) 127 | { 128 | struct fuse_chan *ch = (struct fuse_chan *) malloc(sizeof(*ch)); 129 | if (ch == NULL) { 130 | fprintf(stderr, "fuse: failed to allocate channel\n"); 131 | return NULL; 132 | } 133 | 134 | memset(ch, 0, sizeof(*ch)); 135 | ch->op = *op; 136 | ch->fd = fd; 137 | ch->bufsize = bufsize; 138 | ch->data = data; 139 | ch->compat = compat; 140 | 141 | return ch; 142 | } 143 | 144 | struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd, 145 | size_t bufsize, void *data) 146 | { 147 | return fuse_chan_new_common(op, fd, bufsize, data, 0); 148 | } 149 | 150 | struct fuse_chan *fuse_chan_new_compat24(struct fuse_chan_ops_compat24 *op, 151 | int fd, size_t bufsize, void *data) 152 | { 153 | return fuse_chan_new_common((struct fuse_chan_ops *) op, fd, bufsize, 154 | data, 24); 155 | } 156 | 157 | int fuse_chan_fd(struct fuse_chan *ch) 158 | { 159 | return ch->fd; 160 | } 161 | 162 | size_t fuse_chan_bufsize(struct fuse_chan *ch) 163 | { 164 | return ch->bufsize; 165 | } 166 | 167 | void *fuse_chan_data(struct fuse_chan *ch) 168 | { 169 | return ch->data; 170 | } 171 | 172 | struct fuse_session *fuse_chan_session(struct fuse_chan *ch) 173 | { 174 | return ch->se; 175 | } 176 | 177 | int fuse_chan_recv(struct fuse_chan **chp, char *buf, size_t size) 178 | { 179 | struct fuse_chan *ch = *chp; 180 | if (ch->compat) 181 | return ((struct fuse_chan_ops_compat24 *) &ch->op) 182 | ->receive(ch, buf, size); 183 | else 184 | return ch->op.receive(chp, buf, size); 185 | } 186 | 187 | int fuse_chan_receive(struct fuse_chan *ch, char *buf, size_t size) 188 | { 189 | int res; 190 | 191 | res = fuse_chan_recv(&ch, buf, size); 192 | return res >= 0 ? res : (res != -EINTR && res != -EAGAIN) ? -1 : 0; 193 | } 194 | 195 | int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[], size_t count) 196 | { 197 | return ch->op.send(ch, iov, count); 198 | } 199 | 200 | void fuse_chan_destroy(struct fuse_chan *ch) 201 | { 202 | fuse_session_remove_chan(ch); 203 | if (ch->op.destroy) 204 | ch->op.destroy(ch); 205 | free(ch); 206 | } 207 | 208 | #ifndef __FreeBSD__ 209 | FUSE_SYMVER(".symver fuse_chan_new_compat24,fuse_chan_new@FUSE_2.4"); 210 | #endif 211 | -------------------------------------------------------------------------------- /xar/arcmod.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 Rob Braun 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of Rob Braun nor the names of his contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | /* 30 | * 03-Apr-2005 31 | * DRI: Rob Braun 32 | */ 33 | /* 34 | * Portions Copyright 2006, Apple Computer, Inc. 35 | * Christopher Ryan 36 | */ 37 | 38 | #include "arcmod.h" 39 | #include "archive.h" 40 | #include "stat.h" 41 | #include "data.h" 42 | #include "linuxattr.h" 43 | #include "fbsdattr.h" 44 | #include "darwinattr.h" 45 | #include "ext2.h" 46 | #include "xar.h" 47 | #include 48 | 49 | struct arcmod xar_arcmods[] = { 50 | { xar_stat_archive, xar_stat_extract }, /* must be first */ 51 | { xar_linuxattr_archive, xar_linuxattr_extract }, 52 | { xar_fbsdattr_archive, xar_fbsdattr_extract }, 53 | { xar_darwinattr_archive, xar_darwinattr_extract }, 54 | { xar_ext2attr_archive, xar_ext2attr_extract }, 55 | { xar_data_archive, xar_data_extract }, 56 | /* Add new modules here */ 57 | { NULL, xar_set_perm }, 58 | { NULL, xar_flags_extract } 59 | }; 60 | 61 | /* xar_arcmod_archive 62 | * x: archive to add the file to 63 | * f: node representing the file 64 | * file: the filesystem path to the file 65 | * Returns: 0 on success 66 | * Summary: This is the entry point to actual file archival. 67 | */ 68 | int32_t xar_arcmod_archive(xar_t x, xar_file_t f, const char *file, const char *buffer, size_t len) { 69 | int i; 70 | int32_t ret; 71 | for(i = 0; i < (sizeof(xar_arcmods)/sizeof(struct arcmod)); i++) { 72 | if( xar_arcmods[i].archive ) { 73 | ret = xar_arcmods[i].archive(x, f, file, buffer, len); 74 | if( ret < 0 ) { 75 | return ret; 76 | } 77 | if( ret > 0 ) { 78 | return 0; 79 | } 80 | } 81 | } 82 | return 0; 83 | } 84 | 85 | /* xar_arcmod_extract 86 | * x: archive to extract the file from 87 | * f: node representing the file 88 | * file: the filesystem path to the target file 89 | * Returns: 0 on success 90 | * Summary: This is the entry point to actual file archival. 91 | */ 92 | int32_t xar_arcmod_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len) { 93 | int i; 94 | int32_t ret; 95 | for(i = 0; i < (sizeof(xar_arcmods)/sizeof(struct arcmod)); i++) { 96 | if( xar_arcmods[i].extract ) { 97 | ret = xar_arcmods[i].extract(x, f, file, buffer, len); 98 | if( ret < 0 ) { 99 | return ret; 100 | } 101 | if( ret > 0 ) { 102 | return 0; 103 | } 104 | } 105 | } 106 | return 0; 107 | } 108 | 109 | 110 | int32_t xar_arcmod_verify(xar_t x, xar_file_t f){ 111 | return xar_data_verify(x,f); 112 | } 113 | 114 | /* xar_check_prop 115 | * x: xar archive 116 | * name: name of property to check 117 | * Description: If XAR_OPT_PROPINCLUDE is set at all, only properties 118 | * specified for inclusion will be added. 119 | * If XAR_OPT_PROPINCLUDE is not set, and XAR_OPT_PROPEXCLUDE is set, 120 | * properies specified by XAR_OPT_PROPEXCLUDE will be omitted. 121 | * Returns: 0 for not to include, 1 for include. 122 | */ 123 | int32_t xar_check_prop(xar_t x, const char *name) { 124 | xar_attr_t i; 125 | char includeset = 0; 126 | 127 | for(i = XAR(x)->attrs; i; i = XAR_ATTR(i)->next) { 128 | if( strcmp(XAR_ATTR(i)->key, XAR_OPT_PROPINCLUDE) == 0 ) { 129 | if( strcmp(XAR_ATTR(i)->value, name) == 0 ) 130 | return 1; 131 | includeset = 1; 132 | } 133 | } 134 | 135 | if( includeset ) 136 | return 0; 137 | 138 | for(i = XAR(x)->attrs; i; i = XAR_ATTR(i)->next) { 139 | if( strcmp(XAR_ATTR(i)->key, XAR_OPT_PROPEXCLUDE) == 0 ) { 140 | if( strcmp(XAR_ATTR(i)->value, name) == 0 ) 141 | return 0; 142 | } 143 | } 144 | 145 | return 1; 146 | } 147 | -------------------------------------------------------------------------------- /dictionary.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dictionary.h Sep 2007 $Revision: 1.12 $ 3 | * Implements a dictionary for string variables. 4 | * This module implements a simple dictionary object, i.e. a list 5 | * of string/string associations. This object is useful to store e.g. 6 | * informations retrieved from a configuration file (ini files). 7 | * 8 | * $Id: dictionary.h,v 1.12 2007-11-23 21:37:00 ndevilla Exp $ 9 | * $Author: ndevilla $ 10 | * $Date: 2007-11-23 21:37:00 $ 11 | * $Revision: 1.12 $ 12 | */ 13 | 14 | #if !defined(NN2_DICTIONARY) 15 | #define NN2_DICTIONARY 16 | #include 17 | 18 | /* 19 | * Dictionary object 20 | * 21 | * This object contains a list of string/string associations. Each 22 | * association is identified by a unique string key. Looking up values 23 | * in the dictionary is speeded up by the use of a (hopefully collision-free) 24 | * hash function. 25 | */ 26 | typedef struct _dictionary_ { 27 | int n; /** Number of entries in dictionary */ 28 | int size; /** Storage size */ 29 | char **val; /** List of string values */ 30 | char **key; /** List of string keys */ 31 | unsigned *hash; /** List of hash values for keys */ 32 | } dictionary; 33 | 34 | /** 35 | @brief Compute the hash key for a string. 36 | @param key Character string to use for key. 37 | @return 1 unsigned int on at least 32 bits. 38 | 39 | This hash function has been taken from an Article in Dr Dobbs Journal. 40 | This is normally a collision-free function, distributing keys evenly. 41 | The key is stored anyway in the struct so that collision can be avoided 42 | by comparing the key itself in last resort. 43 | */ 44 | extern unsigned dictionary_hash(const char *key); 45 | 46 | /** 47 | @brief Create a new dictionary object. 48 | @param size Optional initial size of the dictionary. 49 | @return 1 newly allocated dictionary objet. 50 | 51 | This function allocates a new dictionary object of given size and returns 52 | it. If you do not know in advance (roughly) the number of entries in the 53 | dictionary, give size=0. 54 | */ 55 | extern dictionary *dictionary_new(int size); 56 | 57 | /** 58 | @brief Delete a dictionary object 59 | @param d dictionary object to deallocate. 60 | @return void 61 | 62 | Deallocate a dictionary object and all memory associated to it. 63 | */ 64 | extern void dictionary_del(dictionary * vd); 65 | 66 | /** 67 | @brief Get a value from a dictionary. 68 | @param d dictionary object to search. 69 | @param key Key to look for in the dictionary. 70 | @param def Default value to return if key not found. 71 | @return 1 pointer to internally allocated character string. 72 | 73 | This function locates a key in a dictionary and returns a pointer to its 74 | value, or the passed 'def' pointer if no such key can be found in 75 | dictionary. The returned character pointer points to data internal to the 76 | dictionary object, you should not try to free it or modify it. 77 | */ 78 | extern char *dictionary_get(dictionary * d, const char *key, const char *def); 79 | 80 | /** 81 | @brief Set a value in a dictionary. 82 | @param d dictionary object to modify. 83 | @param key Key to modify or add. 84 | @param val Value to add. 85 | @return int 0 if Ok, anything else otherwise 86 | 87 | If the given key is found in the dictionary, the associated value is 88 | replaced by the provided one. If the key cannot be found in the 89 | dictionary, it is added to it. 90 | 91 | It is Ok to provide a NULL value for val, but NULL values for the dictionary 92 | or the key are considered as errors: the function will return immediately 93 | in such a case. 94 | 95 | Notice that if you dictionary_set a variable to NULL, a call to 96 | dictionary_get will return a NULL value: the variable will be found, and 97 | its value (NULL) is returned. In other words, setting the variable 98 | content to NULL is equivalent to deleting the variable from the 99 | dictionary. It is not possible (in this implementation) to have a key in 100 | the dictionary without value. 101 | 102 | This function returns non-zero in case of failure. 103 | */ 104 | extern int dictionary_set(dictionary * vd, const char *key, const char *val); 105 | 106 | /** 107 | @brief Delete a key in a dictionary 108 | @param d dictionary object to modify. 109 | @param key Key to remove. 110 | @return void 111 | 112 | This function deletes a key in a dictionary. Nothing is done if the 113 | key cannot be found. 114 | */ 115 | extern void dictionary_unset(dictionary * d, const char *key); 116 | 117 | /** 118 | @brief Dump a dictionary to an opened file pointer. 119 | @param d Dictionary to dump 120 | @param f Opened file pointer. 121 | @return void 122 | 123 | Dumps a dictionary onto an opened file pointer. Key pairs are printed out 124 | as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as 125 | output file pointers. 126 | */ 127 | extern void dictionary_dump(dictionary * d, FILE * out); 128 | 129 | #endif /* !defined(NN2_DICTIONARY) */ 130 | -------------------------------------------------------------------------------- /vfs_inotify.c: -------------------------------------------------------------------------------- 1 | /* 2 | * file: vfs_inotify.c 3 | * author: nn 4 | * copyright: 2008 N2 Networks LLC, All rights reserved. 5 | * license: MIT 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "conf.h" 19 | #include "dlink.h" 20 | #include "evt.h" 21 | #include "logger.h" 22 | #include "pkg.h" 23 | #include "vfs.h" 24 | 25 | #define INOTIFY_BUFSIZE ((sizeof(struct inotify_event) + FILENAME_MAX) * 1024) 26 | static int vfs_inotify_fd = 0; 27 | static ev_io vfs_inotify_evt; 28 | 29 | static dlink_node *vfs_watch_findnode(vfs_watch_t * watch) { 30 | dlink_node *ptr, *tptr; 31 | 32 | DLINK_FOREACH_SAFE(ptr, tptr, vfs_watch_list.head) { 33 | if ((vfs_watch_t *) ptr->data == watch) 34 | return ptr; 35 | } 36 | 37 | return NULL; 38 | } 39 | 40 | static dlink_node *vfs_watch_findnode_byfd(const int fd) { 41 | dlink_node *ptr, *tptr; 42 | 43 | DLINK_FOREACH_SAFE(ptr, tptr, vfs_watch_list.head) { 44 | if (((vfs_watch_t *) ptr->data)->fd == fd) 45 | return ptr; 46 | } 47 | 48 | return NULL; 49 | } 50 | 51 | /* 52 | * function: vfs_inotify_evt_get 53 | * description: process the events inotify has given us 54 | */ 55 | void vfs_inotify_evt_get(struct ev_loop *loop, ev_io * w, int revents) { 56 | ssize_t len, i = 0; 57 | char buf[INOTIFY_BUFSIZE] = { 0 }; 58 | char path[PATH_MAX]; 59 | dlink_node *ptr; 60 | char *ext; 61 | 62 | len = read(w->fd, buf, INOTIFY_BUFSIZE); 63 | 64 | while (i < len) { 65 | struct inotify_event *e = (struct inotify_event *)&buf[i]; 66 | 67 | if (e->name[0] == '.') 68 | continue; 69 | 70 | if ((ptr = vfs_watch_findnode_byfd(e->wd)) == NULL) { 71 | Log(LOG_ERROR, "got watch for unregistered fd %d.. wtf?", e->wd); 72 | return; 73 | } 74 | 75 | /* 76 | * If we don't have a name, this is useless event... 77 | */ 78 | if (!e->len) 79 | return; 80 | 81 | memset(path, 0, PATH_MAX); 82 | snprintf(path, PATH_MAX - 1, "%s/%s", ((vfs_watch_t *) ptr->data)->path, e->name); 83 | 84 | /* 85 | * Skip over non-packages 86 | */ 87 | ext = strrchr(path, '.'); 88 | if (strncmp(ext, ".pkg", 4) && strncmp(ext, ".xar", 4)) 89 | return; 90 | 91 | if (e->mask & IN_CLOSE_WRITE || e->mask & IN_MOVED_TO) 92 | pkg_import(path); 93 | else if (e->mask & IN_DELETE || e->mask & IN_MOVED_FROM) 94 | pkg_forget(path); 95 | else if (e->mask & IN_DELETE_SELF) { 96 | vfs_watch_remove((vfs_watch_t *) ptr->data); 97 | } 98 | 99 | i += sizeof(struct inotify_event) + e->len; 100 | } 101 | } 102 | 103 | int vfs_watch_init(void) { 104 | char buf[PATH_MAX]; 105 | char *p; 106 | if (vfs_inotify_fd) 107 | return -1; 108 | 109 | /* 110 | * Try to initialize inotify interface 111 | */ 112 | if ((vfs_inotify_fd = inotify_init()) == -1) { 113 | Log(LOG_ERROR, "%s:inotify_init %d:%s", __FUNCTION__, errno, strerror(errno)); 114 | return -2; 115 | } 116 | 117 | /* 118 | * Setup the socket callback 119 | */ 120 | ev_io_init(&vfs_inotify_evt, vfs_inotify_evt_get, vfs_inotify_fd, EV_READ); 121 | ev_io_start(evt_loop, &vfs_inotify_evt); 122 | 123 | /* 124 | * set up the blockheap 125 | */ 126 | vfs_watch_heap = 127 | blockheap_create(sizeof(vfs_watch_t), 128 | dconf_get_int("tuning.heap.vfs_watch", 32), "vfs_watch"); 129 | 130 | /* 131 | * add all the paths in the config file 132 | */ 133 | memcpy(buf, dconf_get_str("path.pkg", "/pkg"), PATH_MAX); 134 | for (p = strtok(buf, ":\n"); p; p = strtok(NULL, ":\n")) 135 | vfs_watch_add(p); 136 | 137 | return 0; 138 | } 139 | 140 | void vfs_watch_fini(void) { 141 | blockheap_destroy(vfs_watch_heap); 142 | } 143 | 144 | vfs_watch_t *vfs_watch_add(const char *path) { 145 | vfs_watch_t *wh = blockheap_alloc(vfs_watch_heap); 146 | 147 | wh->mask = IN_CLOSE_WRITE | IN_MOVED_TO | IN_MOVED_FROM | IN_DELETE | IN_DELETE_SELF; 148 | memcpy(wh->path, path, sizeof(wh->path)); 149 | 150 | if ((wh->fd = inotify_add_watch(vfs_inotify_fd, path, wh->mask)) <= 0) { 151 | Log(LOG_ERROR, "failed creating vfs watcher for path %s", wh->path); 152 | blockheap_free(vfs_watch_heap, wh); 153 | return NULL; 154 | } 155 | 156 | dlink_add_tail_alloc(wh, &vfs_watch_list); 157 | return wh; 158 | } 159 | 160 | /* XXX: We need to scan the watch lists and remove subdirs too -bk */ 161 | int vfs_watch_remove(vfs_watch_t * watch) { 162 | int rv; 163 | dlink_node *ptr; 164 | 165 | if ((rv = inotify_rm_watch(watch->fd, vfs_inotify_fd)) != 0) { 166 | Log(LOG_ERROR, "error removing watch for %s (fd: %d)", watch->path, watch->fd); 167 | } 168 | 169 | if ((ptr = vfs_watch_findnode(watch)) != NULL) { 170 | dlink_delete(ptr, &vfs_watch_list); 171 | blockheap_free(vfs_watch_heap, ptr->data); 172 | } 173 | 174 | return rv; 175 | } 176 | -------------------------------------------------------------------------------- /vfs_pkg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FUSE VFS Package file operations 3 | * 4 | * This file should NEVER be included directly outside 5 | * of vfs_fuse.c, in fact we throw an error if this 6 | * is done 7 | */ 8 | #if !defined(VFS_FUSE_C) 9 | #error never include vfs_fuse_pkg.h outside vfs_fuse.c 10 | #error this file is for internal use only 11 | #endif 12 | #include "timestr.h" 13 | 14 | static void vfs_fuse_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { 15 | pkg_inode_t *i; 16 | struct stat sb; 17 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 18 | 19 | if ((i = db_query(QUERY_INODE, "SELECT * FROM files WHERE inode = %d", (u_int32_t) ino)) != NULL) { 20 | /* 21 | * XXX: do stuff ;) 22 | */ 23 | sb.st_ino = ino; 24 | sb.st_mode = i->st_mode; 25 | sb.st_size = i->st_size; 26 | sb.st_uid = i->st_uid; 27 | sb.st_gid = i->st_gid; 28 | blockheap_free(inode_heap, i); 29 | } 30 | 31 | /* 32 | * Did we get a valid response? 33 | */ 34 | if (sb.st_ino) 35 | fuse_reply_attr(req, &sb, 0.0); 36 | else 37 | fuse_reply_err(req, ENOENT); 38 | } 39 | 40 | static void vfs_fuse_access(fuse_req_t req, fuse_ino_t ino, int mask) { 41 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 42 | fuse_reply_err(req, 0); /* success */ 43 | } 44 | 45 | static void vfs_fuse_readlink(fuse_req_t req, fuse_ino_t ino) { 46 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 47 | fuse_reply_err(req, ENOSYS); 48 | } 49 | 50 | static void vfs_fuse_opendir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { 51 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 52 | fuse_reply_err(req, ENOENT); 53 | } 54 | 55 | static void vfs_fuse_readdir(fuse_req_t req, fuse_ino_t ino, 56 | size_t size, off_t off, struct fuse_file_info *fi) { 57 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 58 | fuse_reply_err(req, ENOENT); 59 | } 60 | 61 | static void vfs_fuse_releasedir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { 62 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 63 | fuse_reply_err(req, ENOENT); 64 | } 65 | 66 | static void vfs_fuse_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { 67 | struct vfs_handle *fh; 68 | fh = blockheap_alloc(vfs_handle_heap); 69 | fi->fh = ((uint64_t) fh); 70 | pkg_inode_t *i; 71 | struct stat sb; 72 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 73 | 74 | /* 75 | * Look for fill inside a package 76 | */ 77 | if ((i = db_query(QUERY_INODE, "SELECT * FROM files WHERE inode = %d", (u_int32_t) ino))) { 78 | /* 79 | * XXX: do stuff ;) 80 | */ 81 | } else { 82 | /* 83 | * XXX: look it up in spill over 84 | */ 85 | } 86 | 87 | if (!i) { 88 | if (!fi->flags & O_CREAT) { 89 | fuse_reply_err(req, ENOENT); 90 | } else { 91 | /* 92 | * XXX: create spillover file instead of EROFS 93 | */ 94 | fuse_reply_err(req, EROFS); 95 | } 96 | } 97 | 98 | blockheap_free(inode_heap, i); 99 | fuse_reply_open(req, fi); 100 | } 101 | 102 | static void vfs_fuse_release(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { 103 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 104 | fuse_reply_err(req, 0); /* success */ 105 | } 106 | 107 | static void vfs_fuse_read(fuse_req_t req, fuse_ino_t ino, 108 | size_t size, off_t off, struct fuse_file_info *fi) { 109 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 110 | /* reply_buf_limited(req, hello_str, strlen(hello_str), off, size); */ 111 | fuse_reply_err(req, EBADF); 112 | } 113 | 114 | static void vfs_fuse_statfs(fuse_req_t req, fuse_ino_t ino) { 115 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 116 | fuse_reply_err(req, ENOSYS); 117 | } 118 | 119 | static void vfs_fuse_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name, size_t size) { 120 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 121 | fuse_reply_err(req, ENOTSUP); 122 | } 123 | 124 | static void vfs_fuse_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size) { 125 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 126 | fuse_reply_err(req, ENOTSUP); 127 | } 128 | 129 | static void vfs_fuse_lookup(fuse_req_t req, fuse_ino_t parent, const char *name) { 130 | struct fuse_entry_param e; 131 | 132 | Log(LOG_DEBUG, "[%lu] %s:%d:%s", time(NULL), __FILE__, __LINE__, __FUNCTION__); 133 | #if 0 134 | if (parent != 1) /* XXX: need checks here */ 135 | #endif 136 | fuse_reply_err(req, ENOENT); 137 | #if 0 138 | else { 139 | memset(&e, 0, sizeof(e)); 140 | e.ino = 2; /* Inode number */ 141 | e.attr_timeout = 1.0; 142 | e.entry_timeout = 1.0; 143 | /* 144 | * XXX: stat 145 | */ 146 | vfs_fuse_stat(e.ino, &e.attr); 147 | fuse_reply_entry(req, &e); 148 | } 149 | #endif 150 | } 151 | -------------------------------------------------------------------------------- /ev_port.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libev solaris event port backend 3 | * 4 | * Copyright (c) 2007,2008 Marc Alexander Lehmann 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without modifica- 8 | * tion, are permitted provided that the following conditions are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- 19 | * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 20 | * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- 21 | * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- 25 | * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | * OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | * Alternatively, the contents of this file may be used under the terms of 29 | * the GNU General Public License ("GPL") version 2 or any later version, 30 | * in which case the provisions of the GPL are applicable instead of 31 | * the above. If you wish to allow the use of your version of this file 32 | * only under the terms of the GPL and not to allow others to use your 33 | * version of this file under the BSD license, indicate your decision 34 | * by deleting the provisions above and replace them with the notice 35 | * and other provisions required by the GPL. If you do not delete the 36 | * provisions above, a recipient may use your version of this file under 37 | * either the BSD or the GPL. 38 | */ 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | void inline_speed port_associate_and_check(EV_P_ int fd, int ev) { 48 | if (0 > port_associate(backend_fd, PORT_SOURCE_FD, fd, (ev & EV_READ ? POLLIN : 0) 49 | | (ev & EV_WRITE ? POLLOUT : 0), 0) 50 | ) { 51 | if (errno == EBADFD) 52 | fd_kill(EV_A_ fd); 53 | else 54 | ev_syserr("(libev) port_associate"); 55 | } 56 | } 57 | 58 | static void port_modify(EV_P_ int fd, int oev, int nev) { 59 | /* 60 | * we need to reassociate no matter what, as closes are 61 | * * once more silently being discarded. 62 | */ 63 | if (!nev) { 64 | if (oev) 65 | port_dissociate(backend_fd, PORT_SOURCE_FD, fd); 66 | } else 67 | port_associate_and_check(EV_A_ fd, nev); 68 | } 69 | 70 | static void port_poll(EV_P_ ev_tstamp timeout) { 71 | int res, i; 72 | struct timespec ts; 73 | uint_t nget = 1; 74 | 75 | ts.tv_sec = (time_t) timeout; 76 | ts.tv_nsec = (long)(timeout - (ev_tstamp) ts.tv_sec) * 1e9; 77 | res = port_getn(backend_fd, port_events, port_eventmax, &nget, &ts); 78 | 79 | if (res == -1) { 80 | if (errno != EINTR && errno != ETIME) 81 | ev_syserr("(libev) port_getn"); 82 | 83 | return; 84 | } 85 | 86 | for (i = 0; i < nget; ++i) { 87 | if (port_events[i].portev_source == PORT_SOURCE_FD) { 88 | int fd = port_events[i].portev_object; 89 | 90 | fd_event(EV_A_ fd, (port_events[i].portev_events & (POLLOUT | POLLERR | POLLHUP) 91 | ? EV_WRITE : 0) 92 | | (port_events[i].portev_events & (POLLIN | POLLERR | POLLHUP) 93 | ? EV_READ : 0) 94 | ); 95 | 96 | port_associate_and_check(EV_A_ fd, anfds[fd].events); 97 | } 98 | } 99 | 100 | if (expect_false(nget == port_eventmax)) { 101 | ev_free(port_events); 102 | port_eventmax = array_nextsize(sizeof(port_event_t), port_eventmax, port_eventmax + 1); 103 | port_events = (port_event_t *) ev_malloc(sizeof(port_event_t) * port_eventmax); 104 | } 105 | } 106 | 107 | int inline_size port_init(EV_P_ int flags) { 108 | /* 109 | * Initalize the kernel queue 110 | */ 111 | if ((backend_fd = port_create()) < 0) 112 | return 0; 113 | 114 | fcntl(backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */ 115 | 116 | backend_fudge = 1e-3; /* needed to compensate for port_getn returning early */ 117 | backend_modify = port_modify; 118 | backend_poll = port_poll; 119 | 120 | port_eventmax = 64; /* intiial number of events receivable per poll */ 121 | port_events = (port_event_t *) ev_malloc(sizeof(port_event_t) * port_eventmax); 122 | 123 | return EVBACKEND_PORT; 124 | } 125 | 126 | void inline_size port_destroy(EV_P) { 127 | ev_free(port_events); 128 | } 129 | 130 | void inline_size port_fork(EV_P) { 131 | close(backend_fd); 132 | 133 | while ((backend_fd = port_create()) < 0) 134 | ev_syserr("(libev) port"); 135 | 136 | fcntl(backend_fd, F_SETFD, FD_CLOEXEC); 137 | 138 | /* 139 | * re-register interest in fds 140 | */ 141 | fd_rearm_all(EV_A); 142 | } 143 | -------------------------------------------------------------------------------- /xar/b64.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2004 Rob Braun 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of Rob Braun nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | /* 30 | * 1-Oct-2004 31 | * DRI: Rob Braun 32 | */ 33 | 34 | #include 35 | #include 36 | 37 | #ifdef _BTEST_ 38 | int main(int argc, char* argv[]) { 39 | unsigned char* enc = benc(argv[1], strlen(argv[1])); 40 | printf("%s", enc); 41 | printf("%s\n", bdec(enc, strlen(enc))); 42 | } 43 | #endif 44 | 45 | 46 | /* 47 | * The code below derives from "Secure Programming Cookbook for C and 48 | * C++"* and adapted by Kogule, Ryo (kogule@opendarwin.org). 49 | * 50 | * *John Viega and Matt Messier, O'Reilly, 2003 51 | * http://www.secureprogramming.com/ 52 | */ 53 | 54 | static char b64revtb[256] = { 55 | -3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*0-15*/ 56 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16-31*/ 57 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /*32-47*/ 58 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, /*48-63*/ 59 | -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /*64-79*/ 60 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /*80-95*/ 61 | -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /*96-111*/ 62 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, /*112-127*/ 63 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128-143*/ 64 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*144-159*/ 65 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*160-175*/ 66 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*176-191*/ 67 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*192-207*/ 68 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*208-223*/ 69 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*224-239*/ 70 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /*240-255*/ 71 | }; 72 | 73 | static unsigned int raw_base64_decode( 74 | const unsigned char *input, unsigned char *output, int len) 75 | { 76 | 77 | unsigned int x, i = 0, ignr = 0; 78 | unsigned char buf[3], pad = 0; 79 | 80 | while (i < len || !pad) { 81 | x = b64revtb[input[i++]]; 82 | switch (x) { 83 | case -3: /* NULL TERMINATOR */ 84 | if ((i - ignr - 1) % 4) return 1; 85 | return 0; 86 | case -2: /* PADDING CHARACTER */ 87 | if ((i - ignr - 1) % 4 < 2) { 88 | /* Invalid here */ 89 | return 1; 90 | } else if ((i - ignr - 1) % 4 == 2) { 91 | /* Make sure there's appropriate padding */ 92 | if (input[i] != '=') return 1; 93 | buf[2] = 0; 94 | pad = 2; 95 | break; 96 | } else { 97 | pad = 1; 98 | break; 99 | } 100 | return 0; 101 | case -1: 102 | ignr++; 103 | break; 104 | default: 105 | switch ((i - ignr - 1) % 4) { 106 | case 0: 107 | buf[0] = x << 2; 108 | break; 109 | case 1: 110 | buf[0] |= (x >> 4); 111 | buf[1] = x << 4; 112 | break; 113 | case 2: 114 | buf[1] |= (x >> 2); 115 | buf[2] = x << 6; 116 | break; 117 | case 3: 118 | buf[2] |= x; 119 | for (x = 0; x < 3 - pad; x++) *output++ = buf[x]; 120 | break; 121 | } 122 | break; 123 | } 124 | } 125 | if (i > len) return 2; 126 | for (x = 0; x < 3 - pad; x++) *output++ = buf[x]; 127 | return 0; 128 | } 129 | 130 | unsigned char* xar_from_base64(const unsigned char* input, int len) 131 | { 132 | int err; 133 | unsigned char *output; 134 | 135 | output = malloc(3 * (len / 4 + 1)); 136 | if (!output) return NULL; 137 | 138 | err = raw_base64_decode(input, output, len); 139 | 140 | if (err) { 141 | free(output); 142 | return NULL; 143 | } 144 | return output; 145 | } 146 | -------------------------------------------------------------------------------- /fuse/fuse_loop_mt.c: -------------------------------------------------------------------------------- 1 | /* 2 | FUSE: Filesystem in Userspace 3 | Copyright (C) 2001-2007 Miklos Szeredi 4 | 5 | This program can be distributed under the terms of the GNU LGPLv2. 6 | See the file COPYING.LIB. 7 | */ 8 | 9 | #include "fuse_lowlevel.h" 10 | #include "fuse_misc.h" 11 | #include "fuse_kernel.h" 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | /* Environment var controlling the thread stack size */ 23 | #define ENVNAME_THREAD_STACK "FUSE_THREAD_STACK" 24 | 25 | struct fuse_worker { 26 | struct fuse_worker *prev; 27 | struct fuse_worker *next; 28 | pthread_t thread_id; 29 | size_t bufsize; 30 | char *buf; 31 | struct fuse_mt *mt; 32 | }; 33 | 34 | struct fuse_mt { 35 | pthread_mutex_t lock; 36 | int numworker; 37 | int numavail; 38 | struct fuse_session *se; 39 | struct fuse_chan *prevch; 40 | struct fuse_worker main; 41 | sem_t finish; 42 | int exit; 43 | int error; 44 | }; 45 | 46 | static void list_add_worker(struct fuse_worker *w, struct fuse_worker *next) 47 | { 48 | struct fuse_worker *prev = next->prev; 49 | w->next = next; 50 | w->prev = prev; 51 | prev->next = w; 52 | next->prev = w; 53 | } 54 | 55 | static void list_del_worker(struct fuse_worker *w) 56 | { 57 | struct fuse_worker *prev = w->prev; 58 | struct fuse_worker *next = w->next; 59 | prev->next = next; 60 | next->prev = prev; 61 | } 62 | 63 | static int fuse_start_thread(struct fuse_mt *mt); 64 | 65 | static void *fuse_do_work(void *data) 66 | { 67 | struct fuse_worker *w = (struct fuse_worker *) data; 68 | struct fuse_mt *mt = w->mt; 69 | 70 | while (!fuse_session_exited(mt->se)) { 71 | int isforget = 0; 72 | struct fuse_chan *ch = mt->prevch; 73 | int res; 74 | 75 | pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 76 | res = fuse_chan_recv(&ch, w->buf, w->bufsize); 77 | pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 78 | if (res == -EINTR) 79 | continue; 80 | if (res <= 0) { 81 | if (res < 0) { 82 | fuse_session_exit(mt->se); 83 | mt->error = -1; 84 | } 85 | break; 86 | } 87 | 88 | pthread_mutex_lock(&mt->lock); 89 | if (mt->exit) { 90 | pthread_mutex_unlock(&mt->lock); 91 | return NULL; 92 | } 93 | 94 | /* 95 | * This disgusting hack is needed so that zillions of threads 96 | * are not created on a burst of FORGET messages 97 | */ 98 | if (((struct fuse_in_header *) w->buf)->opcode == FUSE_FORGET) 99 | isforget = 1; 100 | 101 | if (!isforget) 102 | mt->numavail--; 103 | if (mt->numavail == 0) 104 | fuse_start_thread(mt); 105 | pthread_mutex_unlock(&mt->lock); 106 | 107 | fuse_session_process(mt->se, w->buf, res, ch); 108 | 109 | pthread_mutex_lock(&mt->lock); 110 | if (!isforget) 111 | mt->numavail++; 112 | if (mt->numavail > 10) { 113 | if (mt->exit) { 114 | pthread_mutex_unlock(&mt->lock); 115 | return NULL; 116 | } 117 | list_del_worker(w); 118 | mt->numavail--; 119 | mt->numworker--; 120 | pthread_mutex_unlock(&mt->lock); 121 | 122 | pthread_detach(w->thread_id); 123 | free(w->buf); 124 | free(w); 125 | return NULL; 126 | } 127 | pthread_mutex_unlock(&mt->lock); 128 | } 129 | 130 | sem_post(&mt->finish); 131 | pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 132 | pause(); 133 | 134 | return NULL; 135 | } 136 | 137 | static int fuse_start_thread(struct fuse_mt *mt) 138 | { 139 | sigset_t oldset; 140 | sigset_t newset; 141 | int res; 142 | pthread_attr_t attr; 143 | char *stack_size; 144 | struct fuse_worker *w = malloc(sizeof(struct fuse_worker)); 145 | if (!w) { 146 | fprintf(stderr, "fuse: failed to allocate worker structure\n"); 147 | return -1; 148 | } 149 | memset(w, 0, sizeof(struct fuse_worker)); 150 | w->bufsize = fuse_chan_bufsize(mt->prevch); 151 | w->buf = malloc(w->bufsize); 152 | w->mt = mt; 153 | if (!w->buf) { 154 | fprintf(stderr, "fuse: failed to allocate read buffer\n"); 155 | free(w); 156 | return -1; 157 | } 158 | 159 | /* Override default stack size */ 160 | pthread_attr_init(&attr); 161 | stack_size = getenv(ENVNAME_THREAD_STACK); 162 | if (stack_size && pthread_attr_setstacksize(&attr, atoi(stack_size))) 163 | fprintf(stderr, "fuse: invalid stack size: %s\n", stack_size); 164 | 165 | /* Disallow signal reception in worker threads */ 166 | sigemptyset(&newset); 167 | sigaddset(&newset, SIGTERM); 168 | sigaddset(&newset, SIGINT); 169 | sigaddset(&newset, SIGHUP); 170 | sigaddset(&newset, SIGQUIT); 171 | pthread_sigmask(SIG_BLOCK, &newset, &oldset); 172 | res = pthread_create(&w->thread_id, &attr, fuse_do_work, w); 173 | pthread_sigmask(SIG_SETMASK, &oldset, NULL); 174 | pthread_attr_destroy(&attr); 175 | if (res != 0) { 176 | fprintf(stderr, "fuse: error creating thread: %s\n", 177 | strerror(res)); 178 | free(w->buf); 179 | free(w); 180 | return -1; 181 | } 182 | list_add_worker(w, &mt->main); 183 | mt->numavail ++; 184 | mt->numworker ++; 185 | 186 | return 0; 187 | } 188 | 189 | static void fuse_join_worker(struct fuse_mt *mt, struct fuse_worker *w) 190 | { 191 | pthread_join(w->thread_id, NULL); 192 | pthread_mutex_lock(&mt->lock); 193 | list_del_worker(w); 194 | pthread_mutex_unlock(&mt->lock); 195 | free(w->buf); 196 | free(w); 197 | } 198 | 199 | int fuse_session_loop_mt(struct fuse_session *se) 200 | { 201 | int err; 202 | struct fuse_mt mt; 203 | struct fuse_worker *w; 204 | 205 | memset(&mt, 0, sizeof(struct fuse_mt)); 206 | mt.se = se; 207 | mt.prevch = fuse_session_next_chan(se, NULL); 208 | mt.error = 0; 209 | mt.numworker = 0; 210 | mt.numavail = 0; 211 | mt.main.thread_id = pthread_self(); 212 | mt.main.prev = mt.main.next = &mt.main; 213 | sem_init(&mt.finish, 0, 0); 214 | fuse_mutex_init(&mt.lock); 215 | 216 | pthread_mutex_lock(&mt.lock); 217 | err = fuse_start_thread(&mt); 218 | pthread_mutex_unlock(&mt.lock); 219 | if (!err) { 220 | /* sem_wait() is interruptible */ 221 | while (!fuse_session_exited(se)) 222 | sem_wait(&mt.finish); 223 | 224 | for (w = mt.main.next; w != &mt.main; w = w->next) 225 | pthread_cancel(w->thread_id); 226 | mt.exit = 1; 227 | pthread_mutex_unlock(&mt.lock); 228 | 229 | while (mt.main.next != &mt.main) 230 | fuse_join_worker(&mt, mt.main.next); 231 | 232 | err = mt.error; 233 | } 234 | 235 | pthread_mutex_destroy(&mt.lock); 236 | sem_destroy(&mt.finish); 237 | fuse_session_reset(se); 238 | return err; 239 | } 240 | --------------------------------------------------------------------------------