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