Get rid of size member of Odr_oct
[yaz-moved-to-github.git] / client / admin.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2013 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 #if OCT_SIZE
242                 oct->size = status.st_size;
243 #endif
244                 oct->buf = (unsigned char *) odr_malloc (out, oct->len);
245                 if (fread(oct->buf, 1, oct->len, inf) != (size_t) oct->len)
246                 {
247                     printf("Incomplete read of file %s\n", fname);
248                 }
249                 if (fclose(inf))
250                 {
251                     printf("Close failed for file %s\n", fname);
252                 }
253
254                 segment->segmentRecords[segment->num_segmentRecords++] = rec;
255
256                 if (segment->num_segmentRecords == chunk)
257                 {
258                     send_apdu (apdu);
259                     apdu = 0;
260                 }
261             }
262         }
263     }
264     if (apdu)
265         send_apdu(apdu);
266     apdu = zget_APDU(out, Z_APDU_segmentRequest);
267     send_apdu (apdu);
268     closedir(dir);
269     return 2;
270 }
271 #else
272 int cmd_adm_import(const char *arg)
273 {
274     printf ("not available on WIN32\n");
275     return 0;
276 }
277 #endif
278
279
280 /* "Freshen" the specified database, by checking metadata records against the sources from which they were
281    generated, and creating a new record if the source has been touched since the last extraction */
282 int cmd_adm_refresh(const char *arg)
283 {
284     if ( arg )
285     {
286         sendAdminES(Z_ESAdminOriginPartToKeep_refresh, NULL);
287         return 2;
288     }
289     return 0;
290 }
291
292 /* cmd_adm_commit
293    Make imported records a permenant & visible to the live system */
294 int cmd_adm_commit(const char *arg)
295 {
296     sendAdminES(Z_ESAdminOriginPartToKeep_commit, NULL);
297     return 2;
298 }
299
300 int cmd_adm_shutdown(const char *arg)
301 {
302     sendAdminES(Z_ESAdminOriginPartToKeep_shutdown, NULL);
303     return 2;
304 }
305
306 int cmd_adm_startup(const char *arg)
307 {
308     sendAdminES(Z_ESAdminOriginPartToKeep_start, NULL);
309     return 2;
310 }
311 /*
312  * Local variables:
313  * c-basic-offset: 4
314  * c-file-style: "Stroustrup"
315  * indent-tabs-mode: nil
316  * End:
317  * vim: shiftwidth=4 tabstop=8 expandtab
318  */
319