geturl.c 5.01 KB
Newer Older
1
/* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 3 4 5
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

6 7
#include <stdio.h>
#include <string.h>
8
#include <stdlib.h>
9 10 11 12 13 14 15 16 17 18

#include <thread/thread.h>

#include "connection.h"
#include "refbuf.h"
#include "client.h"
#include "logging.h"
#include "format.h"
#include "geturl.h"
#include "source.h"
19
#include "cfgfile.h"
20 21 22 23 24 25

#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>


Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
26
#define CATMODULE "geturl" 
27

Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
28
static curl_connection curl_connections[NUM_CONNECTIONS];
29
static mutex_t _curl_mutex;
30

31 32
size_t curl_write_memory_callback(void *ptr, size_t size, 
        size_t nmemb, void *data)
33
{
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
34
    register int realsize = size * nmemb;
35

Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
36
    struct curl_memory_struct *mem = (struct curl_memory_struct *)data;
37

Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
38 39 40
    if ((realsize + mem->size) < YP_RESPONSE_SIZE-1) {
        strncat(mem->memory, ptr, realsize);
    }
41

Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
42
    return realsize;
43
}
44 45 46

size_t curl_header_memory_callback(void *ptr, size_t size, 
        size_t nmemb, void *data)
47
{
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
48 49 50 51 52 53 54 55 56 57
    char *p1 = 0;
    char *p2 = 0;
    int copylen = 0;
    register int realsize = size * nmemb;
    struct curl_memory_struct2 *mem = (struct curl_memory_struct2 *)data;

    if (!strncmp(ptr, "SID: ", strlen("SID: "))) {
        p1 = (char *)ptr + strlen("SID: ");
        p2 = strchr((const char *)p1, '\r');
        memset(mem->sid, '\000', sizeof(mem->sid));
58 59 60
        if (p2) {
            if (p2-p1 > sizeof(mem->sid)-1) {
                copylen = sizeof(mem->sid)-1;
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
61 62
            }
            else {
63
                copylen = p2-p1;
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
64
            }
65 66 67 68 69
            strncpy(mem->sid, p1, copylen);
        }
        else {
            strncpy(mem->sid, p1, sizeof(mem->sid)-1);
        }
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
    }
    if (!strncmp(ptr, "YPMessage: ", strlen("YPMessage: "))) {
        p1 = (char *)ptr + strlen("YPMessage: ");
        p2 = strchr((const char *)p1, '\r');
        memset(mem->message, '\000', sizeof(mem->message));
        if (p2) {
            if (p2-p1 > sizeof(mem->message)-1) {
                copylen = sizeof(mem->message)-1;
            }
            else {
                copylen = p2-p1;
            }
            strncpy(mem->message, p1, copylen);
        }
        else {
            strncpy(mem->message, p1, sizeof(mem->message)-1);
        }
    }
    if (!strncmp(ptr, "TouchFreq: ", strlen("TouchFreq: "))) {
        p1 = (char *)ptr + strlen("TouchFreq: ");
90
        mem->touch_interval = atoi(p1);
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
91 92 93 94 95 96
    }
    if (!strncmp(ptr, "YPResponse: ", strlen("YPResponse: "))) {
        p1 = (char *)ptr + strlen("YPResponse: ");
        mem->response = atoi(p1);
    }
    return realsize;
97 98 99
}
int curl_initialize()
{
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
100 101 102
    int i = 0;
    thread_mutex_create(&_curl_mutex);

103
    memset(&curl_connections, 0, sizeof(curl_connections));
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
104 105 106 107 108
    for (i=0; i<NUM_CONNECTIONS; i++) {
        curl_connections[i].curl_handle = curl_easy_init();
        curl_easy_setopt(curl_connections[i].curl_handle, 
                CURLOPT_WRITEFUNCTION, curl_write_memory_callback);
        curl_easy_setopt(curl_connections[i].curl_handle, 
109 110
                CURLOPT_WRITEHEADER, 
                (void *)&(curl_connections[i].header_result));
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
111 112 113 114 115 116
        curl_easy_setopt(curl_connections[i].curl_handle, 
                CURLOPT_HEADERFUNCTION, curl_header_memory_callback);
        curl_easy_setopt(curl_connections[i].curl_handle, 
                CURLOPT_FILE, (void *)&(curl_connections[i].result));
    }
    return(1);
117 118 119
}
void curl_shutdown()
{
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
120 121 122
    int i = 0;
    for (i=0; i<NUM_CONNECTIONS; i++) {
        curl_easy_cleanup(curl_connections[i].curl_handle);
123
        memset(&(curl_connections[i]), 0, sizeof(curl_connections[i]));
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
124
    }
125
}
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
126
int curl_get_connection()
127
{
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
128 129 130 131 132 133 134 135 136 137 138 139 140 141
    int found = 0;
    int curl_connection = -1;
    int i = 0;
    while (!found) {
        thread_mutex_lock(&_curl_mutex);
        for (i=0; i<NUM_CONNECTIONS; i++) {
            if (!curl_connections[i].in_use) {
                found = 1;
                curl_connections[i].in_use = 1;
                curl_connection = i;
                break;
            }
        }
        thread_mutex_unlock(&_curl_mutex);
142
#ifdef WIN32
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
143
        Sleep(200);
144
#else
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
145
        usleep(200);
146
#endif
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
147 148
    }
    return(curl_connection);
149
}
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
150
int curl_release_connection(int which)
151
{
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
152 153
    thread_mutex_lock(&_curl_mutex);
    curl_connections[which].in_use = 0;
154
    memset(&(curl_connections[which].result), 0, 
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
155
                sizeof(curl_connections[which].result));
156
    memset(&(curl_connections[which].header_result), 0, 
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
157 158 159
                sizeof(curl_connections[which].header_result));
    thread_mutex_unlock(&_curl_mutex);
    return 1;
160
}
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
161 162 163
void curl_print_header_result(struct curl_memory_struct2 *mem) {
    DEBUG1("SID -> (%s)", mem->sid);
    DEBUG1("Message -> (%s)", mem->message);
164
    DEBUG1("Touch Freq -> (%d)", mem->touch_interval);
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
165
    DEBUG1("Response -> (%d)", mem->response);
166 167 168
}


Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
169
CURL *curl_get_handle(int which)
170
{
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
171
    return curl_connections[which].curl_handle;
172
}
173

Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
174
struct curl_memory_struct *curl_get_result(int which)
175
{
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
176
    return &(curl_connections[which].result);
177 178
}

Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
179
struct curl_memory_struct2 *curl_get_header_result(int which)
180
{
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
181
    return &(curl_connections[which].header_result);
182
}