~ubuntu-branches/ubuntu/precise/yazpp/precise

« back to all changes in this revision

Viewing changes to src/yaz-my-client.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Simon
  • Date: 2007-01-22 12:28:56 UTC
  • Revision ID: james.westby@ubuntu.com-20070122122856-b74ahbio5cqcohai
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 1998-2004, Index Data.
 
3
 * See the file LICENSE for details.
 
4
 * 
 
5
 * $Id: yaz-my-client.cpp,v 1.23 2006/03/29 13:14:16 adam Exp $
 
6
 */
 
7
 
 
8
#include <stdlib.h>
 
9
#include <yaz/log.h>
 
10
#include <yaz/options.h>
 
11
#include <yaz/diagbib1.h>
 
12
#include <yaz/marcdisp.h>
 
13
#include <yazpp/ir-assoc.h>
 
14
#include <yazpp/pdu-assoc.h>
 
15
#include <yazpp/socket-manager.h>
 
16
 
 
17
extern "C" {
 
18
#if HAVE_READLINE_READLINE_H
 
19
#include <readline/readline.h>
 
20
#endif
 
21
#if HAVE_READLINE_HISTORY_H
 
22
#include <readline/history.h>
 
23
#endif
 
24
}
 
25
 
 
26
using namespace yazpp_1;
 
27
 
 
28
class YAZ_EXPORT MyClient : public IR_Assoc {
 
29
private:
 
30
    int m_interactive_flag;
 
31
    char m_thisCommand[1024];
 
32
    char m_lastCommand[1024];
 
33
    int m_setOffset;
 
34
    SocketManager *m_socketManager;
 
35
public:
 
36
    MyClient(IPDU_Observable *the_PDU_Observable,
 
37
             SocketManager *the_SocketManager);
 
38
    IPDU_Observer *sessionNotify(
 
39
        IPDU_Observable *the_PDU_Observable, int fd);
 
40
    int args(SocketManager *socketManager, int argc, char **argv);
 
41
    int interactive(SocketManager *socketManager);
 
42
    int wait();
 
43
    void recv_initResponse(Z_InitResponse *initResponse);
 
44
    void recv_searchResponse(Z_SearchResponse *searchResponse);
 
45
    void recv_presentResponse(Z_PresentResponse *presentResponse);
 
46
    void recv_records (Z_Records *records);
 
47
    void recv_diagrecs(Z_DiagRec **pp, int num);
 
48
    void recv_namePlusRecord (Z_NamePlusRecord *zpr, int offset);
 
49
    void recv_record(Z_DatabaseRecord *record, int offset,
 
50
                     const char *databaseName);
 
51
    void recv_textRecord(int type, const char *buf, size_t len);
 
52
    void recv_genericRecord(Z_GenericRecord *r);
 
53
    void display_genericRecord(Z_GenericRecord *r, int level);
 
54
    void display_variant(Z_Variant *v, int level);
 
55
    void connectNotify();
 
56
    void failNotify();
 
57
    void timeoutNotify();
 
58
    char *get_cookie (Z_OtherInformation **oi);
 
59
    int processCommand(const char *cmd);
 
60
    const char *getCommand();
 
61
    int cmd_open(char *host);
 
62
    int cmd_connect(char *host);
 
63
    int cmd_quit(char *args);
 
64
    int cmd_close(char *args);
 
65
    int cmd_find(char *args);
 
66
    int cmd_show(char *args);
 
67
    int cmd_cookie(char *args);
 
68
    int cmd_init(char *args);
 
69
    int cmd_format(char *args);
 
70
    int cmd_proxy(char *args);
 
71
};
 
72
 
 
73
 
 
74
void MyClient::connectNotify()
 
75
{
 
76
    printf ("Connection accepted by target\n");
 
77
    set_lastReceived(-1);
 
78
}
 
79
 
 
80
void MyClient::timeoutNotify()
 
81
{
 
82
    printf ("Connection timeout\n");
 
83
    close();
 
84
}
 
85
 
 
86
void MyClient::failNotify()
 
87
{
 
88
    printf ("Connection closed by target\n");
 
89
    set_lastReceived(-1);
 
90
}
 
91
 
 
92
IPDU_Observer *MyClient::sessionNotify(IPDU_Observable *the_PDU_Observable,
 
93
                                       int fd)
 
94
 
95
    return new MyClient(the_PDU_Observable, m_socketManager);
 
96
}
 
97
 
 
98
MyClient::MyClient(IPDU_Observable *the_PDU_Observable,
 
99
                   SocketManager *the_socketManager) :
 
100
    IR_Assoc (the_PDU_Observable)
 
101
{
 
102
    m_setOffset = 1;
 
103
    m_interactive_flag = 1;
 
104
    m_thisCommand[0] = '\0';
 
105
    m_lastCommand[0] = '\0';
 
106
    m_socketManager = the_socketManager;
 
107
}
 
108
 
 
109
void usage(char *prog)
 
110
{
 
111
    fprintf (stderr, "%s: [-v log] [-c cookie] [-p proxy] [zurl]\n", prog);
 
112
    exit (1);
 
113
}
 
114
 
 
115
char *MyClient::get_cookie(Z_OtherInformation **otherInfo)
 
116
{
 
117
    int oid[OID_SIZE];
 
118
    Z_OtherInformationUnit *oi;
 
119
    struct oident ent;
 
120
    ent.proto = PROTO_Z3950;
 
121
    ent.oclass = CLASS_USERINFO;
 
122
    ent.value = (oid_value) VAL_COOKIE;
 
123
 
 
124
    if (oid_ent_to_oid (&ent, oid) && 
 
125
        (oi = update_otherInformation(otherInfo, 0, oid, 1, 1)) &&
 
126
        oi->which == Z_OtherInfo_characterInfo)
 
127
        return oi->information.characterInfo;
 
128
    return 0;
 
129
}
 
130
 
 
131
void MyClient::recv_initResponse(Z_InitResponse *initResponse)
 
132
{
 
133
    printf ("Got InitResponse. Status ");
 
134
    if (*initResponse->result)
 
135
    {
 
136
        printf ("Ok\n");
 
137
 
 
138
        const char *p = get_cookie (&initResponse->otherInfo);
 
139
        if (p)
 
140
        {
 
141
            printf ("cookie = %s\n", p);
 
142
            set_cookie(p);
 
143
        }
 
144
    }
 
145
    else
 
146
        printf ("Fail\n");
 
147
}
 
148
 
 
149
void MyClient::recv_diagrecs(Z_DiagRec **pp, int num)
 
150
{
 
151
    int i;
 
152
    oident *ent;
 
153
    Z_DefaultDiagFormat *r;
 
154
 
 
155
    printf("Diagnostic message(s) from database:\n");
 
156
    for (i = 0; i<num; i++)
 
157
    {
 
158
        Z_DiagRec *p = pp[i];
 
159
        if (p->which != Z_DiagRec_defaultFormat)
 
160
        {
 
161
            printf("Diagnostic record not in default format.\n");
 
162
            return;
 
163
        }
 
164
        else
 
165
            r = p->u.defaultFormat;
 
166
        if (!(ent = oid_getentbyoid(r->diagnosticSetId)) ||
 
167
            ent->oclass != CLASS_DIAGSET || ent->value != VAL_BIB1)
 
168
            printf("Missing or unknown diagset\n");
 
169
        printf("    [%d] %s", *r->condition, diagbib1_str(*r->condition));
 
170
#ifdef ASN_COMPILED
 
171
        switch (r->which)
 
172
        {
 
173
        case Z_DefaultDiagFormat_v2Addinfo:
 
174
            printf (" -- v2 addinfo '%s'\n", r->u.v2Addinfo);
 
175
            break;
 
176
        case Z_DefaultDiagFormat_v3Addinfo:
 
177
            printf (" -- v3 addinfo '%s'\n", r->u.v3Addinfo);
 
178
            break;
 
179
        }
 
180
#else
 
181
        if (r->addinfo && *r->addinfo)
 
182
            printf(" -- '%s'\n", r->addinfo);
 
183
        else
 
184
            printf("\n");
 
185
#endif
 
186
    }
 
187
}
 
188
 
 
189
void MyClient::recv_textRecord(int type, const char *buf, size_t len)
 
190
{
 
191
    fwrite (buf, 1, len, stdout);
 
192
    fputc ('\n', stdout);
 
193
}
 
194
 
 
195
void MyClient::display_variant(Z_Variant *v, int level)
 
196
{
 
197
    int i;
 
198
 
 
199
    for (i = 0; i < v->num_triples; i++)
 
200
    {
 
201
        printf("%*sclass=%d,type=%d", level * 4, "", *v->triples[i]->zclass,
 
202
            *v->triples[i]->type);
 
203
        if (v->triples[i]->which == Z_Triple_internationalString)
 
204
            printf(",value=%s\n", v->triples[i]->value.internationalString);
 
205
        else
 
206
            printf("\n");
 
207
    }
 
208
}
 
209
 
 
210
void MyClient::display_genericRecord(Z_GenericRecord *r, int level)
 
211
{
 
212
    int i;
 
213
 
 
214
    if (!r)
 
215
        return;
 
216
    for (i = 0; i < r->num_elements; i++)
 
217
    {
 
218
        Z_TaggedElement *t;
 
219
 
 
220
        printf("%*s", level * 4, "");
 
221
        t = r->elements[i];
 
222
        printf("(");
 
223
        if (t->tagType)
 
224
            printf("%d,", *t->tagType);
 
225
        else
 
226
            printf("?,");
 
227
        if (t->tagValue->which == Z_StringOrNumeric_numeric)
 
228
            printf("%d) ", *t->tagValue->u.numeric);
 
229
        else
 
230
            printf("%s) ", t->tagValue->u.string);
 
231
        if (t->content->which == Z_ElementData_subtree)
 
232
        {
 
233
            printf("\n");
 
234
            display_genericRecord(t->content->u.subtree, level+1);
 
235
        }
 
236
        else if (t->content->which == Z_ElementData_string)
 
237
            printf("%s\n", t->content->u.string);
 
238
        else if (t->content->which == Z_ElementData_numeric)
 
239
            printf("%d\n", *t->content->u.numeric);
 
240
        else if (t->content->which == Z_ElementData_oid)
 
241
        {
 
242
            int *ip = t->content->u.oid;
 
243
            oident *oent;
 
244
 
 
245
            if ((oent = oid_getentbyoid(t->content->u.oid)))
 
246
                printf("OID: %s\n", oent->desc);
 
247
            else
 
248
            {
 
249
                printf("{");
 
250
                while (ip && *ip >= 0)
 
251
                    printf(" %d", *(ip++));
 
252
                printf(" }\n");
 
253
            }
 
254
        }
 
255
        else if (t->content->which == Z_ElementData_noDataRequested)
 
256
            printf("[No data requested]\n");
 
257
        else if (t->content->which == Z_ElementData_elementEmpty)
 
258
            printf("[Element empty]\n");
 
259
        else if (t->content->which == Z_ElementData_elementNotThere)
 
260
            printf("[Element not there]\n");
 
261
        else
 
262
            printf("??????\n");
 
263
        if (t->appliedVariant)
 
264
            display_variant(t->appliedVariant, level+1);
 
265
        if (t->metaData && t->metaData->supportedVariants)
 
266
        {
 
267
            int c;
 
268
 
 
269
            printf("%*s---- variant list\n", (level+1)*4, "");
 
270
            for (c = 0; c < t->metaData->num_supportedVariants; c++)
 
271
            {
 
272
                printf("%*svariant #%d\n", (level+1)*4, "", c);
 
273
                display_variant(t->metaData->supportedVariants[c], level + 2);
 
274
            }
 
275
        }
 
276
    }
 
277
}
 
278
 
 
279
void MyClient::recv_genericRecord(Z_GenericRecord *r)
 
280
{
 
281
    display_genericRecord(r, 0);
 
282
}
 
283
 
 
284
void MyClient::recv_record(Z_DatabaseRecord *record, int offset,
 
285
                           const char *databaseName)
 
286
{
 
287
    Z_External *r = (Z_External*) record;
 
288
    oident *ent = oid_getentbyoid(r->direct_reference);
 
289
 
 
290
    /*
 
291
     * Tell the user what we got.
 
292
     */
 
293
    if (r->direct_reference)
 
294
    {
 
295
        printf("Record type: ");
 
296
        if (ent)
 
297
            printf("%s\n", ent->desc);
 
298
    }
 
299
    /* Check if this is a known, ASN.1 type tucked away in an octet string */
 
300
    Z_ext_typeent *etype = z_ext_getentbyref(ent->value);
 
301
    if (ent && (r->which == Z_External_octet || r->which == Z_External_single)
 
302
        && (etype = z_ext_getentbyref(ent->value)))
 
303
 
 
304
    {
 
305
        void *rr;
 
306
        /*
 
307
         * Call the given decoder to process the record.
 
308
         */
 
309
        odr_setbuf(odr_decode(), (char*)record->u.octet_aligned->buf,
 
310
                   record->u.octet_aligned->len, 0);
 
311
        if (!(*etype->fun)(odr_decode(), (char **)&rr, 0, 0))
 
312
        {
 
313
            odr_perror(odr_decode(), "Decoding constructed record.");
 
314
            fprintf(stderr, "[Near %d]\n", odr_offset(odr_decode()));
 
315
            fprintf(stderr, "Packet dump:\n---------\n");
 
316
            odr_dumpBER(stderr, (char*)record->u.octet_aligned->buf,
 
317
                        record->u.octet_aligned->len);
 
318
            fprintf(stderr, "---------\n");
 
319
        }
 
320
        if (etype->what == Z_External_sutrs)
 
321
        {
 
322
            Z_SUTRS *sutrs = (Z_SUTRS *) rr;
 
323
            recv_textRecord ((int) VAL_SUTRS, (const char *) sutrs->buf,
 
324
                             (size_t) sutrs->len);
 
325
        }
 
326
        return;
 
327
    }
 
328
    if (r->which == Z_External_octet && record->u.octet_aligned->len)
 
329
    {
 
330
        switch (ent->value)
 
331
        {
 
332
        case VAL_ISO2709:
 
333
        case VAL_UNIMARC:
 
334
        case VAL_INTERMARC:
 
335
        case VAL_USMARC:
 
336
        case VAL_UKMARC:
 
337
        case VAL_NORMARC:
 
338
        case VAL_LIBRISMARC:
 
339
        case VAL_DANMARC:
 
340
        case VAL_FINMARC:
 
341
        case VAL_MAB:
 
342
        case VAL_CANMARC:
 
343
        case VAL_SBN:
 
344
        case VAL_PICAMARC:
 
345
        case VAL_AUSMARC:
 
346
        case VAL_IBERMARC:
 
347
        case VAL_CATMARC:
 
348
        case VAL_MALMARC:
 
349
        case VAL_JPMARC:
 
350
        case VAL_SWEMARC:
 
351
        case VAL_SIGLEMARC:
 
352
        case VAL_ISDSMARC:
 
353
        case VAL_RUSMARC:
 
354
            marc_display((char*) record->u.octet_aligned->buf,0);
 
355
            break;
 
356
        default:
 
357
            recv_textRecord((int) ent->value,
 
358
                            (const char *) record->u.octet_aligned->buf,
 
359
                            (size_t) record->u.octet_aligned->len);
 
360
        }
 
361
    }
 
362
    else if (ent && ent->value == VAL_SUTRS && r->which == Z_External_sutrs)
 
363
        recv_textRecord((int) VAL_SUTRS, (const char *) r->u.sutrs->buf,
 
364
                        (size_t) r->u.sutrs->len);
 
365
    else if (ent && ent->value == VAL_GRS1 && r->which == Z_External_grs1)
 
366
        recv_genericRecord(r->u.grs1);
 
367
    else 
 
368
    {
 
369
        printf("Unknown record representation.\n");
 
370
        if (!z_External(odr_print(), &r, 0, 0))
 
371
        {
 
372
            odr_perror(odr_print(), "Printing external");
 
373
            odr_reset(odr_print());
 
374
        }
 
375
    }    
 
376
}
 
377
 
 
378
void MyClient::recv_namePlusRecord (Z_NamePlusRecord *zpr, int offset)
 
379
{
 
380
    if (zpr->databaseName)
 
381
        printf("[%s]", zpr->databaseName);
 
382
    if (zpr->which == Z_NamePlusRecord_surrogateDiagnostic)
 
383
        recv_diagrecs(&zpr->u.surrogateDiagnostic, 1);
 
384
    else
 
385
        recv_record(zpr->u.databaseRecord, offset, zpr->databaseName);
 
386
}
 
387
 
 
388
void MyClient::recv_records (Z_Records *records)
 
389
{
 
390
#ifdef ASN_COMPILED
 
391
    Z_DiagRec dr, *dr_p = &dr;
 
392
#endif
 
393
    if (!records)
 
394
        return;
 
395
    int i;
 
396
    switch (records->which)
 
397
    {
 
398
    case Z_Records_DBOSD:
 
399
        for (i = 0; i < records->u.databaseOrSurDiagnostics->num_records; i++)
 
400
            recv_namePlusRecord(records->u.databaseOrSurDiagnostics->
 
401
                                records[i], i + m_setOffset);
 
402
        m_setOffset += records->u.databaseOrSurDiagnostics->num_records;
 
403
        break;
 
404
    case Z_Records_NSD:
 
405
#ifdef ASN_COMPILED
 
406
        dr.which = Z_DiagRec_defaultFormat;
 
407
        dr.u.defaultFormat = records->u.nonSurrogateDiagnostic;
 
408
        recv_diagrecs (&dr_p, 1);
 
409
#else
 
410
        recv_diagrecs (&records->u.nonSurrogateDiagnostic, 1);
 
411
#endif
 
412
        break;
 
413
    case Z_Records_multipleNSD:
 
414
        recv_diagrecs (records->u.multipleNonSurDiagnostics->diagRecs,
 
415
                       records->u.multipleNonSurDiagnostics->num_diagRecs);
 
416
        break;
 
417
    }
 
418
}
 
419
 
 
420
void MyClient::recv_searchResponse(Z_SearchResponse *searchResponse)
 
421
{
 
422
    printf ("Got SearchResponse. Status ");
 
423
    if (!*searchResponse->searchStatus)
 
424
    {
 
425
        printf ("Fail\n");
 
426
    }
 
427
    else
 
428
    {
 
429
        printf ("Ok\n");
 
430
        printf ("Hits: %d\n", *searchResponse->resultCount);
 
431
    }
 
432
    recv_records (searchResponse->records);
 
433
}
 
434
 
 
435
void MyClient::recv_presentResponse(Z_PresentResponse *presentResponse)
 
436
{
 
437
    printf ("Got PresentResponse\n");
 
438
    recv_records (presentResponse->records);
 
439
}
 
440
 
 
441
int MyClient::wait()
 
442
{
 
443
    set_lastReceived(0);
 
444
    while (m_socketManager->processEvent() > 0)
 
445
    {
 
446
        if (get_lastReceived())
 
447
            return 1;
 
448
    }
 
449
    return 0;
 
450
}
 
451
 
 
452
 
 
453
#define C_PROMPT "Z>"
 
454
 
 
455
int MyClient::cmd_connect(char *host)
 
456
{
 
457
    client (host);
 
458
    timeout (10);
 
459
    wait ();
 
460
    timeout (-1);
 
461
    return 1;
 
462
}
 
463
 
 
464
int MyClient::cmd_open(char *host)
 
465
{
 
466
    client (host);
 
467
    timeout (10);
 
468
    wait ();
 
469
    timeout (-1);
 
470
    send_initRequest();
 
471
    wait ();
 
472
    return 1;
 
473
}
 
474
 
 
475
int MyClient::cmd_init(char *args)
 
476
{
 
477
    if (send_initRequest() >= 0)
 
478
        wait();
 
479
    else
 
480
        close();
 
481
    return 1;
 
482
}
 
483
 
 
484
int MyClient::cmd_quit(char *args)
 
485
{
 
486
    return 0;
 
487
}
 
488
 
 
489
int MyClient::cmd_close(char *args)
 
490
{
 
491
    close();
 
492
    return 1;
 
493
}
 
494
 
 
495
int MyClient::cmd_find(char *args)
 
496
{
 
497
    Yaz_Z_Query query;
 
498
 
 
499
    if (query.set_rpn(args) <= 0)
 
500
    {
 
501
        printf ("Bad RPN query\n");
 
502
        return 1;
 
503
    }
 
504
    if (send_searchRequest(&query) >= 0)
 
505
        wait();
 
506
    else
 
507
        printf ("Not connected\n");
 
508
    return 1;
 
509
}
 
510
 
 
511
int MyClient::cmd_show(char *args)
 
512
{
 
513
    int start = m_setOffset, number = 1;
 
514
 
 
515
    sscanf (args, "%d %d", &start, &number);
 
516
    m_setOffset = start;
 
517
    if (send_presentRequest(start, number) >= 0)
 
518
        wait();
 
519
    else
 
520
        printf ("Not connected\n");
 
521
    return 1;
 
522
}
 
523
 
 
524
int MyClient::cmd_cookie(char *args)
 
525
{
 
526
    set_cookie(*args ? args : 0);
 
527
    return 1;
 
528
}
 
529
 
 
530
int MyClient::cmd_format(char *args)
 
531
{
 
532
    set_preferredRecordSyntax(args);
 
533
    return 1;
 
534
}
 
535
 
 
536
int MyClient::cmd_proxy(char *args)
 
537
{
 
538
    set_proxy(args);
 
539
    return 1;
 
540
}
 
541
 
 
542
int MyClient::processCommand(const char *commandLine)
 
543
{
 
544
    char cmdStr[1024], cmdArgs[1024];
 
545
    cmdArgs[0] = '\0';
 
546
    cmdStr[0] = '\0';
 
547
    static struct {
 
548
        const char *cmd;
 
549
        int (MyClient::*fun)(char *arg);
 
550
        const char *ad;
 
551
    } cmd[] = {
 
552
        {"open", &MyClient::cmd_open, "<host>[':'<port>][/<database>]"},
 
553
        {"connect", &MyClient::cmd_connect, "<host>[':'<port>][/<database>]"},
 
554
        {"quit", &MyClient::cmd_quit, ""},
 
555
        {"close", &MyClient::cmd_close, ""},
 
556
        {"find", &MyClient::cmd_find, "<query>"},
 
557
        {"show", &MyClient::cmd_show, "[<start> [<number>]]"},
 
558
        {"cookie", &MyClient::cmd_cookie, "<cookie>"},
 
559
        {"init", &MyClient::cmd_init, ""},
 
560
        {"format", &MyClient::cmd_format, "<record-syntax>"},
 
561
        {"proxy", &MyClient::cmd_proxy, "<host>:[':'<port>]"},
 
562
        {0,0,0}
 
563
    };
 
564
    
 
565
    if (sscanf(commandLine, "%s %[^;]", cmdStr, cmdArgs) < 1)
 
566
        return 1;
 
567
    int i;
 
568
    for (i = 0; cmd[i].cmd; i++)
 
569
        if (!strncmp(cmd[i].cmd, cmdStr, strlen(cmdStr)))
 
570
            break;
 
571
    
 
572
    int res = 1;
 
573
    if (cmd[i].cmd) // Invoke command handler
 
574
        res = (this->*cmd[i].fun)(cmdArgs);
 
575
    else            // Dump help screen
 
576
    {
 
577
        printf("Unknown command: %s.\n", cmdStr);
 
578
        printf("Currently recognized commands:\n");
 
579
        for (i = 0; cmd[i].cmd; i++)
 
580
            printf("   %s %s\n", cmd[i].cmd, cmd[i].ad);
 
581
    }
 
582
    return res;
 
583
}
 
584
 
 
585
const char *MyClient::getCommand()
 
586
{
 
587
#if HAVE_READLINE_READLINE_H
 
588
    // Read using GNU readline
 
589
    char *line_in;
 
590
    line_in=readline(C_PROMPT);
 
591
    if (!line_in)
 
592
        return 0;
 
593
#if HAVE_READLINE_HISTORY_H
 
594
    if (*line_in)
 
595
        add_history(line_in);
 
596
#endif
 
597
    strncpy(m_thisCommand,line_in, 1023);
 
598
    m_thisCommand[1023] = '\0';
 
599
    free (line_in);
 
600
#else    
 
601
    // Read using fgets(3)
 
602
    printf (C_PROMPT);
 
603
    fflush(stdout);
 
604
    if (!fgets(m_thisCommand, 1023, stdin))
 
605
        return 0;
 
606
#endif
 
607
    // Remove trailing whitespace
 
608
    char *cp = m_thisCommand + strlen(m_thisCommand);
 
609
    while (cp != m_thisCommand && strchr("\t \n", cp[-1]))
 
610
        cp--;
 
611
    *cp = '\0';
 
612
    cp = m_thisCommand;
 
613
    // Remove leading spaces...
 
614
    while (*cp && strchr ("\t \n", *cp))
 
615
        cp++;
 
616
    // Save command if non-empty
 
617
    if (*cp != '\0')
 
618
        strcpy (m_lastCommand, cp);
 
619
    return m_lastCommand;
 
620
}
 
621
 
 
622
int MyClient::interactive(SocketManager *socketManager)
 
623
{
 
624
    const char *cmd;
 
625
    if (!m_interactive_flag)
 
626
        return 0;
 
627
    while ((cmd = getCommand()))
 
628
    {
 
629
        if (!processCommand(cmd))
 
630
            break;
 
631
    }
 
632
    return 0;
 
633
}
 
634
 
 
635
int MyClient::args(SocketManager *socketManager, int argc, char **argv)
 
636
{
 
637
    char *host = 0;
 
638
    char *proxy = 0;
 
639
    char *arg;
 
640
    char *prog = argv[0];
 
641
    int ret;
 
642
 
 
643
    while ((ret = options("c:p:v:q", argv, argc, &arg)) != -2)
 
644
    {
 
645
        switch (ret)
 
646
        {
 
647
        case 0:
 
648
            if (host)
 
649
            {
 
650
                usage(prog);
 
651
                return 1;
 
652
            }
 
653
            host = arg;
 
654
            break;
 
655
        case 'p':
 
656
            if (proxy)
 
657
            {
 
658
                usage(prog);
 
659
                return 1;
 
660
            }
 
661
            set_proxy(arg);
 
662
            break;
 
663
        case 'c':
 
664
            set_cookie(arg);
 
665
            break;
 
666
        case 'v':
 
667
            yaz_log_init_level (yaz_log_mask_str(arg));
 
668
            break;
 
669
        case 'q':
 
670
            m_interactive_flag = 0;
 
671
            break;
 
672
        default:
 
673
            usage(prog);
 
674
            return 1;
 
675
        }
 
676
    }
 
677
    if (host)
 
678
    {
 
679
        client (host);
 
680
        timeout (10);
 
681
        wait ();
 
682
        timeout (-1);
 
683
        send_initRequest();
 
684
        wait ();
 
685
    }
 
686
    return 0;
 
687
}
 
688
 
 
689
int main(int argc, char **argv)
 
690
{
 
691
    SocketManager mySocketManager;
 
692
    PDU_Assoc *some = new PDU_Assoc(&mySocketManager);
 
693
 
 
694
    MyClient z(some, &mySocketManager);
 
695
 
 
696
    if (z.args(&mySocketManager, argc, argv))
 
697
        exit (1);
 
698
    if (z.interactive(&mySocketManager))
 
699
        exit (1);
 
700
    return 0;
 
701
}
 
702
/*
 
703
 * Local variables:
 
704
 * c-basic-offset: 4
 
705
 * indent-tabs-mode: nil
 
706
 * End:
 
707
 * vim: shiftwidth=4 tabstop=8 expandtab
 
708
 */
 
709