blob: 7fb3f51f083734133fc11b0ec5d57ea725d246b7 [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** util.c - miscellaneous utility code for libtar
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 <sys/param.h>
17#include <errno.h>
Ethan Yonker71187742017-01-13 13:30:10 -060018#include <linux/capability.h>
bigbiff bigbiff9c754052013-01-09 09:09:08 -050019
20#ifdef STDC_HEADERS
21# include <string.h>
22#endif
23
24
25/* hashing function for pathnames */
26int
27path_hashfunc(char *key, int numbuckets)
28{
29 char buf[MAXPATHLEN];
30 char *p;
31
32 strcpy(buf, key);
33 p = basename(buf);
34
35 return (((unsigned int)p[0]) % numbuckets);
36}
37
38
39/* matching function for dev_t's */
40int
41dev_match(dev_t *dev1, dev_t *dev2)
42{
43 return !memcmp(dev1, dev2, sizeof(dev_t));
44}
45
46
47/* matching function for ino_t's */
48int
49ino_match(ino_t *ino1, ino_t *ino2)
50{
51 return !memcmp(ino1, ino2, sizeof(ino_t));
52}
53
54
55/* hashing function for dev_t's */
56int
57dev_hash(dev_t *dev)
58{
59 return *dev % 16;
60}
61
62
63/* hashing function for ino_t's */
64int
65ino_hash(ino_t *inode)
66{
67 return *inode % 256;
68}
69
70
71/*
72** mkdirhier() - create all directories in a given path
73** returns:
74** 0 success
75** 1 all directories already exist
76** -1 (and sets errno) error
77*/
78int
79mkdirhier(char *path)
80{
81 char src[MAXPATHLEN], dst[MAXPATHLEN] = "";
82 char *dirp, *nextp = src;
83 int retval = 1;
84
85 if (strlcpy(src, path, sizeof(src)) > sizeof(src))
86 {
87 errno = ENAMETOOLONG;
88 return -1;
89 }
90
91 if (path[0] == '/')
92 strcpy(dst, "/");
93
94 while ((dirp = strsep(&nextp, "/")) != NULL)
95 {
96 if (*dirp == '\0')
97 continue;
98
99 if (dst[0] != '\0')
100 strcat(dst, "/");
101 strcat(dst, dirp);
102
103 if (mkdir(dst, 0777) == -1)
104 {
105 if (errno != EEXIST)
106 return -1;
107 }
108 else
109 retval = 0;
110 }
111
112 return retval;
113}
114
115
116/* calculate header checksum */
117int
118th_crc_calc(TAR *t)
119{
120 int i, sum = 0;
121
122 for (i = 0; i < T_BLOCKSIZE; i++)
123 sum += ((unsigned char *)(&(t->th_buf)))[i];
124 for (i = 0; i < 8; i++)
125 sum += (' ' - (unsigned char)t->th_buf.chksum[i]);
126
127 return sum;
128}
129
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500130/* calculate a signed header checksum */
131int
132th_signed_crc_calc(TAR *t)
133{
134 int i, sum = 0;
135
136 for (i = 0; i < T_BLOCKSIZE; i++)
137 sum += ((signed char *)(&(t->th_buf)))[i];
138 for (i = 0; i < 8; i++)
139 sum += (' ' - (signed char)t->th_buf.chksum[i]);
140
141 return sum;
142}
143
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500144/* string-octal to integer conversion */
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500145int64_t
146oct_to_int(char *oct, size_t octlen)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500147{
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500148 long long int val;
149 char tmp[octlen + 1];
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500150
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500151 memcpy(tmp, oct, octlen);
152 tmp[octlen] = '\0';
153 return sscanf(oct, "%llo", &val) == 1 ? (int64_t)val : 0;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500154}
155
156
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500157/* string-octal or binary to integer conversion */
158int64_t oct_to_int_ex(char *oct, size_t octlen)
159{
160 if (*(unsigned char *)oct & 0x80) {
161 int64_t val = 0;
162 char tmp[octlen];
163 unsigned char *p;
164 unsigned int i;
165
166 memcpy(tmp, oct, octlen);
167 *tmp &= 0x7f;
168 p = (unsigned char *)tmp + octlen - sizeof(val);
169 for (i = 0; i < sizeof(val); ++i) {
170 val <<= 8;
171 val |= *(p++);
172 }
173 return val;
174 }
175 return oct_to_int(oct, octlen);
176}
177
178
179/* integer to NULL-terminated string-octal conversion */
180void int_to_oct(int64_t num, char *oct, size_t octlen)
181{
182 char tmp[sizeof(num)*3 + 1];
183 int olen;
184
185 olen = sprintf(tmp, "%0*llo", (int)octlen, (long long)num);
186 memcpy(oct, tmp + olen - octlen + 1, octlen);
187}
188
189
190/* integer to string-octal conversion, or binary as necessary */
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500191void
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500192int_to_oct_ex(int64_t num, char *oct, size_t octlen)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500193{
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500194 if (num < 0 || num >= ((int64_t)1 << ((octlen - 1) * 3))) {
195 unsigned char *p;
196 unsigned int i;
197
198 memset(oct, 0, octlen);
199 p = (unsigned char *)oct + octlen;
200 for (i = 0; i < sizeof(num); ++i) {
201 *(--p) = num & 0xff;
202 num >>= 8;
203 }
204 if (num < 0) {
205 for (; i < octlen; ++i) {
206 *(--p) = 0xff;
207 }
208 }
209 *(unsigned char *)oct |= 0x80;
210 return;
211 }
212 int_to_oct(num, oct, octlen);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500213}
Ethan Yonker71187742017-01-13 13:30:10 -0600214
215void print_caps(struct vfs_cap_data *cap_data) {
216 printf(" magic_etc=%u \n", cap_data->magic_etc);
217 printf(" data[0].permitted=%u \n", cap_data->data[0].permitted);
218 printf(" data[0].inheritable=%u \n", cap_data->data[0].inheritable);
219 printf(" data[1].permitted=%u \n", cap_data->data[1].permitted);
220 printf(" data[1].inheritable=%u \n", cap_data->data[1].inheritable);
221}