Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/pax/pax-ar.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1987-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
* *
19
***********************************************************************/
20
#pragma prototyped
21
22
/*
23
* pax ar library format
24
*/
25
26
#include "format.h"
27
28
#include <ardir.h>
29
30
typedef struct Ar_s
31
{
32
Ardir_t* dir;
33
Ardirent_t* ent;
34
} Ar_t;
35
36
static int
37
ar_getprologue(Pax_t* pax, Format_t* fp, register Archive_t* ap, register File_t* f, unsigned char* buf, size_t size)
38
{
39
Ar_t* ar;
40
Ardir_t* dir;
41
42
if (!(dir = ardiropen(ap->name, NiL, 0)))
43
return 0;
44
if (!(ar = newof(0, Ar_t, 1, 0)))
45
{
46
ardirclose(dir);
47
nospace();
48
return -1;
49
}
50
ap->data = ar;
51
ar->dir = dir;
52
ap->type = (char*)dir->meth->name;
53
return 1;
54
}
55
56
static int
57
ar_done(Pax_t* pax, register Archive_t* ap)
58
{
59
register Ar_t* ar = (Ar_t*)ap->data;
60
61
if (ar)
62
{
63
if (ar->dir)
64
ardirclose(ar->dir);
65
free(ar);
66
ap->data = 0;
67
}
68
return 0;
69
}
70
71
static int
72
ar_getheader(Pax_t* pax, register Archive_t* ap, register File_t* f)
73
{
74
register Ar_t* ar = (Ar_t*)ap->data;
75
off_t pos;
76
77
if (!(ar->ent = ardirnext(ar->dir)))
78
{
79
pos = lseek(ap->io->fd, (off_t)0, SEEK_END);
80
return (pos < 0 || paxseek(pax, ap, pos, SEEK_SET, 0) != pos) ? -1 : 0;
81
}
82
f->name = ar->ent->name;
83
f->st->st_dev = 0;
84
f->st->st_ino = 0;
85
f->st->st_mode = X_IFREG|(ar->ent->mode&X_IPERM);
86
f->st->st_uid = ar->ent->uid;
87
f->st->st_gid = ar->ent->gid;
88
f->st->st_nlink = 1;
89
IDEVICE(f->st, 0);
90
f->st->st_mtime = ar->ent->mtime;
91
f->st->st_size = ar->ent->size;
92
f->linktype = NOLINK;
93
f->linkpath = 0;
94
f->uidname = 0;
95
f->gidname = 0;
96
return 1;
97
}
98
99
static int
100
ar_getdata(Pax_t* pax, register Archive_t* ap, register File_t* f, int wfd)
101
{
102
register Ar_t* ar = (Ar_t*)ap->data;
103
104
if (ar->ent->offset < 0)
105
{
106
error(3, "%s: read not supported for %s format", f->name, ap->format->name);
107
return -1;
108
}
109
if (wfd >= 0)
110
{
111
if (ardircopy(ar->dir, ar->ent, wfd) < 0)
112
{
113
error(ERROR_SYSTEM|2, "%s: copy error", f->name);
114
return -1;
115
}
116
closeout(ap, f, wfd);
117
setfile(ap, f);
118
}
119
return 1;
120
}
121
122
static int
123
ar_getepilogue(Pax_t* pax, Archive_t* ap)
124
{
125
return 1;
126
}
127
128
Format_t pax_ar_format =
129
{
130
"ar",
131
"library",
132
"object library archive",
133
0,
134
ARCHIVE|NOHARDLINKS|IN,
135
0,
136
0,
137
2,
138
PAXNEXT(ar),
139
0,
140
ar_done,
141
ar_getprologue,
142
ar_getheader,
143
ar_getdata,
144
0,
145
ar_getepilogue
146
};
147
148
PAXLIB(ar)
149
150