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