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