1*74a4d8c2SCharles.Forsyth #include "mk.h"
2*74a4d8c2SCharles.Forsyth #include <ar.h>
3*74a4d8c2SCharles.Forsyth
4*74a4d8c2SCharles.Forsyth static int dolong;
5*74a4d8c2SCharles.Forsyth
6*74a4d8c2SCharles.Forsyth static void atimes(char *);
7*74a4d8c2SCharles.Forsyth static char *split(char*, char**);
8*74a4d8c2SCharles.Forsyth
9*74a4d8c2SCharles.Forsyth long
atimeof(int force,char * name)10*74a4d8c2SCharles.Forsyth atimeof(int force, char *name)
11*74a4d8c2SCharles.Forsyth {
12*74a4d8c2SCharles.Forsyth Symtab *sym;
13*74a4d8c2SCharles.Forsyth long t;
14*74a4d8c2SCharles.Forsyth char *archive, *member, buf[512];
15*74a4d8c2SCharles.Forsyth
16*74a4d8c2SCharles.Forsyth archive = split(name, &member);
17*74a4d8c2SCharles.Forsyth if(archive == 0)
18*74a4d8c2SCharles.Forsyth Exit();
19*74a4d8c2SCharles.Forsyth
20*74a4d8c2SCharles.Forsyth t = mtime(archive);
21*74a4d8c2SCharles.Forsyth sym = symlook(archive, S_AGG, 0);
22*74a4d8c2SCharles.Forsyth if(sym){
23*74a4d8c2SCharles.Forsyth if(force || (t > (long)sym->value)){
24*74a4d8c2SCharles.Forsyth atimes(archive);
25*74a4d8c2SCharles.Forsyth sym->value = (void *)t;
26*74a4d8c2SCharles.Forsyth }
27*74a4d8c2SCharles.Forsyth }
28*74a4d8c2SCharles.Forsyth else{
29*74a4d8c2SCharles.Forsyth atimes(archive);
30*74a4d8c2SCharles.Forsyth /* mark the aggegate as having been done */
31*74a4d8c2SCharles.Forsyth symlook(strdup(archive), S_AGG, "")->value = (void *)t;
32*74a4d8c2SCharles.Forsyth }
33*74a4d8c2SCharles.Forsyth /* truncate long member name to sizeof of name field in archive header */
34*74a4d8c2SCharles.Forsyth if(dolong)
35*74a4d8c2SCharles.Forsyth snprint(buf, sizeof(buf), "%s(%s)", archive, member);
36*74a4d8c2SCharles.Forsyth else
37*74a4d8c2SCharles.Forsyth snprint(buf, sizeof(buf), "%s(%.*s)", archive, SARNAME, member);
38*74a4d8c2SCharles.Forsyth sym = symlook(buf, S_TIME, 0);
39*74a4d8c2SCharles.Forsyth if (sym)
40*74a4d8c2SCharles.Forsyth return (long)sym->value; /* uggh */
41*74a4d8c2SCharles.Forsyth return 0;
42*74a4d8c2SCharles.Forsyth }
43*74a4d8c2SCharles.Forsyth
44*74a4d8c2SCharles.Forsyth void
atouch(char * name)45*74a4d8c2SCharles.Forsyth atouch(char *name)
46*74a4d8c2SCharles.Forsyth {
47*74a4d8c2SCharles.Forsyth char *archive, *member;
48*74a4d8c2SCharles.Forsyth int fd, i;
49*74a4d8c2SCharles.Forsyth struct ar_hdr h;
50*74a4d8c2SCharles.Forsyth long t;
51*74a4d8c2SCharles.Forsyth
52*74a4d8c2SCharles.Forsyth archive = split(name, &member);
53*74a4d8c2SCharles.Forsyth if(archive == 0)
54*74a4d8c2SCharles.Forsyth Exit();
55*74a4d8c2SCharles.Forsyth
56*74a4d8c2SCharles.Forsyth fd = open(archive, ORDWR);
57*74a4d8c2SCharles.Forsyth if(fd < 0){
58*74a4d8c2SCharles.Forsyth fd = create(archive, OWRITE, 0666);
59*74a4d8c2SCharles.Forsyth if(fd < 0){
60*74a4d8c2SCharles.Forsyth perror(archive);
61*74a4d8c2SCharles.Forsyth Exit();
62*74a4d8c2SCharles.Forsyth }
63*74a4d8c2SCharles.Forsyth write(fd, ARMAG, SARMAG);
64*74a4d8c2SCharles.Forsyth }
65*74a4d8c2SCharles.Forsyth if(symlook(name, S_TIME, 0)){
66*74a4d8c2SCharles.Forsyth /* hoon off and change it in situ */
67*74a4d8c2SCharles.Forsyth LSEEK(fd, SARMAG, 0);
68*74a4d8c2SCharles.Forsyth while(read(fd, (char *)&h, sizeof(h)) == sizeof(h)){
69*74a4d8c2SCharles.Forsyth for(i = SARNAME-1; i > 0 && h.name[i] == ' '; i--)
70*74a4d8c2SCharles.Forsyth ;
71*74a4d8c2SCharles.Forsyth h.name[i+1]=0;
72*74a4d8c2SCharles.Forsyth if(strcmp(member, h.name) == 0){
73*74a4d8c2SCharles.Forsyth t = SARNAME-sizeof(h); /* ughgghh */
74*74a4d8c2SCharles.Forsyth LSEEK(fd, t, 1);
75*74a4d8c2SCharles.Forsyth fprint(fd, "%-12ld", time(0));
76*74a4d8c2SCharles.Forsyth break;
77*74a4d8c2SCharles.Forsyth }
78*74a4d8c2SCharles.Forsyth t = atol(h.size);
79*74a4d8c2SCharles.Forsyth if(t&01) t++;
80*74a4d8c2SCharles.Forsyth LSEEK(fd, t, 1);
81*74a4d8c2SCharles.Forsyth }
82*74a4d8c2SCharles.Forsyth }
83*74a4d8c2SCharles.Forsyth close(fd);
84*74a4d8c2SCharles.Forsyth }
85*74a4d8c2SCharles.Forsyth
86*74a4d8c2SCharles.Forsyth static void
atimes(char * ar)87*74a4d8c2SCharles.Forsyth atimes(char *ar)
88*74a4d8c2SCharles.Forsyth {
89*74a4d8c2SCharles.Forsyth struct ar_hdr h;
90*74a4d8c2SCharles.Forsyth long t;
91*74a4d8c2SCharles.Forsyth int fd, i;
92*74a4d8c2SCharles.Forsyth char buf[BIGBLOCK];
93*74a4d8c2SCharles.Forsyth char *n, name[sizeof(h.name)+1];
94*74a4d8c2SCharles.Forsyth
95*74a4d8c2SCharles.Forsyth fd = open(ar, OREAD);
96*74a4d8c2SCharles.Forsyth if(fd < 0)
97*74a4d8c2SCharles.Forsyth return;
98*74a4d8c2SCharles.Forsyth
99*74a4d8c2SCharles.Forsyth if(read(fd, buf, SARMAG) != SARMAG){
100*74a4d8c2SCharles.Forsyth close(fd);
101*74a4d8c2SCharles.Forsyth return;
102*74a4d8c2SCharles.Forsyth }
103*74a4d8c2SCharles.Forsyth while(read(fd, (char *)&h, sizeof(h)) == sizeof(h)){
104*74a4d8c2SCharles.Forsyth t = atol(h.date);
105*74a4d8c2SCharles.Forsyth if(t == 0) /* as it sometimes happens; thanks ken */
106*74a4d8c2SCharles.Forsyth t = 1;
107*74a4d8c2SCharles.Forsyth strncpy(name, h.name, sizeof(h.name));
108*74a4d8c2SCharles.Forsyth for(i = sizeof(h.name)-1; i > 0 && name[i] == ' '; i--)
109*74a4d8c2SCharles.Forsyth ;
110*74a4d8c2SCharles.Forsyth if(name[i] == '/') /* system V bug */
111*74a4d8c2SCharles.Forsyth i--;
112*74a4d8c2SCharles.Forsyth name[i+1]=0;
113*74a4d8c2SCharles.Forsyth n = membername(name, fd, h.size);
114*74a4d8c2SCharles.Forsyth if(n == nil){
115*74a4d8c2SCharles.Forsyth dolong = 1;
116*74a4d8c2SCharles.Forsyth continue;
117*74a4d8c2SCharles.Forsyth }
118*74a4d8c2SCharles.Forsyth sprint(buf, "%s(%s)", ar, n);
119*74a4d8c2SCharles.Forsyth symlook(strdup(buf), S_TIME, (void *)t)->value = (void *)t;
120*74a4d8c2SCharles.Forsyth t = atol(h.size);
121*74a4d8c2SCharles.Forsyth if(t&01) t++;
122*74a4d8c2SCharles.Forsyth LSEEK(fd, t, 1);
123*74a4d8c2SCharles.Forsyth }
124*74a4d8c2SCharles.Forsyth close(fd);
125*74a4d8c2SCharles.Forsyth }
126*74a4d8c2SCharles.Forsyth
127*74a4d8c2SCharles.Forsyth static int
type(char * file)128*74a4d8c2SCharles.Forsyth type(char *file)
129*74a4d8c2SCharles.Forsyth {
130*74a4d8c2SCharles.Forsyth int fd;
131*74a4d8c2SCharles.Forsyth char buf[SARMAG];
132*74a4d8c2SCharles.Forsyth
133*74a4d8c2SCharles.Forsyth fd = open(file, OREAD);
134*74a4d8c2SCharles.Forsyth if(fd < 0){
135*74a4d8c2SCharles.Forsyth if(symlook(file, S_BITCH, 0) == 0){
136*74a4d8c2SCharles.Forsyth Bprint(&bout, "%s doesn't exist: assuming it will be an archive\n", file);
137*74a4d8c2SCharles.Forsyth symlook(file, S_BITCH, (void *)file);
138*74a4d8c2SCharles.Forsyth }
139*74a4d8c2SCharles.Forsyth return 1;
140*74a4d8c2SCharles.Forsyth }
141*74a4d8c2SCharles.Forsyth if(read(fd, buf, SARMAG) != SARMAG){
142*74a4d8c2SCharles.Forsyth close(fd);
143*74a4d8c2SCharles.Forsyth return 0;
144*74a4d8c2SCharles.Forsyth }
145*74a4d8c2SCharles.Forsyth close(fd);
146*74a4d8c2SCharles.Forsyth return !strncmp(ARMAG, buf, SARMAG);
147*74a4d8c2SCharles.Forsyth }
148*74a4d8c2SCharles.Forsyth
149*74a4d8c2SCharles.Forsyth static char*
split(char * name,char ** member)150*74a4d8c2SCharles.Forsyth split(char *name, char **member)
151*74a4d8c2SCharles.Forsyth {
152*74a4d8c2SCharles.Forsyth char *p, *q;
153*74a4d8c2SCharles.Forsyth
154*74a4d8c2SCharles.Forsyth p = strdup(name);
155*74a4d8c2SCharles.Forsyth q = utfrune(p, '(');
156*74a4d8c2SCharles.Forsyth if(q){
157*74a4d8c2SCharles.Forsyth *q++ = 0;
158*74a4d8c2SCharles.Forsyth if(member)
159*74a4d8c2SCharles.Forsyth *member = q;
160*74a4d8c2SCharles.Forsyth q = utfrune(q, ')');
161*74a4d8c2SCharles.Forsyth if (q)
162*74a4d8c2SCharles.Forsyth *q = 0;
163*74a4d8c2SCharles.Forsyth if(type(p))
164*74a4d8c2SCharles.Forsyth return p;
165*74a4d8c2SCharles.Forsyth free(p);
166*74a4d8c2SCharles.Forsyth fprint(2, "mk: '%s' is not an archive\n", name);
167*74a4d8c2SCharles.Forsyth }
168*74a4d8c2SCharles.Forsyth return 0;
169*74a4d8c2SCharles.Forsyth }
170