blob: a26c094ccf89d5016aa4e76e7286994424b2f6cb [file] [log] [blame]
bigbiff bigbiff9c754052013-01-09 09:09:08 -05001/*
2** Copyright 1998-2003 University of Illinois Board of Trustees
3** Copyright 1998-2003 Mark D. Roth
4** All rights reserved.
5**
6** handle.c - libtar code for initializing a TAR handle
7**
8** Mark D. Roth <roth@uiuc.edu>
9** Campus Information Technologies and Educational Services
10** University of Illinois at Urbana-Champaign
11*/
12
13#include <internal.h>
14
15#include <stdio.h>
16#include <fcntl.h>
17#include <errno.h>
18
19#ifdef HAVE_UNISTD_H
20# include <unistd.h>
21#endif
22
23#ifdef STDC_HEADERS
24# include <stdlib.h>
25#endif
26
27
28const char libtar_version[] = PACKAGE_VERSION;
29
30static tartype_t default_type = { open, close, read, write };
31
32
33static int
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -050034tar_init(TAR **t, const char *pathname, tartype_t *type,
Ethan Yonker58f21322018-08-24 11:17:36 -050035 int oflags, int mode __unused, int options)
bigbiff bigbiff9c754052013-01-09 09:09:08 -050036{
37 if ((oflags & O_ACCMODE) == O_RDWR)
38 {
39 errno = EINVAL;
40 return -1;
41 }
42
43 *t = (TAR *)calloc(1, sizeof(TAR));
44 if (*t == NULL)
45 return -1;
46
47 (*t)->pathname = pathname;
48 (*t)->options = options;
49 (*t)->type = (type ? type : &default_type);
50 (*t)->oflags = oflags;
51
52 if ((oflags & O_ACCMODE) == O_RDONLY)
53 (*t)->h = libtar_hash_new(256,
54 (libtar_hashfunc_t)path_hashfunc);
55 else
56 (*t)->h = libtar_hash_new(16, (libtar_hashfunc_t)dev_hash);
57 if ((*t)->h == NULL)
58 {
59 free(*t);
60 return -1;
61 }
62
63 return 0;
64}
65
66
67/* open a new tarfile handle */
68int
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -050069tar_open(TAR **t, const char *pathname, tartype_t *type,
bigbiff bigbiff9c754052013-01-09 09:09:08 -050070 int oflags, int mode, int options)
71{
72 if (tar_init(t, pathname, type, oflags, mode, options) == -1)
73 return -1;
74
75 if ((options & TAR_NOOVERWRITE) && (oflags & O_CREAT))
76 oflags |= O_EXCL;
77
78#ifdef O_BINARY
79 oflags |= O_BINARY;
80#endif
81
82 (*t)->fd = (*((*t)->type->openfunc))(pathname, oflags, mode);
83 if ((*t)->fd == -1)
84 {
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -050085 libtar_hash_free((*t)->h, NULL);
bigbiff bigbiff9c754052013-01-09 09:09:08 -050086 free(*t);
87 return -1;
88 }
89
90 return 0;
91}
92
93
94int
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -050095tar_fdopen(TAR **t, int fd, const char *pathname, tartype_t *type,
bigbiff bigbiff9c754052013-01-09 09:09:08 -050096 int oflags, int mode, int options)
97{
98 if (tar_init(t, pathname, type, oflags, mode, options) == -1)
99 return -1;
100
101 (*t)->fd = fd;
102 return 0;
103}
104
105
106int
107tar_fd(TAR *t)
108{
109 return t->fd;
110}
111
112
113/* close tarfile handle */
114int
115tar_close(TAR *t)
116{
117 int i;
118
119 i = (*(t->type->closefunc))(t->fd);
120
121 if (t->h != NULL)
122 libtar_hash_free(t->h, ((t->oflags & O_ACCMODE) == O_RDONLY
123 ? free
124 : (libtar_freefunc_t)tar_dev_free));
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500125 if (t->th_pathname != NULL)
126 free(t->th_pathname);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500127 free(t);
128
129 return i;
130}
131
132