|
|
1.1 root 1: #include <string.h>
2: #include <time.h>
3: #include "tar.h"
4:
5: static int
6: chksum(struct tarbuf *buf)
7: {
8: char *p;
9: int sum;
10:
11: p = (char *) buf;
12: for (sum = 0; p < buf->chksum; ++p)
13: sum += *(unsigned char *) p;
14: sum += ' ' * sizeof buf->chksum;
15: for (p = buf->chksum + sizeof buf->chksum; p < (char *) (buf + 1); ++p)
16: sum += *(unsigned char *) p;
17: return sum;
18: }
19:
20: /* opposite of strncpy */
21: static void
22: cpystrn(char *dst, char *src, int n)
23: {
24: while (n-- && (*dst++ = *src++))
25: ;
26: *dst = '\0';
27: }
28:
29: static int
30: getoct(unsigned long *dst, char *src, int n)
31: {
32: *dst = 0;
33: while (n && *src == ' ')
34: ++src, --n;
35: while (n && *src >= '0' && *src <= '7') {
36: *dst = 8 * *dst + *src - '0';
37: ++src, --n;
38: }
39: while (n) {
40: if (*src && *src != ' ')
41: return 1;
42: ++src, --n;
43: }
44: return 0;
45: }
46:
47: static void
48: putoct(char *dst, unsigned long val, int n)
49: {
50: char temp[24], *sp;
51:
52: sp = temp;
53: do { /* at least one digit */
54: *sp++ = val % 8 + '0';
55: val /= 8;
56: } while (val);
57: while ((n - 1) - (sp - temp))
58: *dst++ = ' ', --n;
59: while (sp > temp)
60: *dst++ = *--sp, --n;
61: while (n--)
62: *dst++ = ' ';
63: }
64:
65: int
66: thdrget(struct tarhdr *hdr, struct tarbuf *buf)
67: {
68: int nerr, len, id, bufsum, mysum;
69: char name[sizeof buf->uname], *np;
70: unsigned long otmp;
71:
72: nerr = 0;
73: memset(hdr, 0, sizeof *hdr);
74: cpystrn(hdr->name, buf->prefix, sizeof buf->prefix);
75: if (len = strlen(hdr->name))
76: hdr->name[len++] = '/';
77: cpystrn(hdr->name + len, buf->name, sizeof buf->name);
78: #define OCT(V, S) nerr += getoct(&otmp, S, sizeof S), V = otmp
79: OCT(hdr->mode, buf->mode);
80: OCT(hdr->uid, buf->uid);
81: OCT(hdr->gid, buf->gid);
82: OCT(hdr->size, buf->size);
83: OCT(hdr->mtime, buf->mtime);
84: OCT(bufsum, buf->chksum);
85: mysum = chksum(buf);
86: nerr += bufsum != mysum;
87: hdr->typeflag = buf->typeflag[0];
88: cpystrn(hdr->linkname, buf->linkname, sizeof buf->linkname);
89: len = strlen(hdr->name);
90: if (memcmp(buf->magic, TMAGIC, TMAGLEN) == 0
91: && memcmp(buf->version, TVERSION, TVERSLEN) == 0) {
92: if (hdr->typeflag == DIRTYPE && hdr->name[len - 1] != '/')
93: hdr->name[len++] = '/', hdr->name[len] = '\0';
94: cpystrn(name, buf->uname, sizeof buf->uname - 1);
95: id = uidnum(name);
96: if (id != -1)
97: hdr->uid = id;
98: cpystrn(name, buf->gname, sizeof buf->gname - 1);
99: id = gidnum(name);
100: if (id != -1)
101: hdr->gid = id;
102: OCT(hdr->devmajor, buf->devmajor);
103: OCT(hdr->devminor, buf->devminor);
104: } else {
105: if (hdr->name[len - 1] == '/')
106: hdr->typeflag = DIRTYPE;
107: np = uidstr(hdr->uid);
108: if (np)
109: cpystrn(hdr->uname, np, sizeof buf->uname - 1);
110: np = gidstr(hdr->gid);
111: if (np)
112: cpystrn(hdr->gname, np, sizeof buf->gname - 1);
113: hdr->devmajor = 0;
114: hdr->devminor = 0;
115: }
116: if (hdr->typeflag == AREGTYPE)
117: hdr->typeflag = REGTYPE;
118: #undef OCT
119: return nerr;
120: }
121:
122: int
123: thdrput(struct tarbuf *buf, struct tarhdr *hdr)
124: {
125: int npref, mysum;
126: char *slash, *s;
127:
128: memset(buf, 0, sizeof *buf);
129: if (strlen(hdr->name) > sizeof buf->name) {
130: /* split on a '/' */
131: npref = 0;
132: while (slash = strchr(hdr->name + npref + 1, '/')) {
133: npref = slash - hdr->name;
134: if (strlen(slash + 1) <= sizeof buf->name)
135: break;
136: }
137: if (!slash || npref > sizeof buf->prefix)
138: return 1;
139: strncpy(buf->name, slash + 1, sizeof buf->name);
140: *slash = '\0'; /* evil */
141: strncpy(buf->prefix, hdr->name, sizeof buf->prefix);
142: *slash = '/';
143: } else
144: strncpy(buf->name, hdr->name, sizeof buf->name);
145: if (hdr->uname[0])
146: hdr->uid = uidnum(hdr->uname);
147: else if (s = uidstr(hdr->uid)) {
148: hdr->uname[TUGNAMEMAX] = '\0';
149: strncpy(hdr->uname, s, TUGNAMEMAX);
150: }
151: if (hdr->gname[0])
152: hdr->gid = gidnum(hdr->gname);
153: else if (s = gidstr(hdr->gid)) {
154: hdr->gname[TUGNAMEMAX] = '\0';
155: strncpy(hdr->gname, s, TUGNAMEMAX);
156: }
157: #define OCT(S, V) putoct(S, V, sizeof S)
158: OCT(buf->mode, hdr->mode);
159: OCT(buf->uid, hdr->uid);
160: OCT(buf->gid, hdr->gid);
161: OCT(buf->size, hdr->size);
162: OCT(buf->mtime, hdr->mtime);
163: buf->typeflag[0] = hdr->typeflag;
164: strncpy(buf->linkname, hdr->linkname, sizeof buf->linkname);
165: strncpy(buf->magic, TMAGIC, TMAGLEN);
166: strncpy(buf->version, TVERSION, TVERSLEN);
167: strncpy(buf->uname, hdr->uname, TUGNAMEMAX);
168: strncpy(buf->gname, hdr->gname, TUGNAMEMAX);
169: if (hdr->typeflag == BLKTYPE || hdr->typeflag == CHRTYPE) {
170: OCT(buf->devmajor, hdr->devmajor);
171: OCT(buf->devminor, hdr->devminor);
172: }
173: mysum = chksum(buf);
174: OCT(buf->chksum, mysum);
175: return 0;
176: #undef OCT
177: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.