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