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