Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/kshlib/dbm/dbm.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 2007-2012 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
* first hack dbm plugin
23
*/
24
25
#include <ast.h>
26
#include <cmd.h>
27
#include <error.h>
28
#include <ast_ndbm.h>
29
30
typedef struct State_s
31
{
32
DBM* dbm;
33
char* path;
34
int scanning;
35
} State_t;
36
37
#define DB_EXCLUSIVE 1
38
#define DB_READ 2
39
#define DB_WRITE 4
40
41
static State_t state;
42
43
#if defined(__EXPORT__)
44
#define extern __EXPORT__
45
#endif
46
47
static const char dbm_open_usage[] =
48
"[-?@(#)$Id: dbm_open (AT&T Research) 2007-09-26 $\n]"
49
USAGE_LICENSE
50
"[+NAME?dbm_open - open dbm file]"
51
"[e:exclusive?Open for exclusive access.]"
52
"[r:read?Open for read.]"
53
"[w:write?Open for write. If \b--read\b is not specified "
54
"then the dbm file is truncated.]"
55
"\n"
56
"\npath\n"
57
"\n"
58
"[+EXIT STATUS]"
59
"{"
60
"[+0?Successful completion.]"
61
"[+>0?An error occurred.]"
62
"}"
63
"[+SEE ALSO?\bdbm_close\b(1), \bdbm_get\b(1), \bdbm_set\b(1), \bdbm\b(3)]"
64
;
65
66
extern int
67
b_dbm_open(int argc, char** argv, Shbltin_t* context)
68
{
69
int flags = 0;
70
71
cmdinit(argc, argv, context, ERROR_CATALOG, ERROR_NOTIFY);
72
#if _use_ndbm
73
if (state.dbm)
74
{
75
dbm_close(state.dbm);
76
state.dbm = 0;
77
}
78
for (;;)
79
{
80
switch (optget(argv, dbm_open_usage))
81
{
82
case 'e':
83
flags |= DB_EXCLUSIVE;
84
continue;
85
case 'r':
86
flags |= DB_READ;
87
continue;
88
case 'w':
89
flags |= DB_WRITE;
90
continue;
91
case '?':
92
error(ERROR_USAGE|4, "%s", opt_info.arg);
93
break;
94
case ':':
95
error(2, "%s", opt_info.arg);
96
break;
97
}
98
break;
99
}
100
argv += opt_info.index;
101
if (error_info.errors || !*argv || *(argv + 1))
102
{
103
error(ERROR_USAGE|2, "%s", optusage(NiL));
104
return 1;
105
}
106
switch (flags & (DB_READ|DB_WRITE))
107
{
108
case DB_READ:
109
flags = O_RDONLY;
110
break;
111
case DB_READ|DB_WRITE:
112
flags = O_RDWR|O_CREAT;
113
break;
114
case DB_WRITE:
115
flags = O_RDWR|O_CREAT|O_TRUNC;
116
break;
117
default:
118
error(3, "one or both of { --read --write } must be specified");
119
return 1;
120
}
121
if (!error_info.errors && !(state.dbm = dbm_open(*argv, flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)))
122
{
123
error(ERROR_SYSTEM|3, "%s: cannot open db", *argv);
124
return 1;
125
}
126
state.scanning = 0;
127
return error_info.errors != 0;
128
#else
129
error(2, "ndbm library required");
130
return 1;
131
#endif
132
}
133
134
static const char dbm_close_usage[] =
135
"[-?@(#)$Id: dbm_close (AT&T Research) 2007-08-26 $\n]"
136
USAGE_LICENSE
137
"[+NAME?dbm_close - close dbm file]"
138
"[+EXIT STATUS]"
139
"{"
140
"[+0?Successful completion.]"
141
"[+>0?An error occurred.]"
142
"}"
143
"[+SEE ALSO?\bdbm_open\b(1), \bdbm_get\b(1), \bdbm_set\b(1), \bdbm\b(3)]"
144
;
145
146
extern int
147
b_dbm_close(int argc, char** argv, Shbltin_t* context)
148
{
149
cmdinit(argc, argv, context, ERROR_CATALOG, ERROR_NOTIFY);
150
#if _use_ndbm
151
for (;;)
152
{
153
switch (optget(argv, dbm_close_usage))
154
{
155
case '?':
156
error(ERROR_USAGE|4, "%s", opt_info.arg);
157
break;
158
case ':':
159
error(2, "%s", opt_info.arg);
160
break;
161
}
162
break;
163
}
164
argv += opt_info.index;
165
if (error_info.errors || *argv)
166
{
167
error(ERROR_USAGE|2, "%s", optusage(NiL));
168
return 1;
169
}
170
if (!error_info.errors)
171
{
172
if (!state.dbm)
173
{
174
error(ERROR_SYSTEM|2, "db not open");
175
return 1;
176
}
177
dbm_close(state.dbm);
178
state.dbm = 0;
179
}
180
return error_info.errors != 0;
181
#else
182
error(2, "ndbm library required");
183
return 1;
184
#endif
185
}
186
187
static const char dbm_get_usage[] =
188
"[-?@(#)$Id: dbm_get (AT&T Research) 2007-08-26 $\n]"
189
USAGE_LICENSE
190
"[+NAME?dbm_get - get value from dbm file]"
191
"[+DESCRIPTION?\bdbm_get\b fetches the value for the \akey\a operand in "
192
"the current \bdbm_open\b file. If \akey\a is omitted then the next "
193
"\akey\a in the current scan is returned.]"
194
"\n"
195
"\n[ key ]\n"
196
"\n"
197
"[+EXIT STATUS]"
198
"{"
199
"[+0?Successful completion.]"
200
"[+1?Data not found or end of scan.]"
201
"[+>1?An error occurred.]"
202
"}"
203
"[+SEE ALSO?\bdbm_open\b(1), \bdbm_close\b(1), \bdbm_set\b(1), \bdbm\b(3)]"
204
;
205
206
extern int
207
b_dbm_get(int argc, char** argv, Shbltin_t* context)
208
{
209
datum key;
210
datum val;
211
int r;
212
213
cmdinit(argc, argv, context, ERROR_CATALOG, ERROR_NOTIFY);
214
#if _use_ndbm
215
for (;;)
216
{
217
switch (optget(argv, dbm_get_usage))
218
{
219
case '?':
220
error(ERROR_USAGE|4, "%s", opt_info.arg);
221
break;
222
case ':':
223
error(2, "%s", opt_info.arg);
224
break;
225
}
226
break;
227
}
228
argv += opt_info.index;
229
if (error_info.errors || (key.dptr = *argv++) && *argv)
230
{
231
error(ERROR_USAGE|2, "%s", optusage(NiL));
232
return 2;
233
}
234
r = 0;
235
if (!state.dbm)
236
{
237
error(ERROR_SYSTEM|2, "db not open");
238
r = 2;
239
}
240
else if (key.dptr)
241
{
242
key.dsize = strlen(key.dptr) + 1;
243
val = dbm_fetch(state.dbm, key);
244
if (val.dptr)
245
sfputr(sfstdout, val.dptr, '\n');
246
else
247
r = 1;
248
}
249
else
250
{
251
if (state.scanning)
252
val = dbm_nextkey(state.dbm);
253
else
254
{
255
state.scanning = 1;
256
val = dbm_firstkey(state.dbm);
257
}
258
if (val.dptr)
259
sfputr(sfstdout, val.dptr, '\n');
260
else
261
{
262
state.scanning = 0;
263
r = 1;
264
}
265
}
266
return r;
267
#else
268
error(2, "ndbm library required");
269
return 1;
270
#endif
271
}
272
273
static const char dbm_set_usage[] =
274
"[-?@(#)$Id: dbm_set (AT&T Research) 2007-08-26 $\n]"
275
USAGE_LICENSE
276
"[+NAME?dbm_set - set value in dbm file]"
277
"[+DESCRIPTION?\bdbm_set\b sets the value for the \akey\a operand in the "
278
"current \bdbm_open\b file to \avalue\a. If \akey\a is omitted then the "
279
"current scan is reset so that \bdbm_get\b with \akey\a omitted will "
280
"return the first key in the implementation defined order. If \avalue\a "
281
"is omitted then \akey\a is deleted.]"
282
"\n"
283
"\n[ key [ value ] ]\n"
284
"\n"
285
"[+EXIT STATUS]"
286
"{"
287
"[+0?Successful completion.]"
288
"[+>0?An error occurred.]"
289
"}"
290
"[+SEE ALSO?\bdbm_open\b(1), \bdbm_close\b(1), \bdbm_get\b(1), \bdbm\b(3)]"
291
;
292
293
extern int
294
b_dbm_set(int argc, char** argv, Shbltin_t* context)
295
{
296
datum key;
297
datum val;
298
int n;
299
300
cmdinit(argc, argv, context, ERROR_CATALOG, ERROR_NOTIFY);
301
#if _use_ndbm
302
for (;;)
303
{
304
switch (optget(argv, dbm_set_usage))
305
{
306
case '?':
307
error(ERROR_USAGE|4, "%s", opt_info.arg);
308
break;
309
case ':':
310
error(2, "%s", opt_info.arg);
311
break;
312
}
313
break;
314
}
315
argv += opt_info.index;
316
if (error_info.errors || (key.dptr = *argv++) && (val.dptr = *argv++) && *argv)
317
{
318
error(ERROR_USAGE|2, "%s", optusage(NiL));
319
return 1;
320
}
321
if (!error_info.errors)
322
{
323
if (!state.dbm)
324
{
325
error(ERROR_SYSTEM|2, "db not open");
326
return 1;
327
}
328
if (!key.dptr)
329
state.scanning = 0;
330
else
331
{
332
key.dsize = strlen(key.dptr) + 1;
333
if (!val.dptr)
334
{
335
if (dbm_delete(state.dbm, key) < 0)
336
{
337
error(ERROR_SYSTEM|2, "db key delete error");
338
return 1;
339
}
340
}
341
else
342
{
343
val.dsize = strlen(val.dptr) + 1;
344
if ((n = dbm_store(state.dbm, key, val, DBM_INSERT)) < 0 || n > 0 && dbm_store(state.dbm, key, val, DBM_REPLACE) < 0)
345
{
346
error(ERROR_SYSTEM|2, "db write error");
347
return 1;
348
}
349
}
350
}
351
}
352
return error_info.errors != 0;
353
#else
354
error(2, "ndbm library required");
355
return 1;
356
#endif
357
}
358
359
SHLIB(dbm)
360
361