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