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, (char *)&h, sizeof(h)) == sizeof(h)){ 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-sizeof(h); /* 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, (char *)&h, sizeof(h)) == sizeof(h)){ 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 } 167