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