/* ** Copyright 1998-2003 University of Illinois Board of Trustees ** Copyright 1998-2003 Mark D. Roth ** All rights reserved. ** ** handle.c - libtar code for initializing a TAR handle ** ** Mark D. Roth ** Campus Information Technologies and Educational Services ** University of Illinois at Urbana-Champaign */ #include #include #include #include #ifdef HAVE_UNISTD_H # include #endif #ifdef STDC_HEADERS # include #endif const char libtar_version[] = PACKAGE_VERSION; static tartype_t default_type = { open, close, read, write }; static int tar_init(TAR **t, const char *pathname, tartype_t *type, int oflags, int mode __unused, int options) { if ((oflags & O_ACCMODE) == O_RDWR) { errno = EINVAL; return -1; } *t = (TAR *)calloc(1, sizeof(TAR)); if (*t == NULL) return -1; (*t)->pathname = pathname; (*t)->options = options; (*t)->type = (type ? type : &default_type); (*t)->oflags = oflags; if ((oflags & O_ACCMODE) == O_RDONLY) (*t)->h = libtar_hash_new(256, (libtar_hashfunc_t)path_hashfunc); else (*t)->h = libtar_hash_new(16, (libtar_hashfunc_t)dev_hash); if ((*t)->h == NULL) { free(*t); return -1; } return 0; } /* open a new tarfile handle */ int tar_open(TAR **t, const char *pathname, tartype_t *type, int oflags, int mode, int options) { if (tar_init(t, pathname, type, oflags, mode, options) == -1) return -1; if ((options & TAR_NOOVERWRITE) && (oflags & O_CREAT)) oflags |= O_EXCL; #ifdef O_BINARY oflags |= O_BINARY; #endif (*t)->fd = (*((*t)->type->openfunc))(pathname, oflags, mode); if ((*t)->fd == -1) { libtar_hash_free((*t)->h, NULL); free(*t); return -1; } return 0; } int tar_fdopen(TAR **t, int fd, const char *pathname, tartype_t *type, int oflags, int mode, int options) { if (tar_init(t, pathname, type, oflags, mode, options) == -1) return -1; (*t)->fd = fd; return 0; } int tar_fd(TAR *t) { return t->fd; } /* close tarfile handle */ int tar_close(TAR *t) { int i; i = (*(t->type->closefunc))(t->fd); if (t->h != NULL) libtar_hash_free(t->h, ((t->oflags & O_ACCMODE) == O_RDONLY ? free : (libtar_freefunc_t)tar_dev_free)); if (t->th_pathname != NULL) free(t->th_pathname); free(t); return i; }