/[gentoo-projects]/pax-utils/paxinc.c
Gentoo

Contents of /pax-utils/paxinc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.15 - (show annotations) (download) (as text)
Sun Nov 4 07:26:24 2012 UTC (21 months, 3 weeks ago) by vapier
Branch: MAIN
Changes since 1.14: +4 -4 lines
File MIME type: text/x-csrc
update copyright years

1 /*
2 * Copyright 2003-2012 Gentoo Foundation
3 * Distributed under the terms of the GNU General Public License v2
4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/paxinc.c,v 1.14 2010/12/08 01:16:01 vapier Exp $
5 *
6 * Copyright 2005-2012 Ned Ludd - <solar@gentoo.org>
7 * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org>
8 */
9
10 /* stick common symbols here that are needed by paxinc.h */
11
12 #define IN_paxinc
13 #include "paxinc.h"
14
15 char do_reverse_endian;
16
17 /* some of this ar code was taken from busybox */
18
19 #define AR_MAGIC "!<arch>"
20 #define AR_MAGIC_SIZE (sizeof(AR_MAGIC)-1) /* dont count null byte */
21 archive_handle *ar_open_fd(const char *filename, int fd)
22 {
23 static archive_handle ret;
24 char buf[AR_MAGIC_SIZE];
25
26 ret.filename = filename;
27 ret.fd = fd;
28 ret.skip = 0;
29 ret.extfn = NULL;
30
31 if (read(ret.fd, buf, AR_MAGIC_SIZE) != AR_MAGIC_SIZE)
32 return NULL;
33 if (strncmp(buf, AR_MAGIC, AR_MAGIC_SIZE))
34 return NULL;
35
36 return &ret;
37 }
38 archive_handle *ar_open(const char *filename)
39 {
40 int fd;
41 archive_handle *ret;
42
43 if ((fd=open(filename, O_RDONLY)) == -1)
44 err("Could not open '%s'", filename);
45
46 ret = ar_open_fd(filename, fd);
47 if (ret == NULL)
48 close(fd);
49
50 return ret;
51 }
52
53 archive_member *ar_next(archive_handle *ar)
54 {
55 char *s;
56 size_t len = 0;
57 static archive_member ret;
58
59 if (ar->skip && lseek(ar->fd, ar->skip, SEEK_CUR) == -1) {
60 close_and_ret:
61 close(ar->fd);
62 return NULL;
63 }
64
65 if (read(ar->fd, ret.buf.raw, sizeof(ret.buf.raw)) != sizeof(ret.buf.raw))
66 goto close_and_ret;
67
68 /* ar header starts on an even byte (2 byte aligned)
69 * '\n' is used for padding */
70 if (ret.buf.raw[0] == '\n') {
71 memmove(ret.buf.raw, ret.buf.raw+1, 59);
72 if (read(ar->fd, ret.buf.raw+59, 1) != 1)
73 goto close_and_ret;
74 }
75
76 if ((ret.buf.formatted.magic[0] != '`') || (ret.buf.formatted.magic[1] != '\n')) {
77 warn("Invalid ar entry");
78 goto close_and_ret;
79 }
80
81 if (ret.buf.formatted.name[0] == '/' && ret.buf.formatted.name[1] == '/') {
82 if (ar->extfn != NULL) {
83 warn("Duplicate GNU extended filename section");
84 goto close_and_ret;
85 }
86 len = atoi(ret.buf.formatted.size);
87 /* we will leak this memory */
88 ar->extfn = xmalloc(sizeof(char) * (len + 1));
89 if (read(ar->fd, ar->extfn, len) != len)
90 goto close_and_ret;
91 ar->extfn[len--] = '\0';
92 for (; len > 0; len--)
93 if (ar->extfn[len] == '\n')
94 ar->extfn[len] = '\0';
95 ar->skip = 0;
96 return ar_next(ar);
97 }
98
99 s = ret.buf.formatted.name;
100 if (s[0] == '#' && s[1] == '1' && s[2] == '/') {
101 /* BSD extended filename, always in use on Darwin */
102 len = atoi(s + 3);
103 if (len <= sizeof(ret.buf.formatted.name)) {
104 if (read(ar->fd, ret.buf.formatted.name, len) != len)
105 goto close_and_ret;
106 } else {
107 s = alloca(sizeof(char) * len);
108 if (read(ar->fd, s, len) != len)
109 goto close_and_ret;
110 }
111 } else if (s[0] == '/' && s[1] >= '0' && s[1] <= '9') {
112 /* GNU extended filename */
113 if (ar->extfn == NULL) {
114 warn("GNU extended filename without special data section");
115 goto close_and_ret;
116 }
117 s = ar->extfn + atoi(s + 1);
118 }
119
120 snprintf(ret.name, sizeof(ret.name), "%s:%s", ar->filename, s);
121 if ((s=strchr(ret.name+strlen(ar->filename), '/')) != NULL)
122 *s = '\0';
123 ret.date = atoi(ret.buf.formatted.date);
124 ret.uid = atoi(ret.buf.formatted.uid);
125 ret.gid = atoi(ret.buf.formatted.gid);
126 ret.mode = strtol(ret.buf.formatted.mode, NULL, 8);
127 ret.size = atoi(ret.buf.formatted.size);
128 ar->skip = ret.size - len;
129
130 return &ret;
131 }
132
133 /* Convert file perms into octal string */
134 const char *strfileperms(const char *fname)
135 {
136 struct stat st;
137 static char buf[8];
138
139 if (stat(fname, &st) == -1)
140 return "";
141
142 snprintf(buf, sizeof(buf), "%o", st.st_mode);
143
144 return buf + 2;
145 }
146
147 /* Color helpers */
148 #define COLOR(c,b) "\e[" c ";" b "m"
149 const char *NORM = COLOR("00", "00");
150 const char *RED = COLOR("31", "01");
151 const char *YELLOW = COLOR("33", "01");
152
153 void color_init(bool disable)
154 {
155 if (!disable) {
156 const char *nocolor = getenv("NOCOLOR");
157 if (nocolor)
158 disable = !strcmp(nocolor, "yes") || !strcmp(nocolor, "true");
159 }
160 if (disable)
161 NORM = RED = YELLOW = "";
162 }

  ViewVC Help
Powered by ViewVC 1.1.20