/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include "mk.h"#include <ar.h> static void atimes(char *);static char *split(char*, char**); ulongatimeof(int force, char *name){ Symtab *sym; ulong t; char *archive, *member, buf[512]; archive = split(name, &member); if(archive == 0) Exit(); t = mtime(archive); sym = symlook(archive, S_AGG, 0); if(sym){ if(force || t > sym->u.value){ atimes(archive); sym->u.value = t; } } else{ atimes(archive); /* mark the aggegate as having been done */ symlook(strdup(archive), S_AGG, "")->u.value = t; } /* truncate long member name to sizeof of name field in archive header */ snprint(buf, sizeof(buf), "%s(%.*s)", archive, utfnlen(member, SARNAME), member); sym = symlook(buf, S_TIME, 0); if (sym) return sym->u.value; return 0;} voidatouch(char *name){ char *archive, *member; int fd, i; struct ar_hdr h; long t; archive = split(name, &member); if(archive == 0) Exit(); fd = open(archive, ORDWR); if(fd < 0){ fd = create(archive, OWRITE, 0666); if(fd < 0){ perror(archive); Exit(); } write(fd, ARMAG, SARMAG); } if(symlook(name, S_TIME, 0)){ /* hoon off and change it in situ */ LSEEK(fd, SARMAG, 0); while(read(fd, (char *)&h, sizeof(h)) == sizeof(h)){ for(i = SARNAME-1; i > 0 && h.name[i] == ' '; i--) ; h.name[i+1]=0; if(strcmp(member, h.name) == 0){ t = SARNAME-sizeof(h); /* ughgghh */ LSEEK(fd, t, 1); fprint(fd, "%-12ld", time(0)); break; } t = atol(h.size); if(t&01) t++; LSEEK(fd, t, 1); } } close(fd);} static voidatimes(char *ar){ struct ar_hdr h; ulong at, t; int fd, i; char buf[BIGBLOCK]; Dir *d; fd = open(ar, OREAD); if(fd < 0) return; if(read(fd, buf, SARMAG) != SARMAG){ close(fd); return; } if((d = dirfstat(fd)) == nil){ close(fd); return; } at = d->mtime; free(d); while(read(fd, (char *)&h, SAR_HDR) == SAR_HDR){ t = strtoul(h.date, nil, 0); if(t >= at) /* new things in old archives confuses mk */ t = at-1; if(t == 0) /* as it sometimes happens; thanks ken */ t = 1; for(i = sizeof(h.name)-1; i > 0 && h.name[i] == ' '; i--) ; if(h.name[i] == '/') /* system V bug */ i--; h.name[i+1]=0; /* can stomp on date field */ snprint(buf, sizeof buf, "%s(%s)", ar, h.name); symlook(strdup(buf), S_TIME, (void*)t)->u.value = t; t = atol(h.size); if(t&01) t++; LSEEK(fd, t, 1); } close(fd);} static inttype(char *file){ int fd; char buf[SARMAG]; fd = open(file, OREAD); if(fd < 0){ if(symlook(file, S_BITCH, 0) == 0){ Bprint(&bout, "%s doesn't exist: assuming it will be an archive\n", file); symlook(file, S_BITCH, (void *)file); } return 1; } if(read(fd, buf, SARMAG) != SARMAG){ close(fd); return 0; } close(fd); return strncmp(ARMAG, buf, SARMAG) == 0;} static char*split(char *name, char **member){ char *p, *q; p = strdup(name); q = utfrune(p, '('); if(q){ *q++ = 0; if(member) *member = q; q = utfrune(q, ')'); if (q) *q = 0; if(type(p)) return p; free(p); fprint(2, "mk: '%s' is not an archive\n", name); } return 0;}
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
#include "mk.h"
#include <ar.h>
static void atimes(char *);
static char *split(char*, char**);
ulong
atimeof(int force, char *name)
{
Symtab *sym;
ulong t;
char *archive, *member, buf[512];
archive = split(name, &member);
if(archive == 0)
Exit();
t = mtime(archive);
sym = symlook(archive, S_AGG, 0);
if(sym){
if(force || t > sym->u.value){
atimes(archive);
sym->u.value = t;
}
}
else{
atimes(archive);
/* mark the aggegate as having been done */
symlook(strdup(archive), S_AGG, "")->u.value = t;
}
/* truncate long member name to sizeof of name field in archive header */
snprint(buf, sizeof(buf), "%s(%.*s)", archive, utfnlen(member, SARNAME), member);
sym = symlook(buf, S_TIME, 0);
if (sym)
return sym->u.value;
return 0;
}
void
atouch(char *name)
{
char *archive, *member;
int fd, i;
struct ar_hdr h;
long t;
archive = split(name, &member);
if(archive == 0)
Exit();
fd = open(archive, ORDWR);
if(fd < 0){
fd = create(archive, OWRITE, 0666);
if(fd < 0){
perror(archive);
Exit();
}
write(fd, ARMAG, SARMAG);
}
if(symlook(name, S_TIME, 0)){
/* hoon off and change it in situ */
LSEEK(fd, SARMAG, 0);
while(read(fd, (char *)&h, sizeof(h)) == sizeof(h)){
for(i = SARNAME-1; i > 0 && h.name[i] == ' '; i--)
;
h.name[i+1]=0;
if(strcmp(member, h.name) == 0){
t = SARNAME-sizeof(h); /* ughgghh */
LSEEK(fd, t, 1);
fprint(fd, "%-12ld", time(0));
break;
}
t = atol(h.size);
if(t&01) t++;
LSEEK(fd, t, 1);
}
}
close(fd);
}
static void
atimes(char *ar)
{
struct ar_hdr h;
ulong at, t;
int fd, i;
char buf[BIGBLOCK];
Dir *d;
fd = open(ar, OREAD);
if(fd < 0)
return;
if(read(fd, buf, SARMAG) != SARMAG){
close(fd);
return;
}
if((d = dirfstat(fd)) == nil){
close(fd);
return;
}
at = d->mtime;
free(d);
while(read(fd, (char *)&h, SAR_HDR) == SAR_HDR){
t = strtoul(h.date, nil, 0);
if(t >= at) /* new things in old archives confuses mk */
t = at-1;
if(t == 0) /* as it sometimes happens; thanks ken */
t = 1;
for(i = sizeof(h.name)-1; i > 0 && h.name[i] == ' '; i--)
;
if(h.name[i] == '/') /* system V bug */
i--;
h.name[i+1]=0; /* can stomp on date field */
snprint(buf, sizeof buf, "%s(%s)", ar, h.name);
symlook(strdup(buf), S_TIME, (void*)t)->u.value = t;
t = atol(h.size);
if(t&01) t++;
LSEEK(fd, t, 1);
}
close(fd);
}
static int
type(char *file)
{
int fd;
char buf[SARMAG];
fd = open(file, OREAD);
if(fd < 0){
if(symlook(file, S_BITCH, 0) == 0){
Bprint(&bout, "%s doesn't exist: assuming it will be an archive\n", file);
symlook(file, S_BITCH, (void *)file);
}
return 1;
}
if(read(fd, buf, SARMAG) != SARMAG){
close(fd);
return 0;
}
close(fd);
return strncmp(ARMAG, buf, SARMAG) == 0;
}
static char*
split(char *name, char **member)
{
char *p, *q;
p = strdup(name);
q = utfrune(p, '(');
if(q){
*q++ = 0;
if(member)
*member = q;
q = utfrune(q, ')');
if (q)
*q = 0;
if(type(p))
return p;
free(p);
fprint(2, "mk: '%s' is not an archive\n", name);
}
return 0;
}