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