Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include	"mk.h"
2
#include	<ar.h>
3
 
4
static void atimes(char *);
5
static char *split(char*, char**);
6
 
7
ulong
8
atimeof(int force, char *name)
9
{
10
	Symtab *sym;
11
	ulong 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
	ulong 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, SAR_HDR) == SAR_HDR){
105
		t = strtoul(h.date, nil, 0);
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) == 0;
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
}