Use WRBUF for addinfo member of cql_transform_t
[yaz-moved-to-github.git] / client / admin.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
5 #if HAVE_CONFIG_H
6 #include <config.h>
7 #endif
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <time.h>
12 #include <assert.h>
13
14 #if HAVE_DIRENT_H
15 #include <dirent.h>
16 #endif
17 #if HAVE_FNMATCH_H
18 #include <fnmatch.h>
19 #endif
20 #if HAVE_SYS_STAT_H
21 #include <sys/stat.h>
22 #endif
23
24 #include <yaz/yaz-util.h>
25
26 #include <yaz/tcpip.h>
27
28 #include <yaz/proto.h>
29 #include <yaz/marcdisp.h>
30 #include <yaz/diagbib1.h>
31 #include <yaz/oid_db.h>
32 #include <yaz/pquery.h>
33
34 #include "admin.h"
35
36 /* Helper functions to get to various statics in the client */
37 ODR getODROutputStream(void);
38
39 extern char *databaseNames[];
40 extern int num_databaseNames;
41
42 static int sendAdminES(int type, char* param1)
43 {
44     ODR out = getODROutputStream();
45     char *dbname = odr_strdup (out, databaseNames[0]);
46
47     /* Type: 1=reindex, 2=truncate, 3=delete, 4=create, 5=import, 6=refresh, 7=commit */
48     Z_APDU *apdu = zget_APDU(out, Z_APDU_extendedServicesRequest );
49     Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest;
50     Z_External *r;
51     Odr_oid *oid;
52     Z_ESAdminOriginPartToKeep  *toKeep;
53     Z_ESAdminOriginPartNotToKeep  *notToKeep;
54     printf ("Admin request\n");
55     fflush(stdout);
56
57     oid = odr_oiddup(out, yaz_oid_extserv_admin);
58
59     req->packageType = oid;
60     req->packageName = "1.Extendedserveq";
61
62     /* Allocate the external */
63     r = req->taskSpecificParameters = (Z_External *)
64         odr_malloc (out, sizeof(*r));
65     r->direct_reference = odr_oiddup(out,oid);
66     r->indirect_reference = 0;
67     r->descriptor = 0;
68     r->which = Z_External_ESAdmin;
69     r->u.adminService = (Z_Admin *)
70         odr_malloc(out, sizeof(*r->u.adminService));
71     r->u.adminService->which = Z_Admin_esRequest;
72     r->u.adminService->u.esRequest = (Z_AdminEsRequest *)
73         odr_malloc(out, sizeof(*r->u.adminService->u.esRequest));
74
75     toKeep = r->u.adminService->u.esRequest->toKeep =
76         (Z_ESAdminOriginPartToKeep *)
77         odr_malloc(out, sizeof(*r->u.adminService->u.esRequest->toKeep));
78
79     toKeep->which=type;
80     toKeep->databaseName = dbname;
81     switch ( type )
82     {
83     case Z_ESAdminOriginPartToKeep_reIndex:
84         toKeep->u.reIndex=odr_nullval();
85         break;
86
87     case Z_ESAdminOriginPartToKeep_truncate:
88         toKeep->u.truncate=odr_nullval();
89         break;
90     case Z_ESAdminOriginPartToKeep_drop:
91         toKeep->u.drop=odr_nullval();
92         break;
93     case Z_ESAdminOriginPartToKeep_create:
94         toKeep->u.create=odr_nullval();
95         break;
96     case Z_ESAdminOriginPartToKeep_import:
97         toKeep->u.import = (Z_ImportParameters*)
98             odr_malloc(out, sizeof(*toKeep->u.import));
99         toKeep->u.import->recordType=param1;
100         /* Need to add additional setup of records here */
101         break;
102     case Z_ESAdminOriginPartToKeep_refresh:
103         toKeep->u.refresh=odr_nullval();
104         break;
105     case Z_ESAdminOriginPartToKeep_commit:
106         toKeep->u.commit=odr_nullval();
107         break;
108     case Z_ESAdminOriginPartToKeep_shutdown:
109         toKeep->u.commit=odr_nullval();
110         break;
111     case Z_ESAdminOriginPartToKeep_start:
112         toKeep->u.commit=odr_nullval();
113         break;
114     default:
115         /* Unknown admin service */
116         break;
117     }
118
119     notToKeep = r->u.adminService->u.esRequest->notToKeep =
120         (Z_ESAdminOriginPartNotToKeep *)
121         odr_malloc(out, sizeof(*r->u.adminService->u.esRequest->notToKeep));
122     notToKeep->which=Z_ESAdminOriginPartNotToKeep_recordsWillFollow;
123     notToKeep->u.recordsWillFollow=odr_nullval();
124
125     send_apdu(apdu);
126
127     return 0;
128 }
129
130 /* cmd_adm_reindex
131    Ask the specified database to fully reindex itself */
132 int cmd_adm_reindex(const char *arg)
133 {
134     sendAdminES(Z_ESAdminOriginPartToKeep_reIndex, NULL);
135     return 2;
136 }
137
138 /* cmd_adm_truncate
139    Truncate the specified database, removing all records and index entries, but leaving
140    the database & it's explain information intact ready for new records */
141 int cmd_adm_truncate(const char *arg)
142 {
143     if ( arg )
144     {
145         sendAdminES(Z_ESAdminOriginPartToKeep_truncate, NULL);
146         return 2;
147     }
148     return 0;
149 }
150
151 /* cmd_adm_create
152    Create a new database */
153 int cmd_adm_create(const char *arg)
154 {
155     if ( arg )
156     {
157         sendAdminES(Z_ESAdminOriginPartToKeep_create, NULL);
158         return 2;
159     }
160     return 0;
161 }
162
163 /* cmd_adm_drop
164    Drop (Delete) a database */
165 int cmd_adm_drop(const char *arg)
166 {
167     if ( arg )
168     {
169         sendAdminES(Z_ESAdminOriginPartToKeep_drop, NULL);
170         return 2;
171     }
172     return 0;
173 }
174
175 /* cmd_adm_import <dbname> <rectype> <sourcefile>
176    Import the specified updated into the database
177    N.B. That in this case, the import may contain instructions to delete records as well as new or updates
178    to existing records */
179
180 #if HAVE_FNMATCH_H
181 int cmd_adm_import(const char *arg)
182 {
183     char type_str[20], dir_str[1024], pattern_str[1024];
184     char *cp;
185     char *sep = "/";
186     DIR *dir;
187     struct dirent *ent;
188     int chunk = 10;
189     Z_APDU *apdu = 0;
190     Z_Segment *segment = 0;
191     ODR out = getODROutputStream();
192
193     if (arg && sscanf (arg, "%19s %1023s %1023s", type_str,
194                        dir_str, pattern_str) != 3)
195         return 0;
196     if (num_databaseNames != 1)
197         return 0;
198     dir = opendir(dir_str);
199     if (!dir)
200         return 0;
201
202     sendAdminES(Z_ESAdminOriginPartToKeep_import, type_str);
203
204     printf ("sent es request\n");
205     if ((cp=strrchr(dir_str, '/')) && cp[1] == 0)
206         sep="";
207
208     while ((ent = readdir(dir)))
209     {
210         if (fnmatch (pattern_str, ent->d_name, 0) == 0)
211         {
212             char fname[1024];
213             struct stat status;
214             FILE *inf;
215
216             sprintf (fname, "%s%s%s", dir_str, sep, ent->d_name);
217             stat (fname, &status);
218
219             if (S_ISREG(status.st_mode) && (inf = fopen(fname, "r")))
220             {
221                 Z_NamePlusRecord *rec;
222                 Odr_oct *oct = (Odr_oct *) odr_malloc (out, sizeof(*oct));
223
224                 if (!apdu)
225                 {
226                     apdu = zget_APDU(out, Z_APDU_segmentRequest);
227                     segment = apdu->u.segmentRequest;
228                     segment->segmentRecords = (Z_NamePlusRecord **)
229                         odr_malloc (out, chunk * sizeof(*segment->segmentRecords));
230                 }
231                 rec = (Z_NamePlusRecord *) odr_malloc (out, sizeof(*rec));
232                 rec->databaseName = 0;
233                 rec->which = Z_NamePlusRecord_intermediateFragment;
234                 rec->u.intermediateFragment = (Z_FragmentSyntax *)
235                     odr_malloc (out, sizeof(*rec->u.intermediateFragment));
236                 rec->u.intermediateFragment->which =
237                     Z_FragmentSyntax_notExternallyTagged;
238                 rec->u.intermediateFragment->u.notExternallyTagged = oct;
239
240                 oct->len = status.st_size;
241                 oct->buf = (char *) odr_malloc (out, oct->len);
242                 if (fread(oct->buf, 1, oct->len, inf) != (size_t) oct->len)
243                 {
244                     printf("Incomplete read of file %s\n", fname);
245                 }
246                 if (fclose(inf))
247                 {
248                     printf("Close failed for file %s\n", fname);
249                 }
250
251                 segment->segmentRecords[segment->num_segmentRecords++] = rec;
252
253                 if (segment->num_segmentRecords == chunk)
254                 {
255                     send_apdu (apdu);
256                     apdu = 0;
257                 }
258             }
259         }
260     }
261     if (apdu)
262         send_apdu(apdu);
263     apdu = zget_APDU(out, Z_APDU_segmentRequest);
264     send_apdu (apdu);
265     closedir(dir);
266     return 2;
267 }
268 #else
269 int cmd_adm_import(const char *arg)
270 {
271     printf ("not available on WIN32\n");
272     return 0;
273 }
274 #endif
275
276
277 /* "Freshen" the specified database, by checking metadata records against the sources from which they were
278    generated, and creating a new record if the source has been touched since the last extraction */
279 int cmd_adm_refresh(const char *arg)
280 {
281     if ( arg )
282     {
283         sendAdminES(Z_ESAdminOriginPartToKeep_refresh, NULL);
284         return 2;
285     }
286     return 0;
287 }
288
289 /* cmd_adm_commit
290    Make imported records a permenant & visible to the live system */
291 int cmd_adm_commit(const char *arg)
292 {
293     sendAdminES(Z_ESAdminOriginPartToKeep_commit, NULL);
294     return 2;
295 }
296
297 int cmd_adm_shutdown(const char *arg)
298 {
299     sendAdminES(Z_ESAdminOriginPartToKeep_shutdown, NULL);
300     return 2;
301 }
302
303 int cmd_adm_startup(const char *arg)
304 {
305     sendAdminES(Z_ESAdminOriginPartToKeep_start, NULL);
306     return 2;
307 }
308 /*
309  * Local variables:
310  * c-basic-offset: 4
311  * c-file-style: "Stroustrup"
312  * indent-tabs-mode: nil
313  * End:
314  * vim: shiftwidth=4 tabstop=8 expandtab
315  */
316