1 76193d7c 2003-09-30 devnull #include "mk.h"
2 76193d7c 2003-09-30 devnull #define ARMAG "!<arch>\n"
3 76193d7c 2003-09-30 devnull #define SARMAG 8
5 76193d7c 2003-09-30 devnull #define ARFMAG "`\n"
6 76193d7c 2003-09-30 devnull #define SARNAME 16
8 76193d7c 2003-09-30 devnull struct ar_hdr
10 76193d7c 2003-09-30 devnull char name[SARNAME];
11 76193d7c 2003-09-30 devnull char date[12];
12 76193d7c 2003-09-30 devnull char uid[6];
13 76193d7c 2003-09-30 devnull char gid[6];
14 76193d7c 2003-09-30 devnull char mode[8];
15 76193d7c 2003-09-30 devnull char size[10];
16 76193d7c 2003-09-30 devnull char fmag[2];
18 76193d7c 2003-09-30 devnull #define SAR_HDR (SARNAME+44)
20 92a0a8b6 2004-04-21 devnull static int dolong = 1;
22 76193d7c 2003-09-30 devnull static void atimes(char *);
23 76193d7c 2003-09-30 devnull static char *split(char*, char**);
26 76193d7c 2003-09-30 devnull atimeof(int force, char *name)
28 76193d7c 2003-09-30 devnull Symtab *sym;
30 76193d7c 2003-09-30 devnull char *archive, *member, buf[512];
32 76193d7c 2003-09-30 devnull archive = split(name, &member);
33 76193d7c 2003-09-30 devnull if(archive == 0)
36 76193d7c 2003-09-30 devnull t = mtime(archive);
37 76193d7c 2003-09-30 devnull sym = symlook(archive, S_AGG, 0);
39 76193d7c 2003-09-30 devnull if(force || (t > (long)sym->value)){
40 76193d7c 2003-09-30 devnull atimes(archive);
41 76193d7c 2003-09-30 devnull sym->value = (void *)t;
45 76193d7c 2003-09-30 devnull atimes(archive);
46 76193d7c 2003-09-30 devnull /* mark the aggegate as having been done */
47 76193d7c 2003-09-30 devnull symlook(strdup(archive), S_AGG, "")->value = (void *)t;
49 76193d7c 2003-09-30 devnull /* truncate long member name to sizeof of name field in archive header */
50 76193d7c 2003-09-30 devnull if(dolong)
51 76193d7c 2003-09-30 devnull snprint(buf, sizeof(buf), "%s(%s)", archive, member);
53 76193d7c 2003-09-30 devnull snprint(buf, sizeof(buf), "%s(%.*s)", archive, SARNAME, member);
54 76193d7c 2003-09-30 devnull sym = symlook(buf, S_TIME, 0);
56 76193d7c 2003-09-30 devnull return (long)sym->value; /* uggh */
57 76193d7c 2003-09-30 devnull return 0;
61 76193d7c 2003-09-30 devnull atouch(char *name)
63 76193d7c 2003-09-30 devnull char *archive, *member;
64 76193d7c 2003-09-30 devnull int fd, i;
65 76193d7c 2003-09-30 devnull struct ar_hdr h;
68 76193d7c 2003-09-30 devnull archive = split(name, &member);
69 76193d7c 2003-09-30 devnull if(archive == 0)
72 76193d7c 2003-09-30 devnull fd = open(archive, ORDWR);
73 76193d7c 2003-09-30 devnull if(fd < 0){
74 76193d7c 2003-09-30 devnull fd = create(archive, OWRITE, 0666);
75 76193d7c 2003-09-30 devnull if(fd < 0){
76 76193d7c 2003-09-30 devnull fprint(2, "create %s: %r\n", archive);
79 76193d7c 2003-09-30 devnull write(fd, ARMAG, SARMAG);
81 76193d7c 2003-09-30 devnull if(symlook(name, S_TIME, 0)){
82 76193d7c 2003-09-30 devnull /* hoon off and change it in situ */
83 76193d7c 2003-09-30 devnull LSEEK(fd, SARMAG, 0);
84 76193d7c 2003-09-30 devnull while(read(fd, (char *)&h, sizeof(h)) == sizeof(h)){
85 76193d7c 2003-09-30 devnull for(i = SARNAME-1; i > 0 && h.name[i] == ' '; i--)
87 76193d7c 2003-09-30 devnull h.name[i+1]=0;
88 76193d7c 2003-09-30 devnull if(strcmp(member, h.name) == 0){
89 76193d7c 2003-09-30 devnull t = SARNAME-sizeof(h); /* ughgghh */
90 76193d7c 2003-09-30 devnull LSEEK(fd, t, 1);
91 76193d7c 2003-09-30 devnull fprint(fd, "%-12ld", time(0));
94 76193d7c 2003-09-30 devnull t = atol(h.size);
95 76193d7c 2003-09-30 devnull if(t&01) t++;
96 76193d7c 2003-09-30 devnull LSEEK(fd, t, 1);
99 76193d7c 2003-09-30 devnull close(fd);
102 76193d7c 2003-09-30 devnull static void
103 76193d7c 2003-09-30 devnull atimes(char *ar)
105 76193d7c 2003-09-30 devnull struct ar_hdr h;
107 d946e4dc 2004-04-21 devnull int fd, i, namelen;
108 d946e4dc 2004-04-21 devnull char buf[2048], *p, *strings;
109 d946e4dc 2004-04-21 devnull char name[1024];
110 d946e4dc 2004-04-21 devnull Symtab *sym;
112 d946e4dc 2004-04-21 devnull strings = nil;
113 76193d7c 2003-09-30 devnull fd = open(ar, OREAD);
114 76193d7c 2003-09-30 devnull if(fd < 0)
117 76193d7c 2003-09-30 devnull if(read(fd, buf, SARMAG) != SARMAG){
118 76193d7c 2003-09-30 devnull close(fd);
121 d946e4dc 2004-04-21 devnull while(readn(fd, (char *)&h, sizeof(h)) == sizeof(h)){
122 76193d7c 2003-09-30 devnull t = atol(h.date);
123 76193d7c 2003-09-30 devnull if(t == 0) /* as it sometimes happens; thanks ken */
125 d946e4dc 2004-04-21 devnull namelen = 0;
126 d946e4dc 2004-04-21 devnull if(memcmp(h.name, "#1/", 3) == 0){ /* BSD */
127 d946e4dc 2004-04-21 devnull namelen = atoi(h.name+3);
128 d946e4dc 2004-04-21 devnull if(namelen >= sizeof name){
129 d946e4dc 2004-04-21 devnull namelen = 0;
130 d946e4dc 2004-04-21 devnull goto skip;
132 d946e4dc 2004-04-21 devnull if(readn(fd, name, namelen) != namelen)
134 d946e4dc 2004-04-21 devnull name[namelen] = 0;
135 d946e4dc 2004-04-21 devnull }else if(memcmp(h.name, "// ", 2) == 0){ /* GNU */
136 d946e4dc 2004-04-21 devnull /* date, uid, gid, mode all ' ' */
137 d946e4dc 2004-04-21 devnull for(i=2; i<16+12+6+6+8; i++)
138 d946e4dc 2004-04-21 devnull if(h.name[i] != ' ')
139 d946e4dc 2004-04-21 devnull goto skip;
140 d946e4dc 2004-04-21 devnull t = atol(h.size);
141 d946e4dc 2004-04-21 devnull if(t&01)
143 d946e4dc 2004-04-21 devnull free(strings);
144 d946e4dc 2004-04-21 devnull strings = malloc(t+1);
145 d946e4dc 2004-04-21 devnull if(strings){
146 d946e4dc 2004-04-21 devnull if(readn(fd, strings, t) != t){
147 d946e4dc 2004-04-21 devnull free(strings);
148 d946e4dc 2004-04-21 devnull strings = nil;
151 d946e4dc 2004-04-21 devnull strings[t] = 0;
152 d946e4dc 2004-04-21 devnull continue;
154 d946e4dc 2004-04-21 devnull goto skip;
155 d946e4dc 2004-04-21 devnull }else if(strings && h.name[0]=='/' && isdigit(h.name[1])){
156 d946e4dc 2004-04-21 devnull i = strtol(h.name+1, &p, 10);
157 92a0a8b6 2004-04-21 devnull if(*p != ' ' || i >= strlen(strings))
158 d946e4dc 2004-04-21 devnull goto skip;
159 d946e4dc 2004-04-21 devnull p = strings+i;
160 d946e4dc 2004-04-21 devnull for(; *p && *p != '/'; p++)
162 d946e4dc 2004-04-21 devnull namelen = p-(strings+i);
163 d946e4dc 2004-04-21 devnull if(namelen >= sizeof name){
164 d946e4dc 2004-04-21 devnull namelen = 0;
165 d946e4dc 2004-04-21 devnull goto skip;
167 d946e4dc 2004-04-21 devnull memmove(name, strings+i, namelen);
168 d946e4dc 2004-04-21 devnull name[namelen] = 0;
169 d946e4dc 2004-04-21 devnull namelen = 0;
171 d946e4dc 2004-04-21 devnull strncpy(name, h.name, sizeof(h.name));
172 d946e4dc 2004-04-21 devnull for(i = sizeof(h.name)-1; i > 0 && name[i] == ' '; i--)
174 d946e4dc 2004-04-21 devnull if(name[i] == '/') /* system V bug */
176 d946e4dc 2004-04-21 devnull name[i+1]=0;
178 a29753a1 2004-04-21 devnull snprint(buf, sizeof buf, "%s(%s)", ar, name);
179 d946e4dc 2004-04-21 devnull sym = symlook(strdup(buf), S_TIME, (void *)t);
180 d946e4dc 2004-04-21 devnull sym->value = (void *)t;
182 76193d7c 2003-09-30 devnull t = atol(h.size);
183 76193d7c 2003-09-30 devnull if(t&01) t++;
184 d946e4dc 2004-04-21 devnull t -= namelen;
185 76193d7c 2003-09-30 devnull LSEEK(fd, t, 1);
187 76193d7c 2003-09-30 devnull close(fd);
188 d946e4dc 2004-04-21 devnull free(strings);
191 76193d7c 2003-09-30 devnull static int
192 76193d7c 2003-09-30 devnull type(char *file)
195 76193d7c 2003-09-30 devnull char buf[SARMAG];
197 76193d7c 2003-09-30 devnull fd = open(file, OREAD);
198 76193d7c 2003-09-30 devnull if(fd < 0){
199 76193d7c 2003-09-30 devnull if(symlook(file, S_BITCH, 0) == 0){
200 76193d7c 2003-09-30 devnull Bprint(&bout, "%s doesn't exist: assuming it will be an archive\n", file);
201 76193d7c 2003-09-30 devnull symlook(file, S_BITCH, (void *)file);
203 76193d7c 2003-09-30 devnull return 1;
205 76193d7c 2003-09-30 devnull if(read(fd, buf, SARMAG) != SARMAG){
206 76193d7c 2003-09-30 devnull close(fd);
207 76193d7c 2003-09-30 devnull return 0;
209 76193d7c 2003-09-30 devnull close(fd);
210 76193d7c 2003-09-30 devnull return !strncmp(ARMAG, buf, SARMAG);
213 76193d7c 2003-09-30 devnull static char*
214 76193d7c 2003-09-30 devnull split(char *name, char **member)
216 76193d7c 2003-09-30 devnull char *p, *q;
218 76193d7c 2003-09-30 devnull p = strdup(name);
219 76193d7c 2003-09-30 devnull q = utfrune(p, '(');
221 76193d7c 2003-09-30 devnull *q++ = 0;
222 76193d7c 2003-09-30 devnull if(member)
223 76193d7c 2003-09-30 devnull *member = q;
224 76193d7c 2003-09-30 devnull q = utfrune(q, ')');
227 76193d7c 2003-09-30 devnull if(type(p))
228 76193d7c 2003-09-30 devnull return p;
229 76193d7c 2003-09-30 devnull free(p);
230 76193d7c 2003-09-30 devnull fprint(2, "mk: '%s' is not an archive\n", name);
232 76193d7c 2003-09-30 devnull return 0;