Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libardir/ar-local.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
* local archive format method
24
*/
25
26
#include <ardirlib.h>
27
#include <ctype.h>
28
#include <tm.h>
29
30
#define SYMDIR_local "(._|_.|__.|___|*/)*"
31
32
typedef struct State_s /* method state */
33
{
34
Sfio_t* sp; /* sfpopen() stream */
35
unsigned long count; /* member count */
36
} State_t;
37
38
/*
39
* closef
40
*/
41
42
static int
43
localclose(Ardir_t* ar)
44
{
45
State_t* state;
46
int r;
47
48
if (!ar || !(state = (State_t*)ar->data))
49
r = -1;
50
else
51
{
52
if (!state->sp || sfclose(state->sp))
53
r = -1;
54
else
55
r = 0;
56
free(state);
57
}
58
return r;
59
}
60
61
/*
62
* openf
63
*/
64
65
static int
66
localopen(Ardir_t* ar, char* buf, size_t n)
67
{
68
State_t* state;
69
char* cmd;
70
int c;
71
72
if (!(ar->flags & ARDIR_LOCAL))
73
return -1;
74
if (!(state = newof(0, State_t, 1, 0)))
75
return -1;
76
ar->data = (void*)state;
77
cmd = sfprints("${ARDIR:-ar} ${ARDIRFLAGS:-tv} '%s' 2>/dev/null", ar->path);
78
if (!(state->sp = sfpopen(NiL, cmd, "r")) || (c = sfgetc(state->sp)) == EOF || sfungetc(state->sp, c) == EOF)
79
{
80
localclose(ar);
81
return -1;
82
}
83
return 0;
84
}
85
86
/*
87
* nextf
88
*/
89
90
static Ardirent_t*
91
localnext(Ardir_t* ar)
92
{
93
State_t* state = (State_t*)ar->data;
94
register char* s;
95
register char* t;
96
char* e;
97
int n;
98
99
while (s = sfgetr(state->sp, '\n', 1))
100
{
101
/*
102
* assume ``junk Mmm ... member''
103
*/
104
105
if (!(t = strrchr(s, ' ')))
106
continue;
107
*t++ = 0;
108
if (state->count++ || !strmatch(t, SYMDIR_local))
109
while (s = strchr(s, ' '))
110
{
111
if (isupper(*++s) && islower(s[1]) && islower(s[2]) && s[3] == ' ')
112
{
113
ar->dirent.mtime = tmdate(s, &e, NiL);
114
if (!*e)
115
{
116
if ((n = strlen(t)) > ar->truncate)
117
ar->truncate = n;
118
break;
119
}
120
}
121
else
122
ar->dirent.size = strtoul(s, NiL, 10);
123
}
124
ar->dirent.name = t;
125
ar->dirent.uid = ar->st.st_uid;
126
ar->dirent.gid = ar->st.st_gid;
127
ar->dirent.mode = ar->st.st_mode;
128
ar->dirent.offset = -1;
129
return &ar->dirent;
130
}
131
if (sferror(state->sp))
132
ar->error = errno;
133
return 0;
134
}
135
136
Ardirmeth_t ar_local =
137
{
138
"local",
139
"local ar archive",
140
localopen,
141
localnext,
142
0,
143
0,
144
0,
145
localclose,
146
ar_local_next
147
};
148
149