Statistics
| Branch: | Revision:

napa-baselibs / ALTOclient / ALTOclient.c @ eca395a2

History | View | Annotate | Download (34 KB)

1
/*
2
 ============================================================================
3
 Name        : ALTOclient.c
4
 Author      : T. Ewald <ewald@nw.neclab.eu>
5
 Version     : 243
6
 Proprietary : NEC Europe Ltd. PROPRIETARY INFORMATION
7
                           This software is supplied under the terms of a license
8
                           agreement or nondisclosure agreement with NEC Europe Ltd. and
9
                           may not be copied or disclosed except in accordance with the
10
                           terms of that agreement. The software and its source code
11
                           contain valuable trade secrets and confidential information
12
                           which have to be maintained in confidence.
13
                           Any unauthorized publication, transfer to third parties or
14
                           duplication of the object or source code - either totally or in
15
                           part - is prohibited.
16
 Copyright         : Copyright (c) 2004 NEC Europe Ltd. All Rights Reserved.
17
                           NEC Europe Ltd. DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR
18
                           IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF
19
                           MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND THE
20
                           WARRANTY AGAINST LATENT DEFECTS, WITH RESPECT TO THE PROGRAM
21
                           AND THE ACCOMPANYING DOCUMENTATION.
22
                           No Liability For Consequential Damages IN NO EVENT SHALL NEC
23
                           Europe Ltd., NEC Corporation OR ANY OF ITS SUBSIDIARIES BE
24
                           LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION,
25
                           DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS
26
                           OF INFORMATION, OR OTHER PECUNIARY LOSS AND INDIRECT,
27
                           CONSEQUENTIAL, INCIDENTAL, ECONOMIC OR PUNITIVE DAMAGES) ARISING
28
                           OUT OF THE USE OF OR INABILITY TO USE THIS PROGRAM, EVEN IF NEC
29
                           Europe Ltd. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
30
 Modification: THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
31
 Description : First try of the ALTO client
32
 ============================================================================
33
 */
34

    
35
#include "ALTOclient.h"
36
#include "ALTOclient_impl.h"
37

    
38
#include <stdarg.h>
39
#include <pthread.h>
40

    
41
/*
42
 *                 Here the reference to the accessible DBs is set
43
 */
44
static altoDbPtr ALTO_DB_req = NULL;                // Pointer to the ALTO DB for the Request
45
static altoDbPtr ALTO_DB_res = NULL;                // Pointer to the ALTO DB for the Resposne
46

    
47
static xmlDocPtr ALTO_XML_req = NULL;                // Pointer to the XML for the Request
48
static xmlDocPtr ALTO_XML_res = NULL;                // Pointer to the XML for the Request
49

    
50

    
51
// This is the varaiable where the ALTO server can be found
52
static char alto_server_url[256];
53

    
54
// And this is the struct where the XML buffer for CURL is cached
55
#ifdef USE_CURL
56
static struct curl_reply_buffer_t alto_rep_buf = {ALTO_REP_BUF_SIZE,0,""};
57
#endif
58

    
59
static char alto_reply_buf_nano[ALTO_REP_BUF_SIZE];
60

    
61
static void alto_debugf(const char* str, ...) {
62
        char msg[1024];
63
        va_list args;
64
        va_start(args, str);
65
//#ifdef USE_DEBUG_OUTPUT
66
        vsprintf(msg, str, args);
67
        //printf("[ALTOclient] %s", msg);
68
        fprintf(stderr, "[ALTOclient] %s", msg);
69
//#endif
70
        va_end(args);
71
}
72

    
73
static void alto_errorf(const char* str, ...) {
74
        char msg[1024];
75
        va_list args;
76
        va_start(args, str);
77
        vsprintf(msg, str, args);
78
        fprintf(stderr, "[ALTOclient] *** ERROR: %s", msg);
79
        va_end(args);
80
}
81

    
82
#define assertCheck(expr, msg) if(!(expr)) { alto_errorf("%s - Assertion failed: '"#expr"' (%s, line: %d) -- %s\n", __FUNCTION__, __FILE__, __LINE__, msg); exit(-1); }
83

    
84
#define returnIf(expr, msg, retval) if(expr) { alto_errorf("%s - Condition check: '"#expr"' (%s, line: %d) -- %s\n", __FUNCTION__, __FILE__, __LINE__, msg); return retval; }
85

    
86
/*
87
 *         Function to set the actual ALTO server for configuration
88
 */
89
int set_ALTO_server(char * string){
90
        // Sanity check
91
        returnIf(string == NULL, "Nothing to set here\n", -1);
92

    
93
        strncpy(alto_server_url, string, strlen(string));
94
        return 1;
95
}
96

    
97
/*
98
 *         get the address from the actual set ALTO server;
99
 */
100
char *get_ALTO_server(void){
101
        alto_debugf("%s: The ALTO server is set to: %s \n", __FUNCTION__, alto_server_url);
102
        return (char *) alto_server_url;
103
}
104

    
105

    
106

    
107

    
108

    
109

    
110

    
111

    
112
/*
113
 *         Func:                                        Convert the "Baschtl" notation into a readable
114
 *                                                         format (get IP address)
115
 *         in:                *host_string        Pointer to the string to convert
116
 *         return:        IP                                Struct where the IP and prefix is encoded
117
 */
118
struct in_addr get_ALTO_host_IP(char * host_string){
119
        struct in_addr IP;
120
        #ifdef WIN32
121
        char * str_buff = new char[strlen(host_string)];
122
        #else
123
        char str_buff[strlen(host_string)];
124
        #endif
125
        strncpy(str_buff,host_string,strlen(host_string));
126
        char *result = NULL;
127
        result = strchr(str_buff, '/');
128
        if(result != NULL) {
129
                *result = 0;
130
                IP.s_addr = inet_addr(str_buff);
131
                return IP;
132
        }if(inet_addr(host_string) != (-1)){
133
                IP.s_addr = inet_addr(host_string);
134
                return IP;
135
        }
136
        alto_debugf("%s: No IP found\n!!!", __FUNCTION__);
137
        #ifdef WIN32
138
        delete [] str_buff;
139
        #endif
140
        return IP;
141
}
142

    
143

    
144

    
145

    
146
/*
147
 *         Func:                        Convert the "Baschtl" notation into a readable format
148
 *                                         (get prefix)
149
 *         in:                *host        Pointer to the string to convert
150
 *         return:        port        struct where the IP and prefix is encoded
151
 */
152
int16_t get_ALTO_host_mask(char * host_string){
153
    int16_t res;
154
    char *result = NULL;
155
    char str_buff[256];
156

    
157
    memset(str_buff, 0, 256);
158
    strncpy(str_buff,host_string,strlen(host_string));
159
    result = strchr(str_buff, '/');
160
    if(result != NULL) {
161
        result++;
162
        res = atoi(result);
163
        return res;
164
    }
165
    // if it can't be found, it was a single host so mask is 32 bit
166
    return 32;
167
}
168

    
169

    
170
/*
171
 *  Func:        Create an ALTO XML request from a given DB
172
 *
173
 *  in:                *db                        the pointer to the DB with the elements
174
                        rc_host                the in_addr of the requesting host
175
 *  ret:        XML_doc                the XML where the request is stored in
176
 */
177
xmlDocPtr alto_create_request_XML(struct alto_db_t * db, struct in_addr rc_host, int pri_rat, int sec_rat){
178

    
179
        // Creates a new document
180
        // <?xml version="1.0" encoding="UTF-8"?>
181
        xmlDocPtr doc = NULL;       /* document pointer */
182
        doc = xmlNewDoc(BAD_CAST "1.0");
183

    
184
        // Create the root node and name it with the correct name space
185
        // <alto xmlns='urn:ietf:params:xml:ns:p2p:alto'>
186
        // Dirty!!! Because NS is here an attribute
187
        // [TODO namespace declaration]
188
        xmlNodePtr root_node = NULL;
189
        root_node = xmlNewNode(NULL, BAD_CAST "alto");
190
    xmlNewNs(root_node, BAD_CAST "urn:ietf:params:xml:ns:p2p:alto",NULL);
191

    
192
    // link it to the document
193
    xmlDocSetRootElement(doc, root_node);
194

    
195
    // Creates a DTD declaration. Isn't mandatory.
196
    // [TODO introduce DTDs by time]
197
//        xmlDtdPtr dtd = NULL;       /* DTD pointer */
198
//  dtd = xmlCreateIntSubset(doc, BAD_CAST "root", NULL, BAD_CAST "tree2.dtd");
199

    
200
        // Here create the group rating request (node_GRR)
201
    // <group_rating_request db_version='1234'>\n"
202
    xmlNodePtr node_GRR = NULL;
203
    node_GRR = xmlNewChild(root_node, NULL, BAD_CAST "group_rating_request", NULL);
204
    xmlNewProp(node_GRR, BAD_CAST "db_version", BAD_CAST "1234");
205

    
206
    // Now create the primary rating criteria
207
    // <pri_ratcrit crit='pref'/>
208
    xmlNodePtr node_PRI = NULL;
209
    node_PRI = xmlNewChild(node_GRR, NULL, BAD_CAST "pri_ratcrit", NULL);
210
    if(pri_rat == REL_PREF){
211
            xmlNewProp(node_PRI, BAD_CAST "crit", BAD_CAST "pref");
212
    }else if(pri_rat == TOP_DIST){
213
            xmlNewProp(node_PRI, BAD_CAST "crit", BAD_CAST "dist");
214
    }else if(pri_rat == MIN_BOUN){
215
            xmlNewProp(node_PRI, BAD_CAST "crit", BAD_CAST "lat");
216
    }
217

    
218

    
219
    // Add the additional rating criteria
220
        if((sec_rat & REL_PREF) == REL_PREF){
221
                xmlNodePtr node_SEC1 = NULL;
222
                node_SEC1 = xmlNewChild(node_GRR, NULL, BAD_CAST "fur_ratcrit", NULL);
223
                xmlNewProp(node_SEC1, BAD_CAST "crit", BAD_CAST "pref");
224
        }
225
        if((sec_rat & TOP_DIST) == TOP_DIST){
226
                xmlNodePtr node_SEC2 = NULL;
227
                node_SEC2 = xmlNewChild(node_GRR, NULL, BAD_CAST "fur_ratcrit", NULL);
228
                xmlNewProp(node_SEC2, BAD_CAST "crit", BAD_CAST "dist");
229
        }
230
        if((sec_rat & MIN_BOUN) == MIN_BOUN){
231
                xmlNodePtr node_SEC4 = NULL;
232
                node_SEC4 = xmlNewChild(node_GRR, NULL, BAD_CAST "fur_ratcrit", NULL);
233
                xmlNewProp(node_SEC4, BAD_CAST "crit", BAD_CAST "lat");
234
        }
235

    
236

    
237
    // Now create the source of the request
238
    // <rc_hla><ipprefix version='4' prefix='195.37.70.39/32'/></rc_hla>
239
    xmlNodePtr node_RC_HLA = NULL;
240
    node_RC_HLA = xmlNewChild(node_GRR, NULL, BAD_CAST "rc_hla", NULL);
241

    
242
    // and within the actual source
243
    // <ipprefix version='4' prefix='195.37.70.39/32'/>
244
    xmlNodePtr node_IPP = NULL;
245
    node_IPP = xmlNewChild(node_RC_HLA, NULL, BAD_CAST "ipprefix", NULL);
246
    xmlNewProp(node_IPP, BAD_CAST "version", BAD_CAST "4");
247
//  xmlNewProp(node_IPP, BAD_CAST "prefix", BAD_CAST "195.37.70.39/32");
248
    char rc_host_str[256];
249
    strcpy(rc_host_str, inet_ntoa(rc_host));
250
    // TODO: really dirty, but it should work
251
    strcat(rc_host_str,"/32");
252
    xmlNewProp(node_IPP, BAD_CAST "prefix", BAD_CAST rc_host_str);
253

    
254
    // Now prepare the request
255
    // <cnd_hla>
256
    xmlNodePtr node_HLA = NULL;
257
    node_HLA = xmlNewChild(node_GRR, NULL, BAD_CAST "cnd_hla", NULL);
258

    
259
    // So far it went quite well, now try to create the host list
260
    // from the given ALTO_LIST
261
    // so create something like this:
262
    // <ipprefix version='4' prefix='195.37.70.39/32'/>
263
    char tmp_buff[256];
264
    struct alto_db_element_t * cur;
265
    cur = db->first;
266
    //while(cur->next != NULL){                // armin 12-jul-2010, bug reported by Andrzej
267
    while(cur != NULL){
268
            node_IPP = xmlNewChild(node_HLA, NULL, BAD_CAST "ipprefix", NULL);
269
            xmlNewProp(node_IPP, BAD_CAST "version", BAD_CAST "4");
270
            sprintf(tmp_buff,"%s/%d",inet_ntoa(cur->host), cur->host_mask);
271
            xmlNewProp(node_IPP, BAD_CAST "prefix", BAD_CAST tmp_buff);
272
            cur = cur->next;
273
    }
274

    
275
    // Dump for checking
276
        #ifdef USE_DEBUG_OUTPUT
277
    xmlDocDump(stdout, doc);
278
    #endif
279

    
280

    
281
    // Free the global variables that may have been allocated by the parser.
282
    //xmlCleanupParser(); // armin 22-jul-2010: Should only be done upon exit
283
    // see libxml2 docu
284

    
285
    // return the finsihed XML
286
    return doc;
287
}
288

    
289
/*==================================
290
       libCURL-based POST code
291
  ==================================*/
292

    
293
// libcurl is now obsolete!
294
#ifdef USE_CURL
295

    
296
// this function will be registered with curl as a handler, which
297
// copies the http reply to a the buffer
298
size_t curl_copy_reply_to_buf(void *ptr,size_t size,size_t nmemb,void *stream){
299
    size_t realsize = size * nmemb;
300
    struct curl_reply_buffer_t *crb = (struct curl_reply_buffer_t *)stream;
301
    // error: new chunk plus trailing zero would not fit into remaining buffer
302
    if( (realsize+1) > (crb->size - crb->fill) ) return 0;
303
    memcpy( &crb->buffer[crb->fill], ptr, realsize );
304
    crb->fill += realsize;
305
    crb->buffer[crb->fill] = 0;
306
    return realsize;
307
}
308
uint16_t prefixes = 0;
309

    
310

    
311

    
312
xmlDocPtr query_ALTO_server_curl(xmlDocPtr doc, char* ALTO_server_URL){
313
        xmlDocPtr ALTO_XML_response;
314

    
315
        // starting here the ALTO list will be send out.....
316
        CURL *curl;
317
        CURLcode res;
318
        struct curl_httppost *formpost=NULL;
319
        struct curl_httppost *lastptr=NULL;
320

    
321
        curl = curl_easy_init();
322
        assertCheck(curl, "Couldn't get a handle from curl_easy_init(). abort.");
323

    
324
//        printf("Will send HTTP POST to %s\nwith form data:\n\n%s\n", alto_server_url, ALTO_XML_query);
325

    
326
        // prepare the buffer to be send
327
        xmlChar*  doctxt;
328
        int       doclen;
329
        xmlDocDumpFormatMemoryEnc(doc,&doctxt,&doclen,"utf-8",1);
330

    
331
        // URL that receives this POST
332
        curl_easy_setopt(curl, CURLOPT_URL, ALTO_server_URL);
333

    
334
        // add form data
335
        curl_formadd(&formpost,
336
                                 &lastptr,
337
                                 CURLFORM_COPYNAME, "alto_xml_request",
338
//                                 CURLFORM_COPYCONTENTS, ALTO_XML_query,
339
                                 CURLFORM_COPYCONTENTS, doctxt,
340
                                 CURLFORM_END);
341

    
342
        curl_formadd(&formpost,
343
                             &lastptr,
344
                             CURLFORM_COPYNAME, "action",
345
                             CURLFORM_COPYCONTENTS, "submit",
346
                             CURLFORM_END);
347

    
348
        curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
349

    
350
        // we do not want the reply written to stdout but to our buffer
351
        alto_rep_buf.fill = 0;        // reset buffer (armin 12-jul-2010, reported by Andrzej)
352
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_copy_reply_to_buf);
353
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &alto_rep_buf);
354

    
355
        // do it!
356
        res = curl_easy_perform(curl);
357

    
358
        // always cleanup
359
        curl_easy_cleanup(curl);
360

    
361
        // then cleanup the form post chain
362
        curl_formfree(formpost);
363

    
364
//  printf("result of curl_easy_perform() is: %i\n", res);
365
//  printf("received %i octetts. the buffer is:\n\n%s\nthat's all. bye.\n",alto_rep_buf.fill,alto_rep_buf.buffer);
366

    
367

    
368
        // and last but nor least, transform it into an XML doc
369
        ALTO_XML_response = xmlRecoverMemory(alto_rep_buf.buffer,sizeof(alto_rep_buf.buffer));                // <- for getting XML from memory
370

    
371
        return ALTO_XML_response;
372
}
373

    
374
#endif // USE_CURL
375

    
376
/*==================================
377
   libxml2 nanohttp based POST code
378
  ==================================*/
379

    
380
#define POST_BOUNDARY "---------------------------12408751047121013601852724877"
381

    
382
void POST_add(char* buf, const char* name, const char* value) {
383
        sprintf(buf+strlen(buf), "--"POST_BOUNDARY"\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", name, value);
384
}
385

    
386
void POST_end(char* buf) {
387
        sprintf(buf+strlen(buf), "--"POST_BOUNDARY"--\r\n\r\n");
388
}
389

    
390
void* POST_send(const char* url, const char* data) {
391
        void* ctx;
392
        char header[] = "Connection: close\r\n";
393
        char contentType[512] = "multipart/form-data; boundary="POST_BOUNDARY;
394
        char* ct = contentType;
395

    
396
        //ctx = xmlNanoHTTPMethod(url, "POST", data, &ct, NULL, strlen(data));
397
        ctx = xmlNanoHTTPMethod(url, "POST", data, &ct, header, strlen(data));
398

    
399
        assertCheck(ctx, "xmlNanoHTTPMethod failed! Make sure ALTO server is reachable (NAT issue?)..");
400

    
401
        free(ct);
402
        return ctx;
403
}
404

    
405
// nano
406
xmlDocPtr ALTO_request_to_server(xmlDocPtr doc, char* endPoint){
407
        xmlDocPtr result = NULL;
408
        xmlChar*  doctxt = NULL;
409
        int                size = 0;
410
        int                doclen = 0;
411
        int                bytesRead = 0;
412
        int                bytesSum = 0;
413
        char*        data = NULL;
414
        size_t  dataLen = 0;
415
        void*        ctx = NULL;
416
        char*   alto_reply_buffer_ptr = alto_reply_buf_nano;
417
//        int                errorcode = 0;
418
//        FILE*        f = NULL;
419

    
420
        xmlNanoHTTPInit();
421
        xmlDocDumpFormatMemoryEnc(doc,&doctxt,&doclen,"utf-8",1);
422

    
423
        dataLen = doclen + 2048;
424
        data = malloc(dataLen);
425
        memset(data, 0, dataLen);
426

    
427
        // build the mime multipart contents
428
        POST_add(data, "alto_xml_request", doctxt);
429
        POST_add(data, "action", "submit");
430
        POST_end(data);
431

    
432
        //printf("data:\n\n%s", data);
433
        xmlFree(doctxt);        // free temp buffer
434

    
435
        alto_debugf("%s: POST begin...\n", __FUNCTION__);
436

    
437
        // send it
438
        ctx = POST_send(endPoint, data);
439

    
440
        free(data);
441
        data = NULL;
442

    
443
        alto_debugf("%s: POST ok.\n", __FUNCTION__);
444

    
445
        memset(alto_reply_buf_nano, 0, ALTO_REP_BUF_SIZE);
446

    
447
//        bytesSum = xmlNanoHTTPRead(ctx, &alto_reply_buf_nano, ALTO_REP_BUF_SIZE);
448
        #define BLOCK_SIZE 4096
449
        bytesRead = xmlNanoHTTPRead(ctx, alto_reply_buffer_ptr, BLOCK_SIZE);
450
        bytesSum += bytesRead;
451
        while (bytesRead) {
452
                alto_reply_buffer_ptr += bytesRead;
453
                bytesRead = xmlNanoHTTPRead(ctx, alto_reply_buffer_ptr, BLOCK_SIZE);
454
                bytesSum += bytesRead;
455
        }
456

    
457
        #ifdef USE_DEBUG_OUTPUT
458
//        printf("xmlNanoHTTPRead: %d bytes read.\n", bytesRead);
459
        printf("ALTO reply (%d bytes):\n\n%s", bytesSum, alto_reply_buf_nano);
460
        #endif
461

    
462
        // dump to file
463
/*        f = fopen("http_reply.txt", "wt");
464
        fwrite(output, 1, strlen(output), f);
465
        fclose(f);*/
466

    
467
        result = xmlRecoverMemory(alto_reply_buf_nano, bytesSum);
468
//
469
// TODO: PushParser doesn't work yet somehow..
470
//
471
/*
472
        xmlParserCtxtPtr pushCtx = NULL;
473
        pushCtx = xmlCreatePushParserCtxt(NULL, NULL, output, bytesRead, NULL);
474
//        xmlInitParserCtxt(pushCtx);
475

476
        if (!pushCtx) {
477
                printf("ERROR: xmlCreatePushParserCtxt failed!\n");
478
        } else {
479
                printf("xmlCreatePushParserCtxt ok.\n");
480
        }
481

482
        while (bytesRead) {
483
                if(xmlParseChunk(pushCtx, output, bytesRead, 0) != 0) {
484
                        printf("ERROR: xmlParseChunk failed!\n");
485
                } else {
486
                        printf("xmlParseChunk ok.\n");
487
                }
488
                bytesRead = xmlNanoHTTPRead(ctx,&output,10024);
489
                printf("xmlNanoHTTPRead: %d bytes read.\n", bytesRead);
490
        }
491

492
        printf("Finalizing...\n");
493
        errorcode = xmlParseChunk(pushCtx, output, 0, 1);
494
        if(errorcode) {
495
                printf("ERROR: Final xmlParseChunk failed! errorcode=%d\n", errorcode);
496
        } else {
497
                printf("Final xmlParseChunk ok.\n");
498
        }
499

500
        result = pushCtx->myDoc;
501
        xmlFreeParserCtxt(pushCtx);
502
*/
503

    
504
        if (!result) {
505
                printf("*** ERROR: ALTO XML reply (%d bytes):\n\n%s", bytesSum, alto_reply_buf_nano);
506
                alto_errorf("%s - XML parsing failed (result == NULL)!\n", __FUNCTION__);
507
        } else {
508
                alto_debugf("%s: XML parsing ok.\n", __FUNCTION__);
509
        }
510

    
511
        xmlNanoHTTPClose(ctx);
512
        return result;
513
}
514

    
515

    
516

    
517

    
518
/*
519
 *
520
 *                 HERE is the magic for the internal DB management
521
 *
522
 */
523

    
524
/*
525
 *         Initialize a ALTO DB structure
526
 */
527
struct alto_db_t * alto_db_init(void){
528
        alto_debugf("%s: Initialize an ALTO database! \n", __FUNCTION__);
529
        struct alto_db_t * db;
530
        db = malloc(sizeof(struct alto_db_t));
531
//        db = (alto_db_t *)malloc(sizeof(struct alto_db_element_t));
532
        db->first = NULL;
533
        db->last = NULL;
534
        db->num_of_elements = 0;
535
        return db;
536
}
537

    
538
/*
539
 *  Kill the DB structure
540
 */
541
int alto_free_db(struct alto_db_t * db){
542
        int res = 1;
543
        alto_debugf("%s: Clean and free ALTO database (%p)! \n", __FUNCTION__, db);
544
        returnIf(db == NULL, "No DB to be free'd.", -1);
545

    
546
        res = alto_purge_db(db);
547

    
548
        // Free the DB struct & Goodby!
549
        free(db);
550
        return res;
551
}
552

    
553
/*
554
 *  Clean/Remove all elements from the DB structure
555
 */
556
int alto_purge_db(struct alto_db_t * db){
557
//        alto_debugf("%s: Purge the ALTO database (%p)! \n", __FUNCTION__, db);
558
        returnIf(db == NULL, "No DB to be purged.", -1);
559

    
560
        // Now kill every single element
561
        struct alto_db_element_t * cur;
562
        cur = db->first;
563
        while(cur != NULL){
564
                alto_rem_element(cur);
565
                cur = db->first; //cur->next;        // armin 12-jul-2010, bug reported by Andrzej
566
        }
567

    
568
        return 1;
569
}
570

    
571

    
572

    
573
/*
574
 *         Helper function to print values of one ALTO DB element
575
 */
576
void alto_dump_element(struct alto_db_element_t * cur){
577
        // Sanity check
578
        assertCheck(cur == NULL, "No element to print values from! ABORT");
579

    
580
        // normal case, print everything
581
//        fprintf(stdout, "---> Internal Data\t");
582
//        fprintf(stdout, "Element ptr  : %p \t", cur);
583
//        fprintf(stdout, "DB   pointer : %p \t", cur->alto_db);
584
//        fprintf(stdout, "next pointer : %p \t", cur->next);
585
//        fprintf(stdout, "prev pointer : %p \t", cur->prev);
586
        alto_debugf("---> User Data\t");
587
        alto_debugf("host  : %s \t", inet_ntoa(cur->host));
588
        alto_debugf("prefix: %d \t", cur->host_mask);
589
        alto_debugf("rating: %d \t", cur->rating);
590
//        fprintf(stdout, "---> Additional Data\n");
591
//        fprintf(stdout, "Subnet       : %s \t", inet_ntoa(cur->subnet));
592
//        fprintf(stdout, "bit mask     : %d \t", cur->subnet_mask);
593
        alto_debugf("\n");
594
        return;
595
}
596

    
597
/*
598
 *         Helper function to print values of one ALTO DB element
599
 */
600
void alto_dump_db(struct alto_db_t *db){
601
        alto_debugf("Dump what's in the DB \n");
602

    
603
        // Security Check
604
        assertCheck(db, "Failure in DB structure! ABORT");
605

    
606
        // General Data
607
        alto_debugf("Number of elements in DB: %d \n", db->num_of_elements);
608
        alto_debugf("DB->first: %p \n", db->first);
609
        alto_debugf("DB->last:  %p \n", db->last);
610

    
611
        // List the elements
612
    struct alto_db_element_t * cur;
613
    cur = db->first;
614
    while(cur != NULL){
615
            alto_dump_element(cur);
616
            cur = cur->next;
617
    }
618

    
619
    // Success!?
620
        return;
621
}
622

    
623

    
624

    
625

    
626
/*
627
 *  Adds one ALTO entry to the DB
628
 */
629
int alto_add_element(struct alto_db_t * db, struct alto_db_element_t * element){
630
//        fprintf(stdout, "Add an element to the ALTO DB! \n");
631

    
632
        // Error handling
633
        returnIf((db == NULL || element == NULL), "Error in appending element on the DB! ABORT", -1);
634

    
635
        // Special case, first element in DB
636
        if(db->first == NULL && db->last == NULL){
637

    
638
                // Update DB
639
                db->first = element;
640
                db->last = element;
641
                db->num_of_elements = 1;
642

    
643
                // Update element
644
                element->next = NULL;
645
                element->prev = NULL;
646
                element->alto_db = db;
647
                element->stamp = time(NULL);
648

    
649
                // And success
650
                return 1;
651
        }
652

    
653
        // Normal case, append element at the end of the list
654
        // Update predecessor
655
        db->last->next = element;
656

    
657
        // Update element
658
        element->prev = db->last;
659
        element->next = NULL;
660
        element->alto_db = db;
661
        element->stamp = time(NULL);
662

    
663
        // Update DB
664
        db->last = element;
665
        db->num_of_elements++;
666

    
667
        // This should be it
668
        return 1;
669
}
670

    
671
int alto_rem_element(struct alto_db_element_t * element){
672

    
673
        // Sanity Check
674
        returnIf(element == NULL, "element == NULL! ABORT", -1);
675

    
676
        // Now get the DB where the element is in
677
        struct alto_db_t *db;
678
        db = element->alto_db;
679

    
680
        // Special case, last and only element in DB
681
        if(db->first == element && db->last == element){
682
                // update main DB
683
                db->first = NULL;
684
                db->last = NULL;
685
                db->num_of_elements = 0;
686
                // free element
687
                free(element);
688
                // exit
689
                return 1;
690
        }
691

    
692
        // Special case, first element in chain
693
        if(db->first == element && db->last != element){
694
                // Update successor
695
                element->next->prev = NULL;
696
                // Update DB
697
                db->first = element->next;
698
                db->num_of_elements--;
699
                // free element
700
                free(element);
701
                // exit
702
                return 1;
703
        }
704

    
705
        // Special case, last element in chain
706
        if(db->first != element && db->last == element){
707
                // Update predecessor
708
                element->prev->next = NULL;
709
                // Update DB
710
                db->last = element->prev;
711
                db->num_of_elements--;
712
                // free element
713
                free(element);
714
                // exit
715
                return 1;
716
        }
717

    
718

    
719
        // normal handling, somwhere in the DB
720
        else {
721
                // update predecessor
722
                element->prev->next = element->next;
723
                element->next->prev = element->prev;
724
                // Update DB
725
                db->num_of_elements--;
726
                // free element
727
                free(element);
728
                // exit
729
                return 1;
730
        }
731

    
732
        // Just in case something went wrong
733
        // what NEVER will happen
734
        alto_errorf("%s - Error in removing element function!\n", __FUNCTION__);
735
        return -1;
736
}
737

    
738

    
739
struct in_addr compute_subnet(struct in_addr host, int prefix){
740
        struct in_addr subn;
741
        uint32_t match_host = host.s_addr;
742
        uint32_t match_mask = 0xFFFFFFFF;
743
        match_mask <<= 32 - prefix;
744
        match_mask = ntohl(match_mask);
745
        uint32_t match_merg = match_host & match_mask;
746
//        printf("host  : %s/%d \t", inet_ntoa(host), prefix);
747
//        subn.s_addr = match_mask;
748
//        printf("mask  : %s  \t", inet_ntoa(subn));
749
        subn.s_addr = match_merg;
750
//        printf("net   : %s  \n", inet_ntoa(subn));
751
        return subn;
752
}
753

    
754

    
755

    
756
/*
757
 *         Search in an ALTO DB for the match of an host
758
 *
759
 *         value:        add                Address of the host to search for
760
 *                         db                The ALTO DB to search in
761
 *         return:        value/0        The found value / 0 in case of nothing
762
 */
763
int get_ALTO_rating_for_host(struct in_addr add, ALTO_DB_T * db){
764

    
765
        // Sanity checks
766
        returnIf(add.s_addr == 0, "Couldn't read the ALTO host IP to query! ABORT", 0);
767
        returnIf(db == NULL, "Couldn't access the DB! ABORT", 0);
768

    
769
        // walk through the DB until you find the element
770
    struct alto_db_element_t * cur;
771
    cur = db->first;
772
    while(cur != NULL){
773
            if(cur->host.s_addr == add.s_addr){
774
                    return cur->rating;
775
            }
776
            cur = cur->next;
777
    }
778

    
779
    // Here you come in case of error/not found!
780
        return 0;
781
}
782

    
783

    
784

    
785

    
786

    
787

    
788

    
789

    
790

    
791
int ask_helper_func(struct in_addr subnet, ALTO_DB_T * db){
792
        ALTO_DB_ELEMENT_T * cur = db->first;
793
        while(cur != NULL){
794
                if(subnet.s_addr == cur->host.s_addr){
795
//                        printf("Subnet : %s \t", inet_ntoa(subnet));
796
//                        printf("rating : %d \n", cur->rating);
797
                        return cur->rating;
798
                }
799
                cur = cur->next;
800
        }
801
        return 0;
802
}
803

    
804

    
805

    
806
int get_alto_rating(ALTO_DB_ELEMENT_T * element, ALTO_DB_T * db){
807

    
808
        int mask = element->host_mask;
809
        struct in_addr subnet = compute_subnet(element->host, mask);
810
//        printf("Host: %s/%d \n", inet_ntoa(element->host), mask);
811

    
812
        int i, check;
813
        for(i=mask;i>0;i--){
814
                check = ask_helper_func(subnet, db);
815
                if(check == 0){
816
                        subnet = compute_subnet(element->host, mask--);
817
                }else{
818
//                        printf("Found rating, with value: %d \n", check);
819
                        return check;
820
                }
821
        }
822
        return 0;
823
}
824

    
825

    
826

    
827
int get_alto_subnet_mask(ALTO_DB_ELEMENT_T * element, ALTO_DB_T * db){
828
        int mask = element->host_mask;
829
        struct in_addr subnet = compute_subnet(element->host, mask);
830
//        printf("Host: %s/%d \n", inet_ntoa(element->host), mask);
831
        int i;
832
        for(i=mask;i>0;i--){
833
                if((ask_helper_func(subnet, db)) == 0){
834
                        return mask;
835
                }else{
836
                        mask--;
837
                }
838
        }
839
        return 0;
840
}
841

    
842

    
843

    
844

    
845

    
846

    
847

    
848

    
849
/*
850
 *         Here the matching between the requested IPs and the delivered
851
 *         list will be done
852
 *
853
 *         in:                db_req                Pointer to the DB where the IPs are
854
 *                         db_res                Pointer to the DB where the ALTO response is
855
 *         return:        1                        Success
856
 */
857
int alto_do_the_magic(ALTO_DB_T * ALTO_db_req, ALTO_DB_T * ALTO_db_res){
858
        alto_debugf("%s: Find the rating and assign to IPs\n", __FUNCTION__);
859

    
860
        // Sanity check
861
        returnIf((ALTO_db_req == NULL || ALTO_db_res == NULL), "Errors in accessing the DBs! ABORT", 0);
862

    
863
        // Now iterate through the hosts and find the corresponding rating
864
        ALTO_DB_ELEMENT_T * cur;
865
        cur = ALTO_db_req->first;
866
        while(cur != NULL){
867

    
868
                // store the rating in the asking element
869
                cur->rating = get_alto_rating(cur, ALTO_db_res);
870

    
871
                // next DB item to query
872
                cur = cur->next;
873
        }
874

    
875
        // Aaaaaand finished!
876
        return 1;
877
}
878

    
879

    
880

    
881

    
882

    
883

    
884
int alto_parse_from_file(altoDbPtr db, char *file_name){
885
        alto_debugf("%s: Read hosts from file (%s) and store it in the Request-DB\n", __FUNCTION__, file_name);
886

    
887
        FILE *file;
888
        char line[256];
889
        file = fopen(file_name, "r");
890
        char * ptr;
891

    
892
        // Sanity checks
893
        returnIf(db == NULL, "No DB selected! ABORT", 0);
894
        returnIf(file == NULL, "Can't open the file! ABORT", 0);
895

    
896
        // Now read the lines in
897
        while(fgets(line, sizeof(line), file) != NULL ) {
898
                // parse the line, remove the comments
899
                ptr = strtok(line, " ");
900
                // create the ALTO element
901
                struct alto_db_element_t *element;
902
                element = malloc(sizeof(ALTO_DB_ELEMENT_T));
903
                element->host = get_ALTO_host_IP(ptr);
904
                element->host_mask = get_ALTO_host_mask(ptr);
905
                // and add this element to the db
906
                alto_add_element(db, element);
907
            }
908
        return 1;
909
}
910

    
911

    
912

    
913
int alto_parse_from_XML(altoDbPtr db, xmlDocPtr doc){
914
        alto_debugf("%s: Parse an XML element into the DB structure\n", __FUNCTION__);
915

    
916
        // Sanity check
917
        returnIf((db == NULL || doc == NULL), "Couldn't access XML or DB! ABORT", -1);
918

    
919
        xmlNode *cur = NULL;
920
        cur = xmlDocGetRootElement(doc);
921
        xmlChar *overall_rating = NULL;
922
        xmlChar *ipprefix = NULL;
923

    
924
        while(cur!=NULL){
925
                if(!xmlStrcmp(cur->name, BAD_CAST "cnd_hla")){
926
                        overall_rating = xmlGetProp(cur, BAD_CAST "overall_rating");
927
                }if(!xmlStrcmp(cur->name, BAD_CAST "ipprefix")){
928
                        ipprefix = xmlGetProp(cur, BAD_CAST "prefix");
929
                        if (!ipprefix) {
930
                                alto_debugf("Couldn't find ipprefix!\n");
931
                                break;
932
                        }
933

    
934
                        // create the ALTO element
935
                        struct alto_db_element_t *element;
936
                        element = malloc(sizeof(ALTO_DB_ELEMENT_T));
937
                        element->host = get_ALTO_host_IP((char*) ipprefix);
938
                        element->host_mask = get_ALTO_host_mask((char*) ipprefix);
939
                        if (overall_rating) {
940
                                element->rating = atoi(overall_rating);
941
                                alto_debugf("rating %s = %d\n", ipprefix, overall_rating);
942
                        } else {
943
                                overall_rating = 0;
944
                                alto_debugf("rating %s = %d (DEFAULT, host not in DB!)\n", ipprefix, overall_rating);
945
                        }
946

    
947
                        // and add this element to the db
948
                        alto_add_element(db, element);
949

    
950
                } if(cur->children != NULL){
951
//                        printf("cur->children == NULL \n");
952
                        cur = cur->children;
953
                } if(cur->children == NULL && cur->next != NULL){
954
//                        printf("cur->children == NULL && cur->next != NULL \n");
955
                        cur = cur->next;
956
                } if(cur->children == NULL && cur->next == NULL){
957
//                        printf("cur->children == NULL && cur->next == NULL \n");
958
                        cur = cur->parent->next;
959
                }
960
        }
961

    
962
        return 1;
963
}
964

    
965

    
966

    
967
/*
968
 *         Converts a given alto_list_t structure into the internal DB structure
969
 *
970
 *         in:                db                the databse where the element has to be added
971
 *                         list        the list of the alto elements structure
972
 *                         num                number of eements to add
973
 *         ret:        1/-1        for success failuire
974
 */
975
int alto_parse_from_list(struct alto_db_t *db, struct alto_guidance_t *list, int num_of_elements){
976
        alto_debugf("%s: Convert given list into internal DB structure\n", __FUNCTION__);
977

    
978
        // Sanity check
979
        returnIf((db == NULL || list == NULL), "No lists to parse from / parse in, ABORT!", -1);
980

    
981
        // and now will the elements in the DB
982
        int i;
983
        for(i=0; i < num_of_elements; i++){
984

    
985
                // Create a new element
986
                struct alto_db_element_t *element;
987
                element = malloc(sizeof(ALTO_DB_ELEMENT_T));
988
                element->alto_db = db;
989
                element->next = NULL;
990
                element->prev = NULL;
991
                element->host = list[i].alto_host;                        // here the values come in
992
                element->host_mask = list[i].prefix;                // here the values come in
993
                element->rating = 0;                                                // here the values come in
994

    
995
                // and now append it to the DB
996
                alto_add_element(db, element);
997
        }
998

    
999
        // That's should be it
1000
        return 1;
1001
}
1002

    
1003

    
1004

    
1005

    
1006

    
1007
int alto_write_to_file(altoDbPtr db, char *file_name){
1008
        alto_debugf("%s: Write hosts to file (%s.out) \n", __FUNCTION__, file_name);
1009

    
1010
        // Sanity checks
1011
        returnIf(file_name == NULL, "Can't open the file! ABORT",-1);
1012
        returnIf(db == NULL, "No DB select! ABORT", -1);
1013

    
1014
        // Create the new file
1015
        char * str_out;
1016
        str_out = (char*)malloc(256 * sizeof(char));
1017
        strcpy (str_out,file_name);
1018
        strcat (str_out,".out");
1019

    
1020
        // create the output filename
1021
        FILE *file;
1022
        file = fopen(str_out, "a+");
1023
        returnIf(file == NULL, "Can't create the file! ABORT", 0);
1024

    
1025
        // Write everything to the file
1026
        int count = 0;
1027
        ALTO_DB_ELEMENT_T * cur = db->first;
1028
        while(cur != NULL){
1029
                fprintf(file, "%s/%d \t", inet_ntoa(cur->host), cur->host_mask);
1030
                fprintf(file, "%d \t", cur->rating);
1031
                fprintf(file, "\n");
1032
                count++;
1033
                cur = cur->next;
1034
        }
1035

    
1036
        // Return the number of sucessful written lines
1037
        return count;
1038
}
1039

    
1040

    
1041

    
1042

    
1043
/*
1044
 *         Start & Innitialize the ALTO client
1045
 */
1046
void start_ALTO_client(){
1047
        alto_debugf("START ALTO client! \n");
1048

    
1049
        // initialize the DBs
1050
        ALTO_DB_req = alto_db_init();
1051
        ALTO_DB_res = alto_db_init();
1052

    
1053
        // prepare the XML environment
1054
        LIBXML_TEST_VERSION;
1055

    
1056
        // and Initialize the XMLs
1057
    ALTO_XML_req = NULL;
1058
    ALTO_XML_res = NULL;
1059

    
1060

    
1061
}
1062

    
1063

    
1064
/*
1065
 *         Stop & CleanUp the ALTO client
1066
 */
1067
void stop_ALTO_client(){
1068
        alto_debugf("STOP ALTO client! \n");
1069

    
1070
        // Kill the DBs
1071
        alto_free_db(ALTO_DB_req);
1072
        alto_free_db(ALTO_DB_res);
1073

    
1074
        // Kill the XML
1075
    if (ALTO_XML_req) { xmlFreeDoc(ALTO_XML_req); ALTO_XML_req = NULL; }
1076
    if (ALTO_XML_res) { xmlFreeDoc(ALTO_XML_res); ALTO_XML_res = NULL; }
1077

    
1078
        xmlCleanupParser();
1079
}
1080

    
1081

    
1082

    
1083

    
1084

    
1085

    
1086
/*
1087
 *         Function:        gets for a list in a txt file the correct rating
1088
 *
1089
 *         in:                        *txt        pointer to the list
1090
 *                                 rc_host        The Resource Consumer locator
1091
 *                                 pri_rat        Primary Rating criteria
1092
 *                                 sec_rat        Secondary Rating criteria
1093
 *         return:                1/0                Success/Erros
1094
 */
1095
int get_ALTO_guidance_for_txt(char * txt, struct in_addr rc_host, int pri_rat, int sec_rat){
1096
        alto_debugf("get_ALTO_guidance_txt(%s) was called \n", txt);
1097

    
1098
        // Sanity checks 
1099
        returnIf(txt == NULL, "Can't access the file! ABORT!", 0);
1100
        returnIf(rc_host.s_addr == NULL, "Can't read the rc_host! ABORT!", 0);
1101
        returnIf((pri_rat < 1 || pri_rat > 3), "Primary Rating Criteria wrong! ABORT!", 0);
1102
        returnIf((sec_rat < 1 || sec_rat > 8), "Secondary Rating Criteria(s) wrong! ABORT", 0);
1103

    
1104
        // first purge existing DB entries
1105
        alto_purge_db(ALTO_DB_req);
1106

    
1107
        // Step 1: fill the txt into the DB
1108
        alto_parse_from_file(ALTO_DB_req, txt);
1109

    
1110
        // do the ALTO trick / update db
1111
        do_ALTO_update(rc_host, pri_rat, sec_rat);
1112

    
1113
        // Step 3 (write values back)
1114
        alto_write_to_file(ALTO_DB_req, txt);
1115

    
1116
        // done
1117
        return 1;
1118
}
1119

    
1120
/*
1121
 *         Function:        gets for a list of elements the correct rating
1122
 *
1123
 *         in:                        *list        pointer to the list
1124
 *                                 *num        Number of elements to process
1125
 *         return:                count        Number of sucessfully processed hosts
1126
 */
1127
int get_ALTO_guidance_for_list(ALTO_GUIDANCE_T * list, int num, struct in_addr rc_host, int pri_rat, int sec_rat){
1128
        alto_debugf("get_ALTO_guidance(list, num_of_elements) was called \n");
1129

    
1130
        int count = 0;
1131

    
1132
        // Sanity checks (list)
1133
        returnIf(list == NULL, "Can't access the list!", 0);
1134

    
1135
        // Sanity checks (num of elements)
1136
        returnIf(num < 0, "<0 elements?", 0);
1137

    
1138
        // first purge existing DB entries
1139
        alto_purge_db(ALTO_DB_req);
1140

    
1141
        // Step 1 (read struct into DB)
1142
        alto_parse_from_list(ALTO_DB_req, list, num);
1143

    
1144
        // do the ALTO trick / update db
1145
        do_ALTO_update(rc_host, pri_rat, sec_rat);
1146

    
1147
        // Step 2 (write values back)
1148
        for(count = 0; count < num; count++){
1149
                list[count].rating = get_ALTO_rating_for_host(list[count].alto_host, ALTO_DB_req);
1150
        }
1151

    
1152
        // This should be it
1153
        return 1;
1154
}
1155

    
1156
/*==================================
1157
    Multi-Threaded Query
1158
  ==================================*/
1159

    
1160
static int queryState = ALTO_QUERY_READY;
1161

    
1162
static pthread_t threadId;
1163
static pthread_attr_t attr;
1164

    
1165
typedef struct {
1166
        ALTO_GUIDANCE_T* list;
1167
        int num;        // number of elements in list
1168
        struct in_addr rc_host;
1169
        int pri_rat;
1170
        int sec_rat;
1171
} ALTO_ThreadArgs_t;
1172

    
1173
ALTO_ThreadArgs_t threadArgs;
1174

    
1175
void* alto_query_thread_func(void* thread_args)
1176
{
1177
        int count = 0;
1178
        ALTO_ThreadArgs_t* args = (ALTO_ThreadArgs_t*) thread_args;
1179

    
1180
        alto_debugf("alto_query_thread_func\n");
1181

    
1182
        // this will block at some point
1183
        do_ALTO_update(args->rc_host, args->pri_rat, args->sec_rat);
1184

    
1185
        // write values back
1186
        for(count = 0; count < args->num; count++){
1187
                args->list[count].rating = get_ALTO_rating_for_host(args->list[count].alto_host, ALTO_DB_req);
1188
        }
1189

    
1190
        // signal that query is ready
1191
        queryState = ALTO_QUERY_READY;
1192

    
1193
        return thread_args;
1194
}
1195

    
1196
int ALTO_query_state() {
1197
        return queryState;
1198
}
1199

    
1200
int ALTO_query_exec(ALTO_GUIDANCE_T * list, int num, struct in_addr rc_host, int pri_rat, int sec_rat){
1201
        alto_debugf("ALTO_query_exec\n");
1202

    
1203
        // Sanity checks (list)
1204
        returnIf(list == NULL, "Can't access the list!", 0);
1205

    
1206
        // Sanity checks (num of elements)
1207
        returnIf(num < 0, "<0 elements?", 0);
1208

    
1209
        // set new state
1210
        queryState = ALTO_QUERY_INPROGRESS;
1211

    
1212
        // first purge existing DB entries
1213
        alto_purge_db(ALTO_DB_req);
1214

    
1215
        // Step 1 (read struct into DB)
1216
        alto_parse_from_list(ALTO_DB_req, list, num);
1217

    
1218
        //ALTO_XML_req = alto_create_request_XML(ALTO_DB_req, rc_host, pri_rat, sec_rat);
1219

    
1220
        threadArgs.list = list;
1221
        threadArgs.num = num;
1222
        pthread_attr_init(&attr);
1223
        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1224
        if (pthread_create(&threadId, &attr, alto_query_thread_func, &threadArgs) != 0) {
1225
                fprintf(stderr,"[ALTOclient] pthread_create failed!\n");
1226
                queryState = ALTO_QUERY_READY;
1227
                return 0;
1228
        }
1229

    
1230
        // This should be it
1231
        return 1;
1232
}
1233

    
1234

    
1235

    
1236
/*
1237
 * Function:        With this call the internal request to update the DB is triggered.
1238
 *                                 This should be done on a regual basis to keep the local ALTO-DB
1239
 *                                 up2date
1240
 */
1241

    
1242

    
1243
void do_ALTO_update(struct in_addr rc_host, int pri_rat, int sec_rat){
1244

    
1245
        // Step 2: create an XML from the DB entries
1246
        ALTO_XML_req = alto_create_request_XML(ALTO_DB_req, rc_host, pri_rat, sec_rat);
1247

    
1248
#ifndef USE_LOCAL_REPLY_XML
1249
        // Step2a: send POST request to ALTO server
1250
        #ifdef USE_CURL
1251
        ALTO_XML_res = query_ALTO_server_curl(ALTO_XML_req, alto_server_url);
1252
        #else
1253
        ALTO_XML_res = ALTO_request_to_server(ALTO_XML_req, alto_server_url);
1254
        #endif
1255
#else
1256
        // Step2b: use for testing the local stored TXT-file
1257
        ALTO_XML_res = xmlReadFile("reply.xml",NULL,XML_PARSE_RECOVER);
1258
#endif
1259

    
1260
        // Step 3: Parse the XML to the DB
1261
        alto_parse_from_XML(ALTO_DB_res, ALTO_XML_res);
1262

    
1263
        // ###### Big Magic ######
1264
        // And now check for the corresponding rating
1265
        alto_do_the_magic(ALTO_DB_req, ALTO_DB_res);
1266

    
1267
        // free xml data
1268
        xmlFreeDoc(ALTO_XML_req);
1269
        xmlFreeDoc(ALTO_XML_res);
1270
        ALTO_XML_req = NULL;
1271
        ALTO_XML_res = NULL;
1272

    
1273
        // purge the intermediate DB
1274
        alto_purge_db(ALTO_DB_res);
1275
}
1276

    
1277

    
1278

    
1279

    
1280

    
1281

    
1282

    
1283

    
1284