Etiquetas

C (31) Cpp (28) Linux (14) asm (8) Telegram (5) bot (5) libreria (5) Algoritmo (3) Errores comunes (3) python (3) Opengl (2) kali (2) Android (1) Snippet (1) nano (1) recursividad (1)

viernes, 24 de noviembre de 2023

Bot telegram (1)main.c

 /*
 * Luis Alberto
 * Twitter @albertobsd
 */

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<curl/curl.h>
#include<sys/stat.h>
#include<errno.h>
#include"telegram.h"
#include"jsmn.h"

char *telegram_buffer;
int telegram_buffer_size = 1024;
int telegram_buffer_offset = 0;
char *telegram_baseurl = "https://api.telegram.org/bot";
char *telegram_fileurl = "https://api.telegram.org/file/bot";
char *telegram_token;
int telegram_error = 0;
int telegram_error_code = 0;
char *telegram_error_buffer;

char *message_names[] = {"message_id","from","date","chat",
"forward_from","forward_date","reply_to_message",
"text","audio","document","photo","sticker","video",
"voice","caption","contact","location",
"new_chat_participant","left_chat_participant",
"new_chat_title","new_chat_photo","delete_chat_photo",
"group_chat_created","supergroup_chat_created",
"channel_chat_created","migrate_to_chat_id","migrate_from_chat_id",NULL};

char *contact_names[] = {"phone_number","first_name","last_name","user_id",NULL};
char *chat_names[] = {"id","type","title","username","first_name","last_name",NULL};
char *chat_type_names[] = {"private","group","supergroup","channel",NULL};
char *sticker_names[] = {"file_id","width","height","thumb","file_size",NULL};
char *photosize_names[] = {"file_id","width","height","file_size",NULL};
char *voice_names[] = {"file_id","duration","mime_type","file_size",NULL};
char *location_names[] = {"longitude","latitude",NULL};
char *document_names[] = {"file_id","thumb","file_name","mime_type","file_size",NULL};
char *video_names[] = {"file_id","width","height","duration","thumb","mime_type","file_size",NULL};
char *response_names[] = {"ok","description","result","error_code",NULL};
char *user_names[] = {"id","first_name","last_name","username",NULL};
char *update_names[] = {"update_id","message","inline_query","chosen_inline_result",NULL};
char *file_names[] = {"file_id","file_size","file_path",NULL};

int message_states[3][5] = {{4,1,4,4,4},{4,4,4,2,4},{4,1,1,1,1}};
int parse_array_states[2][5] = {{4,4,1,4,4},{4,1,4,4,4}};

Response *telegram_parse_response(char *str,int *count) {
Response *response;
int r,n =1,c,i =0;
unsigned int state = 0,entrar = 1;
char *variable,*value;
response = calloc(2,sizeof(Response));
jsmntok_t *toks;
jsmn_parser parser;
toks = calloc(n+2,sizeof(jsmntok_t));
r = telegram_jsmn_init(&parser,&toks,str,&n);
while(entrar && i < r)  {
switch(state)   {
case 0:
state = message_states[state][toks[i].type];i++;break;

case 1:
variable = telegram_jsmn_get_token(toks[i],str);
state = message_states[state][toks[i].type];i++;break;

case 2:
value = telegram_jsmn_get_token(toks[i],str);
state = message_states[state][toks[i].type];i++;

switch(indexOf(variable,response_names)){
case 0:response->ok = value;break;
case 1:response->description = value;
telegram_error_buffer = calloc(strlen(value)+2,sizeof(char));
memcpy(telegram_error_buffer,value,strlen(value)*sizeof(char));
entrar = 0;break;
case 2:response->result = value;
entrar = 0;break;
case 3:
response->error_code = strtol(value,NULL,10);
telegram_error = 1;telegram_error_code =  response->error_code;
free(value);break;
default:
telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
entrar = 0;break;}

free(variable);break;
case 3:
telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
entrar = 0;break;

default:
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return response;
}


int telegram_jsmn_init
(jsmn_parser *parser,jsmntok_t **t,char *buffer,int *n){
int r;
jsmntok_t *toks;
jsmn_init(parser);
toks = calloc(n[0]+2,sizeof(jsmntok_t));

if(toks != NULL){
r = jsmn_parse(parser, buffer, strlen(buffer), toks, n[0]);

while (r == JSMN_ERROR_NOMEM){
n[0]*=2;toks = realloc(toks, sizeof(jsmntok_t) * (n[0] + 2));
r = jsmn_parse(parser, buffer, strlen(buffer), toks, n[0]);}

if (r == JSMN_ERROR_INVAL){telegram_set_error("jsmn_parse: invalid JSON string",JSMN_ERROR_INVAL);}
if (r == JSMN_ERROR_PART){telegram_set_error("jsmn_parse: truncated JSON string",JSMN_ERROR_PART);}
t[0] = toks;}else{telegram_set_error("calloc: error",0xDEAD);}
return r;}

int telegram_set_error(char *error_str,int error_code)  {
        telegram_error_buffer = error_str;
        telegram_error_code = error_code;
        telegram_error = 1;
        return 0;
}

Response* telegram_free_response(Response *res) {
        if(res) {
                if(res->ok)     {free(res->ok);}
                if(res->result) {free(res->result);}
                if(res->description){free(res->description);}
                memset(res,0,sizeof(Response));
                free(res);
        }
        return NULL;
}

User* telegram_free_user(User *user){
        if(user){
                if(user->username != NULL){free(user->username);}
                if(user->first_name != NULL){free(user->first_name);}
                if(user->last_name != NULL){free(user->last_name);}
                memset(user,0,sizeof(User));
                free(user);
        }
return NULL;}

int indexOf(char *str,char **ptr_strings){
int i = 0,entrar = 1;

while(entrar && ptr_strings[i] != NULL){
if(strcmp(ptr_strings[i],str) == 0){entrar = 0;i--;}
i++;
}
if(entrar){i = -1;}
return i;}

char * telegram_jsmn_get_token(jsmntok_t token,char *full){
char *str;int size = token.end - token.start;
str = calloc(size+2,sizeof(char));
memcpy(str,full+token.start,size);
return str;}

void telegram_dump_token(jsmntok_t token,char *str){
        char *temp;
        temp = telegram_jsmn_get_token(token,str);
        printf("Token: %s\n",temp);
        free(temp);
        printf("type: %i\n",token.type);
        printf("start: %i\n",token.start);
        printf("end: %i\n",token.end);
        printf("size: %i\n",token.size);
#ifdef JSMN_PARENT_LINKS
        printf("size: %i\n",token.parent);
#endif
}

User* telegram_getMe()  {
        CURL *curl;
        CURLcode res;
        Response *response = NULL;
        User *user = NULL;
        char *url = NULL;
        int i;
        url = telegram_makeurl("/getMe");
        curl = telegram_curl_init();
        curl_easy_setopt(curl, CURLOPT_URL, url);
        res = curl_easy_perform(curl);
        free(url);
        if(res == CURLE_OK)     {
                response = telegram_parse_response(telegram_buffer,&i);
                if(!telegram_error)     {
                        user = telegram_parse_user(response->result,&i);
                }
                telegram_free_response(response);
                telegram_reset_buffer();
                curl_easy_cleanup(curl);
        }
        else    {
                telegram_set_error("curl: curl_easy_perform()",-1000);
        }
        return user;
}

File* telegram_getFile(char *file_id)   {
        CURL *curl;
        CURLcode res;
        Response *response = NULL;
        File *file = NULL;
        char *url = NULL;
        char *postdata = NULL;
        char *variables[] = {"file_id",NULL};
        char *values[] = {file_id,NULL};
        int i;
        if(file_id){
                curl = telegram_curl_init();
                url = telegram_makeurl("/getFile");
                curl_easy_setopt(curl, CURLOPT_URL, url);
                postdata = telegram_build_post(variables,values);
                curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata);
                res = curl_easy_perform(curl);
                free(url);
                if(res == CURLE_OK)     {
                        response = telegram_parse_response(telegram_buffer,&i);
                        if(!telegram_error)     {
                                file = telegram_parse_file(response->result,&i);
                        }
                        telegram_free_response(response);
                        telegram_reset_buffer();
                }
                else    {
                        telegram_set_error("curl_easy_perform() failed!",-1000);
                }
                free(postdata);
                curl_easy_cleanup(curl);
        }
        else    {
                telegram_set_error("NULL file_id",-10);
        }
        return file;
}

char *telegram_makeurl(char *telegram_method)   {
        char *url;
        int l;
        int size_base;
        int size_token;
        int size_method;
        size_base = strlen(telegram_baseurl);
        size_token = strlen(telegram_token);
        size_method = strlen(telegram_method);
        l = size_base + size_token + size_method;
        url = calloc(l+2,sizeof(char));
        if(url != NULL) {
                snprintf(url,l+1,"%s%s%s",telegram_baseurl,telegram_token,telegram_method);
        }
        else    {
                fprintf(stderr,"calloc error\n");
                exit(1);
        }
        return url;
}

User* telegram_parse_user(char *str,int *count) {
        User *user;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        char *token,*token1;
        jsmntok_t *toks;
        jsmn_parser parser;
        user = calloc(2,sizeof(User));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                                switch(indexOf(variable,user_names))    {
                                        case 0:
                                                user->id = strtol(value,NULL,10);
                                                free(value);
                                        break;
                                        case 1:
                                                user->first_name = value;
                                        break;
                                        case 2:
                                                user->last_name = value;
                                        break;
                                        case 3:
                                                user->username = value;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 3:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0] += r;
        return user;
}

int telegram_reset_buffer()     {
        memset(telegram_buffer,0,telegram_buffer_size);
        telegram_buffer_offset = 0;
        return 0;
};

size_t write_callback(void *ptr, size_t size, size_t nmemb, void *userdata )    {
        size_t new_len = telegram_buffer_offset + size*nmemb;
        if(new_len >= telegram_buffer_size)     {
                do      {
                        telegram_buffer_size*=2;
                }while(new_len >= telegram_buffer_size);
                telegram_buffer = realloc(telegram_buffer, (telegram_buffer_size +2)*sizeof(char));
                if (telegram_buffer == NULL) {
                        fprintf(stderr, "realloc() failed\n");
                        exit(EXIT_FAILURE);
                }
        }
        memcpy(telegram_buffer + telegram_buffer_offset, ptr, size*nmemb);
        telegram_buffer[new_len] = '\0';
        telegram_buffer_offset+= size*nmemb;
        return size*nmemb;
}

off_t fsize(const char *filename) {
        struct stat st;
        if (stat(filename, &st) == 0)
                return st.st_size;
        fprintf(stderr, "Cannot determine size of %s: %s\n",filename, strerror(errno));
        return -1;
}

Updates * telegram_getUpdates() {
        CURL *curl;
        CURLcode res;
        Response *response = NULL;
        Updates *updates = NULL;
        char *url = telegram_makeurl("/getUpdates");
        int i;
        curl = telegram_curl_init();
        curl_easy_setopt(curl, CURLOPT_URL, url);
        res = curl_easy_perform(curl);
        free(url);
        if(res == CURLE_OK)     {
                response = telegram_parse_response(telegram_buffer,&i);
                if(!telegram_error)     {
                        if(response && response->result){
                                updates = telegram_parse_updates(response->result,&i);
                        }
                }
                telegram_free_response(response);
                telegram_reset_buffer();
                curl_easy_cleanup(curl);
        }
        else    {
                telegram_set_error("curl: curl_easy_perform()",-1000);
        }
        return updates;
}

Updates * telegram_parse_updates(char *str,int *count)  {
        Updates *updates;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *value;
        updates = calloc(2,sizeof(Updates));
        updates->list = calloc(2,sizeof(Update*));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+2,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = parse_array_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = parse_array_states[state][toks[i].type];
                                updates->list[updates->length] = telegram_parse_update(value,&i);
                                updates->length++;
                                updates->list = realloc(updates->list,(updates->length+2)*sizeof(Update *));
                        break;
                        case 4:
                                telegram_dump_token(toks[i],str);
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return updates;
}

Update * telegram_parse_update(char *str,int *count)    {
        Update *update = NULL;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        update = calloc(2,sizeof(Update));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                switch(indexOf(variable,update_names))  {
                                        case 0:
                                                update->update_id = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 1:
                                                update->item.message = telegram_parse_message(value,&i);
                                                free(value);
                                        break;
                                        case 2:
                                        case 3:
                                                telegram_set_error("Fixme",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                free(value);
                                                entrar = 0;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 3:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                        default:
                        break;
                }

        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+= r;
        return update;
}

Message* telegram_parse_message(char *str,int *count)   {
        Message *message;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        message = calloc(2,sizeof(Message));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                c = indexOf(variable,message_names);
                                switch(c)       {
                                        case 0: //message_id
                                                message->message_id = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 1: //from
                                                message->from = telegram_parse_user(value,&i);
                                                free(value);
                                        break;
                                        case 2: //date
                                                message->date = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 3: //chat
                                                message->chat= telegram_parse_chat(value,&i);
                                                free(value);
                                        break;
                                        case 4: //forward_from
                                                message->forward_from = telegram_parse_user(value,&i);
                                                free(value);
                                        break;
                                        case 5: //forward_date
                                                message->forward_date = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 6: //reply_to_message
                                                message->reply_to_message = telegram_parse_message(value,&i);
                                                free(value);
                                        break;
                                        case 7: //text
                                                message->text = value;
                                                i++;
                                        break;
                                        case 8: //audio
                                                printf("error with token %s\n",value);
                                                entrar = 0;
                                                free(value);
                                                i++;
                                        break;
                                        case 9: //document
                                                message->document = telegram_parse_document(value,&i);
                                                free(value);
                                        break;
                                        case 10: //photo
                                                message->photo = telegram_parse_photos(value,&i);
                                                free(value);
                                        break;
                                        case 11:

                                                message->sticker = telegram_parse_sticker(value,&i);
                                                free(value);
                                        break;
                                        case 12:        //video
                                                message->video = telegram_parse_video(value,&i);
                                        break;
                                        case 13:        //voice
                                                message->voice = telegram_parse_voice(value,&i);
                                                free(value);
                                        break;
                                        case 14:        //Cption
                                                message->caption = value;
                                                i++;
                                        break;
                                        case 15:        //contact
                                                message->contact = telegram_parse_contact(value,&i);
                                                free(value);
                                        break;
                                        case 16:        //location
                                                message->location = telegram_parse_location(value,&i);
                                                free(value);
                                        break;
                                        case 17:        //new_chat_participant
                                                message->new_chat_participant = telegram_parse_user(value,&i);
                                                free(value);
                                        break;
                                        case 18:        //left_chat_participant
                                                message->left_chat_participant = telegram_parse_user(value,&i);
                                                free(value);
                                        break;
                                        case 19:        //new_chat_title
                                                message->new_chat_title = value;
                                                i++;
                                        break;
                                        case 20:        //new_chat_photo
                                                message->new_chat_photo = telegram_parse_photos(value,&i);
                                                free(value);
                                        break;
                                        case 21:        //delete_chat_photo
                                                message->delete_chat_photo = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 22:        //group_chat_created
                                                message->group_chat_created = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 23:        //supergroup_chat_created
                                                message->supergroup_chat_created = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 24:        //channel_chat_created
                                                message->channel_chat_created = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 25:        //migrate_to_chat_id
                                                message->migrate_to_chat_id = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 26:        //migrate_from_chat_id
                                                message->migrate_from_chat_id = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                        default:
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return message;
}

Chat* telegram_parse_chat(char *str,int  *count)        {
        Chat *chat = NULL;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        chat = calloc(2,sizeof(Chat));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                                switch(indexOf(variable,chat_names))    {
                                        case 0:
                                                chat->id = strtol(value,NULL,10);
                                                free(value);
                                        break;
                                        case 1:
                                                chat->type = indexOf(variable,chat_type_names);
                                        break;
                                        case 2:
                                                chat->title = value;
                                        break;
                                        case 3:
                                                chat->username = value;
                                        break;
                                        case 4:
                                                chat->first_name = value;
                                        break;
                                        case 5:
                                                chat->last_name = value;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;

                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return chat;
}

Sticker* telegram_parse_sticker(char *str,int *count)   {
        Sticker *sticker = NULL;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        sticker = calloc(2,sizeof(Sticker));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                switch(indexOf(variable,sticker_names)) {
                                        case 0:
                                                sticker->file_id = value;
                                                i++;
                                        break;
                                        case 1:
                                                sticker->width = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 2:
                                                sticker->height = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 3:
                                                sticker->thumb = telegram_parse_photosize(value,&i);
                                                free(value);
                                        break;
                                        case 4:
                                                sticker->file_size = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;

                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return sticker;
}

PhotoSize* telegram_parse_photosize(char *str,int *count)       {
        PhotoSize *photosize = NULL;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        photosize = calloc(2,sizeof(PhotoSize));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                c = indexOf(variable,photosize_names);
                                switch(c)       {
                                        case 0:
                                                photosize->file_id = value;
                                                i++;
                                        break;
                                        case 1:
                                                photosize->width = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 2:
                                                photosize->height = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 3:
                                                photosize->file_size = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return photosize;
}

Photos* telegram_parse_photos(char *str,int *count)     {
        Photos *photos = NULL;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *value;
        photos = calloc(2,sizeof(Photos));
        photos->length = 0;
        photos->item = calloc(2,sizeof(PhotoSize *));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = parse_array_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = parse_array_states[state][toks[i].type];
                                photos->item[photos->length] = telegram_parse_photosize(value,&i);
                                photos->length++;
                                photos->item = realloc(photos->item,(photos->length+2) * sizeof(PhotoSize*));
                        break;
                        case 4:
                                telegram_dump_token(toks[i],str);
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+= r;
        return photos;

}

Voice* telegram_parse_voice(char *str,int *count)       {
        Voice *voice;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        voice = calloc(2,sizeof(Voice));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                c = indexOf(variable,voice_names);
                                i++;
                                switch(c)       {
                                        case 0:
                                                voice->file_id = value;
                                        break;
                                        case 1:
                                                voice->duration = strtol(value,NULL,10);
                                                free(value);
                                        break;
                                        case 2:
                                                voice->mime_type = value;
;
                                        case 3:
                                                voice->file_size = strtol(value,NULL,10);
                                                free(value);
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return voice;
}

Location* telegram_parse_location(char *str,int *count) {
        Location *location;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        location = calloc(2,sizeof(Location));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                c = indexOf(variable,location_names);
                                i++;
                                switch(c)       {
                                        case 0:
                                                location->longitude = strtof(value,NULL);
                                        break;
                                        case 1:
                                                location->latitude = strtof(value,NULL);
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(value);
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return location;
}

Contact* telegram_parse_contact(char *str,int *count)   {
        Contact *contact;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        contact = calloc(2,sizeof(Contact));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                c = indexOf(variable,contact_names);
                                i++;
                                switch(c)       {
                                        case 0:
                                                contact->phone_number = value;
                                        break;
                                        case 1:
                                                contact->first_name = value;
                                        break;
                                        case 2:
                                                contact->last_name = value;
                                        break;

                                        case 3:
                                                contact->user_id = strtol(value,NULL,10);
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return contact;
}


Document* telegram_parse_document(char *str,int *count) {
        Document *document;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        document = calloc(2,sizeof(Document));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                c = indexOf(variable,document_names);
                                switch(c)       {
                                        case 0:
                                                document->file_id = value;
                                                i++;
                                        break;
                                        case 1:
                                                document->thumb = telegram_parse_photosize(value,&i);
                                                free(value);
                                        break;
                                        case 2:
                                                document->file_name = value;
                                                i++;
                                        break;

                                        case 3:
                                                document->mime_type = value;
                                                i++;
                                        break;

                                        case 4:
                                                document->file_size = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return document;
}

Video * telegram_parse_video(char *str,int *count)      {
        Video *video;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        video = calloc(2,sizeof(Video));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                c = indexOf(variable,video_names);
                                switch(c)       {
                                        case 0:
                                                video->file_id = value;
                                                i++;
                                        break;
                                        case 1:
                                                video->width = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 2:
                                                video->height = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 3:
                                                video->duration = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 4:
                                                video->thumb = telegram_parse_photosize(value,&i);
                                                free(value);
                                        break;
                                        case 5:
                                                video->mime_type = value;
                                                free(value);
                                                i++;
                                        break;
                                        case 6:
                                                video->file_size = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return video;
}

int telegram_init(char *token)  {
        int size;
        size = strlen(token);
        telegram_token = calloc(size,sizeof(char));
        if(telegram_token == NULL)      {
                fprintf(stderr, "calloc() failed\n");
                exit(1);
        }
        telegram_buffer = calloc(telegram_buffer_size,sizeof(char));
        if(telegram_buffer == NULL)     {
                fprintf(stderr, "calloc() failed\n");
                exit(1);
        }
        memcpy(telegram_token,token,size);
        return 0;
}

char *telegram_get_error()      {
        telegram_error = 0;
        return telegram_error_buffer;
}

int telegram_is_error() {
        return telegram_error;
}

char* telegram_build_post(char **variables,char **values)       {
        int i = 0,l = 0,size= 0,offset = 0;
        char *buffer = NULL;
        //printf("%X %X\n",variables,values);
        if(variables && values) {
                while( variables[l] && values[l])       {
                        //printf("%x %x\n",variables[l],values[l]);
                        size += (strlen(variables[l])+ strlen(values[l])+2);
                        l++;
                }
        }
        //printf("size = %i\nl = %i\n",size,l);
        buffer = calloc(size+1,sizeof(char));
        if(buffer)      {
                while(i<l)      {
                        if(i==0)        {
                                sprintf(buffer+offset,"%s=%s",variables[i],values[i]);
                                offset+= (1 +strlen(variables[i]) +strlen(values[i]));
                        }
                        else    {
                                sprintf(buffer+offset,"&%s=%s",variables[i],values[i]);
                                offset+= (1 +strlen(variables[i]) +strlen(values[i]));
                        }
                        i++;
                }
        }
        else    {
                fprintf(stderr,"error callo()");
                exit(0);
        }
        return buffer;
}

File* telegram_parse_file(char *str,int *count) {
        File *file;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        file = calloc(2,sizeof(File));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                c = indexOf(variable,file_names);
                                switch(c)       {
                                        case 0:
                                                file->file_id = value;
                                                i++;
                                        break;
                                        case 1:
                                                file->file_size = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 2:
                                                file->file_path = value;
                                                free(value);
                                                i++;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return file;

}

char* telegra_makeDownloadURL(File *file)       {
        char *url = NULL;
        char *temp = NULL;
        int l;
        int size_base;
        int size_token;
        int size_path;
        size_base = strlen(telegram_fileurl);
        size_token = strlen(telegram_token);
        size_path = strlen(file->file_path);
        l = size_base + size_token + size_path;
        temp = calloc(l+10,sizeof(char));
        if(temp)        {
                snprintf(temp,l+3,"%s%s/%s",telegram_fileurl,telegram_token,file->file_path);
                url = telegram_process_slash(temp);
                free(temp);
        }
        else    {
                fprintf(stderr,"calloc error\n");
                exit(1);
        }
        return url;
}

char* telegram_downloadFile(File *file,char *name)      {
        CURL *curl;
        CURLcode res;
        char *toreturn = NULL;
        FILE *toLocalFile = NULL;
        char **test = NULL;
        char *url = telegra_makeDownloadURL(file);
        curl = telegram_curl_init();
        curl_easy_setopt(curl, CURLOPT_URL, url);
        res = curl_easy_perform(curl);
        free(url);
        if(res == CURLE_OK)     {
                if(file->file_size == telegram_buffer_offset)   {
                        toLocalFile = fopen(name,"w");
                        if(toLocalFile) {
                                if(fwrite(telegram_buffer,sizeof(char),telegram_buffer_offset,toLocalFile) == telegram_buffer_offset)   {
                                        toreturn = name;
                                }
                                else    {
                                        telegram_set_error("stdio: fwrite()",-1000);
                                }
                                fclose(toLocalFile);
                        }
                        else    {
                                telegram_set_error("stdio: fopen()",-1000);
                        }
                        telegram_reset_buffer();
                }
                else    {
                        printf("Diff %i %i\n",file->file_size,telegram_buffer_offset);
                }
                curl_easy_cleanup(curl);
        }
        else    {
                telegram_set_error("curl: curl_easy_perform()",-1000);
        }
        return toreturn;
}

char* telegram_process_slash(char *str) {
        int i = 0,j =0;
        char *temp = NULL;
        if(str) {
                temp = calloc(strlen(str)+2,sizeof(char));
                while(str[j] != 0)      { // '\0'
                        if(str[j] == '\\')
                                j++;
                        temp[i] = str[j];
                        i++;
                        j++;
                }
        }
        else    {
                telegram_set_error("NULL funtion argument",-10);
        }
        return temp;
}

CURL* telegram_curl_init()      {
        CURL *curl  = NULL;
        //printf("CURL INIT\n");
        curl_global_init(CURL_GLOBAL_DEFAULT);
        curl = curl_easy_init();
        if(curl) {
                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
                curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL);
        }
        return curl;
}

Updates* telegram_free_updates(Updates *updates)        {
        if(updates)     {
                int i = 0;
                while(i < updates->length)      {
                        if(updates->list[i])
                                telegram_free_update(updates->list[i]);
                        i++;
                }
                memset(updates,0,sizeof(Updates));
                free(updates);
        }
        return NULL;
}

Update* telegram_free_update(Update *update)    {
        if(update)      {
                switch(update->type)    {
                        case 0:
                                telegram_free_message(update->item.message);
                        break;
                }
                memset(update,0,sizeof(Update));
                free(update);
        }
        return NULL;
}

Message* telegram_free_message(Message *message)        {
        if(message)     {
                if(message->from)       {
                        telegram_free_user(message->from);
                }
                if(message->chat)       {
                        telegram_free_chat(message->chat);
                }
                if(message->forward_from)       {
                        telegram_free_user(message->forward_from);
                }
                if(message->reply_to_message)   {
                        telegram_free_message(message->reply_to_message);
                }
                if(message->audio)      {
                        telegram_free_audio(message->audio);
                }
                if(message->document)   {
                        telegram_free_document(message->document);
                }
                if(message->photo)      {
                        telegram_free_photos(message->photo);
                }
                if(message->sticker)    {
                        telegram_free_sticker(message->sticker);
                }
                if(message->video)      {
                        telegram_free_video(message->video);
                }
                if(message->voice)      {
                        telegram_free_voice(message->voice);
                }
                if(message->contact)    {
                        telegram_free_contact(message->contact);
                }
                if(message->location)   {
                        telegram_free_location(message->location);
                }
                if(message->new_chat_participant)       {
                        telegram_free_user(message->new_chat_participant);
                }
                if(message->left_chat_participant)      {
                        telegram_free_user(message->left_chat_participant);
                }
                if(message->new_chat_photo)     {
                        telegram_free_photos(message->new_chat_photo);
                }
                memset(message,0,sizeof(Message));
                free(message);
        }
        return NULL;
}

Location* telegram_free_location(Location *location)    {
        if(location)    {
                memset(location,0,sizeof(Location));
                free(location);
        }
        return NULL;
}

Voice* telegram_free_voice(Voice *voice)        {
        if(voice)       {
                if(voice->file_id)      {
                        free(voice->file_id);
                }
                if(voice->mime_type)    {
                        free(voice->mime_type);
                }
                memset(voice,0,sizeof(Voice));
                free(voice);
        }
        return NULL;
}

Contact* telegram_free_contact(Contact *contact)        {
        if(contact)     {
                if(contact->phone_number)       {
                        free(contact->phone_number);
                }
                if(contact->first_name) {
                        free(contact->first_name);
                }
                if(contact->last_name)  {
                        free(contact->last_name);
                }
                memset(contact,0,sizeof(Contact));
                free(contact);
        }
        return NULL;
}

Document* telegram_free_document(Document *document)    {
        if(document)    {
                if(document->file_id)   {
                        free(document->file_id);
                }
                if(document->mime_type) {
                        free(document->mime_type);
                }
                if(document->file_name) {
                        free(document->file_name);
                }
                if(document->thumb)     {
                        telegram_free_photosize(document->thumb);
                }
                memset(document,0,sizeof(Document));
                free(document);
        }
        return NULL;
}

Chat* telegram_free_chat(Chat *chat)    {
        if(chat)        {
                if(chat->title) {
                        free(chat->title);
                }
                if(chat->username)      {
                        free(chat->username);
                }
                if(chat->first_name)    {
                        free(chat->first_name);
                }
                if(chat->last_name)     {
                        free(chat->last_name);
                }
                memset(chat,0,sizeof(Chat));
                free(chat);
        }
        return NULL;
}

Audio* telegram_free_audio(Audio *audio)        {
        if(audio)       {
                if(audio->file_id)      {
                        free(audio->file_id);
                }
                if(audio->performer)    {
                        free(audio->performer);
                }
                if(audio->title)        {
                        free(audio->title);
                }
                if(audio->mime_type)    {
                        free(audio->mime_type);
                }
                memset(audio,0,sizeof(Audio));
                free(audio);
        }
        return NULL;
}

Sticker* telegram_free_sticker(Sticker *sticker)        {
        if(sticker)     {
                if(sticker->file_id)    {
                        free(sticker->file_id);
                }
                if(sticker->thumb)      {
                        telegram_free_photosize(sticker->thumb);
                }
                memset(sticker,0,sizeof(Sticker));
                free(sticker);
        }
        return NULL;
}

PhotoSize* telegram_free_photosize(PhotoSize *photosize)        {
        if(photosize)   {
                if(photosize->file_id)  {
                        free(photosize->file_id);
                }
                memset(photosize,0,sizeof(PhotoSize));
                free(photosize);
        }
        return NULL;
}

Photos* telegram_free_photos(Photos *photos)    {
        int i = 0;
        if(photos)      {
                while(i < photos->length)       {
                        if(photos->item[i])
                                telegram_free_photosize(photos->item[i]);
                        i++;
                }
                free(photos->item);
                memset(photos,0,sizeof(Photos));
                free(photos);
        }
        return NULL;
}

Video* telegram_free_video(Video *video)        {
        if(video)       {
                if(video->file_id)      {
                        free(video->file_id);
                }
                if(video->mime_type)    {
                        free(video->mime_type);
                }
                if(video->thumb)        {
                        telegram_free_photosize(video->thumb);
                }
                memset(video,0,sizeof(Video));
                free(video);
        }
        return NULL;
}

Message* telegram_sendMessage(char *postdata)   {
        CURL *curl = NULL;
        CURLcode res;
        Response *response = NULL;
        Message *message = NULL;
        int i;
        char *url = NULL;
        url = telegram_makeurl("/sendMessage");
        curl = telegram_curl_init();
        curl_easy_setopt(curl, CURLOPT_URL , url);
        curl_easy_setopt(curl,  CURLOPT_POSTFIELDS , postdata);
        res = curl_easy_perform(curl);
        free(url);
        if(res == CURLE_OK)     {
                response = telegram_parse_response(telegram_buffer,&i);
                if(!telegram_error)     {
                        message = telegram_parse_message(response->result,&i);
                }
                telegram_free_response(response);
                telegram_reset_buffer();
                curl_easy_cleanup(curl);
        }
        else    {
                telegram_set_error("curl: curl_easy_perform()",-1000);
        }
        return message;
}

Message* telegram_sendDocument(char *filename,char **variables, char **valores) {
        CURL *curl = NULL;
        CURLcode res;
        struct curl_httppost *formpost=NULL;
        struct curl_httppost *lastptr=NULL;
        struct curl_slist *headerlist=NULL;
        static const char buf[] = "Expect:";
        Response *response = NULL;
        Message *message = NULL;
        char *url = NULL;
        int i;
        if(filename){
                url = telegram_makeurl("/sendDocument");
                curl = telegram_curl_init();
                i = 0;
                while(variables[i] != NULL && valores[i] != NULL)       {
                        curl_formadd(&formpost,&lastptr,CURLFORM_COPYNAME, variables[i],CURLFORM_COPYCONTENTS, valores[i],CURLFORM_END);
                        i++;
                }
                curl_formadd(&formpost,&lastptr,CURLFORM_COPYNAME, "document",CURLFORM_FILE, filename,CURLFORM_END);
                headerlist = curl_slist_append(headerlist, buf);
                curl_easy_setopt(curl, CURLOPT_URL , url);
                curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
                curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
                res = curl_easy_perform(curl);
                if(res == CURLE_OK)     {
                        response = telegram_parse_response(telegram_buffer,&i);
                        if(!telegram_error)     {
                                message = telegram_parse_message(response->result,&i);
                        }
                        else    {
                                telegram_set_error(response->description,1);
                        }
                        free(url);
                        curl_easy_cleanup(curl);
                        curl_formfree(formpost);
                        curl_slist_free_all (headerlist);
                }
                else    {
                        telegram_set_error("curl",1);
                }

        }
        else    {
                telegram_set_error("NULL argument",1);
        }
        return  message;
}

Message* sendLocation(char postdata)    {
        CURL *curl = NULL;
        CURLcode res;
        Response *response = NULL;
        Message *message = NULL;
        int i;
        char *url = NULL;
        url = telegram_makeurl("/sendLocation");
        curl = telegram_curl_init();
        curl_easy_setopt(curl, CURLOPT_URL , url);
        curl_easy_setopt(curl,  CURLOPT_POSTFIELDS , postdata);
        res = curl_easy_perform(curl);
        free(url);
        if(res == CURLE_OK)     {
                response = telegram_parse_response(telegram_buffer,&i);
                if(!telegram_error)     {
                        message = telegram_parse_message(response->result,&i);
                }
                telegram_free_response(response);
                telegram_reset_buffer();
                curl_easy_cleanup(curl);
        }
        else    {
                telegram_set_error("curl: curl_easy_perform()",-1000);
        }
        return message;

}