Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libardir/ar-s5r0.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 2002-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* *
20
***********************************************************************/
21
#pragma prototyped
22
/*
23
* s5r0 archive format method
24
*/
25
26
#include <ardirlib.h>
27
#include <swap.h>
28
#include <tm.h>
29
30
#define MAGIC "<ar>"
31
#define MAGIC_SIZE 4
32
33
typedef struct Header_s
34
{
35
char ar_magic[MAGIC_SIZE]; /* MAGIC */
36
char ar_name[16];
37
char ar_date[4]; /* swapget() accessed */
38
char ar_syms[4]; /* " */
39
} Header_t;
40
41
typedef struct Member_s
42
{
43
char arf_name[16];
44
char arf_date[4]; /* swapget() accessed */
45
char arf_uid[4]; /* " */
46
char arf_gid[4]; /* " */
47
char arf_mode[4]; /* " */
48
char arf_size[4]; /* " */
49
} Member_t;
50
51
typedef struct Symbol_s
52
{
53
char sym_name[8]; /* ' ' terminated */
54
char sym_ptr[4]; /* swapget() accessed */
55
} Symbol_t;
56
57
typedef struct State_s /* method state */
58
{
59
off_t current; /* current dirent offset */
60
off_t offset; /* next dirent offset */
61
off_t patch; /* symdir time patch offset */
62
int swap; /* swapget() op if necessary */
63
int touch; /* touch symbol table time */
64
Member_t member; /* current member */
65
} State_t;
66
67
/*
68
* closef
69
*/
70
71
static int
72
s5r0close(Ardir_t* ar)
73
{
74
State_t* state;
75
int r;
76
Header_t header;
77
78
if (!ar || !(state = (State_t*)ar->data))
79
r = -1;
80
else
81
{
82
r = 0;
83
if (state->touch && state->patch >= 0)
84
{
85
if (lseek(ar->fd, state->patch, SEEK_SET) != state->patch)
86
r = -1;
87
else
88
{
89
swapput(0, (char*)&header.ar_date, sizeof(header.ar_date), (intmax_t)((unsigned long)time((time_t*)0) + 5));
90
if (write(ar->fd, &header.ar_date, sizeof(header.ar_date)) != sizeof(header.ar_date))
91
r = -1;
92
}
93
}
94
free(state);
95
}
96
return r;
97
}
98
99
/*
100
* openf
101
*/
102
103
static int
104
s5r0open(Ardir_t* ar, char* buf, size_t n)
105
{
106
Header_t* hdr;
107
State_t* state;
108
109
if (n <= sizeof(Header_t))
110
return -1;
111
hdr = (Header_t*)buf;
112
if (memcmp(hdr->ar_magic, MAGIC, MAGIC_SIZE))
113
return -1;
114
if (!(state = newof(0, State_t, 1, 0)))
115
return -1;
116
ar->data = (void*)state;
117
state->patch = offsetof(Header_t, ar_date);
118
state->offset = sizeof(Header_t) + swapget(0, hdr->ar_syms, sizeof(hdr->ar_syms)) * sizeof(Symbol_t);
119
ar->truncate = 15;
120
return 0;
121
}
122
123
/*
124
* nextf
125
*/
126
127
static Ardirent_t*
128
s5r0next(Ardir_t* ar)
129
{
130
State_t* state = (State_t*)ar->data;
131
ssize_t z;
132
133
state->current = state->offset;
134
if (lseek(ar->fd, state->offset, SEEK_SET) != state->offset)
135
{
136
ar->error = errno;
137
return 0;
138
}
139
if (read(ar->fd, (char*)&state->member, sizeof(state->member)) != sizeof(state->member))
140
{
141
if ((z = read(ar->fd, (char*)&state->member, 1)) < 0)
142
ar->error = errno;
143
else if (z > 0)
144
ar->error = EINVAL;
145
return 0;
146
147
}
148
ar->dirent.name = state->member.arf_name;
149
ar->dirent.mtime = swapget(0, (char*)&state->member.arf_date, sizeof(state->member.arf_date));
150
ar->dirent.uid = swapget(0, (char*)&state->member.arf_uid, sizeof(state->member.arf_uid));
151
ar->dirent.gid = swapget(0, (char*)&state->member.arf_gid, sizeof(state->member.arf_gid));
152
ar->dirent.mode = swapget(0, (char*)&state->member.arf_mode, sizeof(state->member.arf_mode));
153
ar->dirent.offset = state->offset += sizeof(state->member);
154
ar->dirent.size = swapget(0, (char*)&state->member.arf_size, sizeof(state->member.arf_size));
155
state->offset += ar->dirent.size + (ar->dirent.size & 01);
156
return &ar->dirent;
157
}
158
159
/*
160
* changef
161
*/
162
163
static int
164
s5r0change(Ardir_t* ar, Ardirent_t* ent)
165
{
166
State_t* state = (State_t*)ar->data;
167
off_t o;
168
169
o = state->current + offsetof(Member_t, arf_date);
170
if (lseek(ar->fd, o, SEEK_SET) != o)
171
{
172
ar->error = errno;
173
return -1;
174
}
175
swapput(0, (char*)&state->member.arf_date, sizeof(state->member.arf_date), (intmax_t)ent->mtime);
176
if (write(ar->fd, &state->member.arf_date, sizeof(state->member.arf_date)) != sizeof(state->member.arf_date))
177
{
178
ar->error = errno;
179
return -1;
180
}
181
state->touch = 1;
182
return 0;
183
}
184
185
Ardirmeth_t ar_s5r0 =
186
{
187
"s5r0",
188
"system V release 0 archive",
189
s5r0open,
190
s5r0next,
191
s5r0change,
192
0,
193
0,
194
s5r0close,
195
ar_s5r0_next
196
};
197
198