Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libardir/ar-pdp11.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
* pdp11 archive format method
24
*/
25
26
#include <ardirlib.h>
27
#include <swap.h>
28
#include <tm.h>
29
30
#define MAGIC 0177545
31
#define MAGIC_SIZE 2
32
33
typedef struct Header_s
34
{
35
char ar_name[14];
36
uint32_t ar_date; /* native representation*/
37
char ar_uid; /* " */
38
char ar_gid; /* " */
39
uint16_t ar_mode; /* " */
40
uint32_t ar_size; /* " */
41
} Header_t;
42
43
typedef struct State_s /* method state */
44
{
45
off_t current; /* current dirent offset */
46
off_t offset; /* next dirent offset */
47
int swap; /* swapget() op if necessary */
48
Header_t header; /* current header */
49
char name[15]; /* ar_name with trailing '\0' */
50
} State_t;
51
52
/*
53
* closef
54
*/
55
56
static int
57
pdpclose(Ardir_t* ar)
58
{
59
State_t* state;
60
61
if (ar && (state = (State_t*)ar->data))
62
free(state);
63
return 0;
64
}
65
66
/*
67
* openf
68
*/
69
70
static int
71
pdpopen(Ardir_t* ar, char* buf, size_t n)
72
{
73
int swap;
74
State_t* state;
75
76
if (n <= MAGIC_SIZE)
77
return -1;
78
if (swapget(0, buf, MAGIC_SIZE) == MAGIC)
79
swap = 0;
80
else if (swapget(1, buf, MAGIC_SIZE) == MAGIC)
81
swap = 3;
82
else
83
return -1;
84
if (!(state = newof(0, State_t, 1, 0)))
85
return -1;
86
ar->data = (void*)state;
87
state->swap = swap;
88
state->offset = MAGIC_SIZE;
89
ar->truncate = 14;
90
return 0;
91
}
92
93
/*
94
* nextf
95
*/
96
97
static Ardirent_t*
98
pdpnext(Ardir_t* ar)
99
{
100
State_t* state = (State_t*)ar->data;
101
ssize_t z;
102
103
state->current = state->offset;
104
if (lseek(ar->fd, state->offset, SEEK_SET) != state->offset)
105
{
106
ar->error = errno;
107
return 0;
108
}
109
if (read(ar->fd, (char*)&state->header, sizeof(state->header)) != sizeof(state->header))
110
{
111
if ((z = read(ar->fd, (char*)&state->header, 1)) < 0)
112
ar->error = errno;
113
else if (z > 0)
114
ar->error = EINVAL;
115
return 0;
116
117
}
118
strncpy(ar->dirent.name = state->name, state->header.ar_name, sizeof(state->header.ar_name));
119
ar->dirent.mtime = swapget(state->swap, (char*)&state->header.ar_date, sizeof(state->header.ar_date));
120
ar->dirent.uid = swapget(state->swap, (char*)&state->header.ar_uid, sizeof(state->header.ar_uid));
121
ar->dirent.gid = swapget(state->swap, (char*)&state->header.ar_gid, sizeof(state->header.ar_gid));
122
ar->dirent.mode = swapget(state->swap, (char*)&state->header.ar_mode, sizeof(state->header.ar_mode));
123
ar->dirent.offset = state->offset += sizeof(state->header);
124
ar->dirent.size = swapget(state->swap, (char*)&state->header.ar_size, sizeof(state->header.ar_size));
125
state->offset += ar->dirent.size + (ar->dirent.size & 01);
126
return &ar->dirent;
127
}
128
129
/*
130
* changef
131
*/
132
133
static int
134
pdpchange(Ardir_t* ar, Ardirent_t* ent)
135
{
136
State_t* state = (State_t*)ar->data;
137
off_t o;
138
139
o = state->current + offsetof(Header_t, ar_date);
140
if (lseek(ar->fd, o, SEEK_SET) != o)
141
{
142
ar->error = errno;
143
return -1;
144
}
145
swapput(state->swap, (char*)&state->header.ar_date, sizeof(state->header.ar_date), (intmax_t)ent->mtime);
146
if (write(ar->fd, &state->header.ar_date, sizeof(state->header.ar_date)) != sizeof(state->header.ar_date))
147
{
148
ar->error = errno;
149
return -1;
150
}
151
return 0;
152
}
153
154
Ardirmeth_t ar_pdp11 =
155
{
156
"pdp11",
157
"pdp11 archive",
158
pdpopen,
159
pdpnext,
160
pdpchange,
161
0,
162
0,
163
pdpclose,
164
ar_pdp11_next
165
};
166
167