Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> cURL/VS C++ 2010/ imap-клиент 
:(
    Опции темы
XaleRS
Дата 23.10.2012, 18:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 14.4.2008

Репутация: нет
Всего: нет



День добрый!
Есть такой ламерский вопрос smile 
необходимо написать imap-клиент простенький.
с самим протоколом уже разобрался, по телнету пообщался с ним - все нормально.
загвоздка встала при написании приложения - из всех предлагаемых библиотек больше всего доверия внушила cURL.
подключил ее к проекту, в тестовом приложении даже сумел залогиниться к ящику. НО дальше как раз таки и вопрос:
как допустим через cURl послать ту же комманду STATUS или FETCH по imap?

Код

CURL *curl;
  CURLcode res = CURLE_OK;

  curl = curl_easy_init();
  if(curl) {
    /* Set username and password */
    curl_easy_setopt(curl, CURLOPT_USERPWD, "xalers:password");

    /* This will fetch the mailbox named "foobar" */
    curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.yandex.ru/");
    //curl_easy_setopt(curl, CURLOPT_URL, "STATUS");
    //curl_easy_setopt(curl, CURLOPT_URL, "SELECT INBOX");
    res = curl_easy_perform(curl);
    
    cout << res << endl;
    /* always cleanup */    
    curl_easy_cleanup(curl);


    //curl_easy_setopt(curl, CURLOPT_URL, "А004 LIST \"/\" *");
    //curl_easy_setopt(curl, CURLOPT_URL, "STATUS");
    //curl_easy_setopt(curl, CURLOPT_URL, "SELECT INBOX");
    res = curl_easy_perform(curl);
    cout << res << endl;
  }
 
       
    getch();
    return 0;  
}


пробывал разными способами...но что-то никак не выходит, документацию курил...но что то не очень вкурил smile... 
ПС....и еще вопросик - полученные данные выдергивать из перменной "res"?
PM MAIL WWW   Вверх
borisbn
Дата 24.10.2012, 06:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 2
Всего: 135



Обязательно нужно на сях? Мне недавно нужно было сделать чтение почты по имапу - сделал на питоне. 20 строк с авторизацией, считыванием и раскодированием заголовков и тела письма. Если нужно могу скинуть


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
XaleRS
Дата 24.10.2012, 11:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 14.4.2008

Репутация: нет
Всего: нет



borisbn, 
впринципе язык разработки не особо важен.
Питон знаю правда так..поверхностно, но думаю разберусь smile - если не трудно скиньте пожалуйста (progeralex @ gmail.com)
PM MAIL WWW   Вверх
borisbn
Дата 24.10.2012, 12:52 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 2
Всего: 135



Код

import imaplib
import email
import email.header

def checkMail( mail_server, login, password ):
    messages = []

    m = imaplib.IMAP4( mail_server )
    m.login( login, password )
    m.select()
    resp, mailIds = m.search( None, 'UNSEEN' )
    mailIds = mailIds[ 0 ].split()
    for i in mailIds:
        resp, mailData = m.fetch( i, "(RFC822)" )
        msg = email.message_from_string( mailData[ 0 ][ 1 ] )
        sender = msg.get( 'From' ).replace( '\r\n', ' ' )
        sender = email.header.decode_header( sender )[ 0 ][ 0 ]
        subject = msg.get( 'Subject' ).replace( '\r\n', ' ' )
        subject = email.header.decode_header( subject )[ 0 ][ 0 ]
        messageStr = ""
        for part in msg.walk():
            #print part.keys()
            #for k in part.keys():
            #    print k, ':', part.get( k )
            if not part.get( 'Content-Type' ).startswith( 'text/plain' ):
                continue
            txt = part.get_payload( decode = True )
            if txt != None:
                lines = txt.splitlines()
                for line in lines:
                    messageStr += line + '\n'
        messageStr = messageStr.rstrip()
        messages.append( ( sender, subject, messageStr ) )
    m.close()
    m.logout()
    return messages


если чего не понятно - спрашивай. лучше здесь

Это сообщение отредактировал(а) borisbn - 24.10.2012, 13:13


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
XaleRS
Дата 26.10.2012, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 14.4.2008

Репутация: нет
Всего: нет



Код

#include "stdafx.h"
#include <cstdio>
#include <iostream>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <windows.h>
using namespace std;
#pragma comment(lib, "Ws2_32.lib")
#define BUFSIZE 1024


int _tmain(int argc, _TCHAR* argv[])
{    
char buf[BUFSIZE]; 
char *msg;
WSADATA wsda;
int     sock;
struct hostent *host;
struct sockaddr_in server_addr;
short int       s_port = 143;
const char      *s_ipaddr = "imap.yandex.ru";
WSAStartup(MAKEWORD(2,2), &wsda);
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
  

server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(s_port);
    server_addr.sin_addr.s_addr = inet_addr(s_ipaddr);

    if(server_addr.sin_addr.s_addr == INADDR_NONE)
    {
        host = NULL;
        host = gethostbyname(s_ipaddr);
        if(host == NULL)
        {
            return false;
        }
        memcpy(&server_addr.sin_addr, host->h_addr_list[0], host->h_length);
    }

    
    if (connect(sock, (struct sockaddr *) &server_addr, sizeof(server_addr)))
        {
               printf (" Connect error  %d \n ", WSAGetLastError ( ) );
               getchar();
               return -1;
        }
    ZeroMemory(buf,sizeof(buf));
    recv (sock,buf,sizeof(buf),0);    
    cout << buf << "\n";
    cout << "Logging-in:\n";
    ///////// отправляет комманду логин
    msg = "a001 Login xalers пароль";
    ZeroMemory(buf,sizeof(buf));
    send(sock, msg, strlen(msg), 0);
    cout << msg << "\n";
    recv(sock,buf,sizeof(buf),1);    
    cout << buf << "\n";

////////////////////

    


//cout << "INBOX\n";
//
//    msg = "a004 LIST \"\" *";
//    send (sock, msg, sizeof(msg), 0) ;
//    cout << msg << "\n";
//    ZeroMemory(buf,256);
//    recv (sock,buf,256,0);
//    cout << buf << "\n";
     getchar();
    closesocket(sock);
    WSACleanup();    
    return 0;
}




Решил попрбывать на сокетах еще smile - впринципе соеденение установил (получил сообщение сервера), НО не получается отправить запрос (тот же Лист)... соотвественно не приходит ответ от сервера....подскажите пожалуйста как его заставить работать:)

Это сообщение отредактировал(а) XaleRS - 26.10.2012, 23:01
PM MAIL WWW   Вверх
XaleRS
Дата 26.10.2012, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 14.4.2008

Репутация: нет
Всего: нет



так...залогиниться сумел...надо было по типу "a1 login name pass\r\n" использовать..
с другими коммандами пока проблема ((

добавлено позже....тупанул....две комманды одинаковых отправил)


...кстати...не подскажите как по имап получить кирилицу не абракадаброй?

Это сообщение отредактировал(а) XaleRS - 26.10.2012, 15:17
PM MAIL WWW   Вверх
XaleRS
Дата 17.11.2012, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 14.4.2008

Репутация: нет
Всего: нет



Опять возник вопрос...

написал функцию для чтения сообщения по номеру, но выскакивает ошибка http://s2.ipicture.ru/uploads/20121117/C5PpYCH5.png
вот код: (если убрать символы \r\n, то компилируется норм, но программа соотвественно не работает.
Код

string imap_fetch (int socket, int number)
{
    char *msg;
    char buf1[BUFSIZE];
    msg = strdup ("");
    strcpy(msg,"a005 FETCH ");
    strcat(msg,"10");
    strcat(msg," BODY[HEADER.FIELDS (\"DATE\")]\r\n");
    send (socket, msg, strlen(msg),0);
    ZeroMemory(buf1,sizeof(buf1));
    recv(socket,buf1,sizeof(buf1),0);    
    while (recv(socket,buf1,sizeof(buf1),0) )
        {return buf1;    
            if (strstr(buf1,"completed") ) {break; return 0;};
        }        
}


аналогичная функция (выбора папки) - работает нормально, без ошибок.

Код

string imap_select (int socket, char *folder)
{
    char *msg;
    char buf[BUFSIZE]; 
    msg = strdup ("");
    strcpy(msg,"a002 select ");
    strcat(msg,folder);
    strcat(msg,"\r\n");
    cout << msg << "\n";  
    ZeroMemory(buf,sizeof(buf));
    send (socket, msg, strlen(msg),0);
    while (recv(socket,buf,sizeof(buf),0) )
        {return buf;        
            if (strstr(buf,"completed")) {break; return 0;};
        }    
}

PM MAIL WWW   Вверх
feodorv
Дата 18.11.2012, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(XaleRS @  17.11.2012,  13:59 Найти цитируемый пост)
программа соотвественно не работает.

Ну посмотрите на этот код:
Цитата(XaleRS @  17.11.2012,  13:59 Найти цитируемый пост)
    msg = strdup ("");
    strcpy(msg,"a005 FETCH ");
    strcat(msg,"10");
    strcat(msg," BODY[HEADER.FIELDS (\"DATE\")]\r\n");

Цитата(XaleRS @  17.11.2012,  13:59 Найти цитируемый пост)
    msg = strdup ("");
    strcpy(msg,"a002 select ");
    strcat(msg,folder);
    strcat(msg,"\r\n");



Что здесь происходит? Под строчку "" в куче выделяется память с гранулярностью кучи (8 или 16 байт), а потом в эту память (ограниченную по размеру этими 8-ю или 16-ю байтами) начинается запихивание разных других строк. Память, выделенная в куче для msg, в конце концов заканчивается, происходит выход за её пределы и в результате - порча кучи, о чём и сообщается. 

Так делать нельзя. Нужно заранее выделять необходимый объём памяти. Или вообще не связываться с выделением памяти, а использовать стековую память.


Запрашиваемую память потом нужно высвобождать (через free). Стековый буфер возвращать никак нельзя:
Цитата(XaleRS @  17.11.2012,  13:59 Найти цитируемый пост)
string imap_select (int socket, char *folder)
{
     ....
    char buf[BUFSIZE]; 
    ...
    while (recv(socket,buf,sizeof(buf),0) )
        {return buf;        
            ....  // <- а это вообще не будет выполнено
        }    
}



Это сообщение отредактировал(а) feodorv - 18.11.2012, 13:49


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
XaleRS
Дата 18.11.2012, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 14.4.2008

Репутация: нет
Всего: нет



feodorv, 
спасибо за совет, буду дальше думать smile
PM MAIL WWW   Вверх
feodorv
Дата 18.11.2012, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(feodorv @  18.11.2012,  14:47 Найти цитируемый пост)
Стековый буфер возвращать никак нельзя

Аааа smile Не заметил, что у Вас там string возвращается. Тогда, может, и можно, но эту string всё равно высвобождать нужно будет.
Ну, если уж пользоваться string, то пользоваться до конца. Отказывайтесь от strdup и strcat, переходите на string  smile

Добавлено через 3 минуты и 22 секунды
И мне не нравится то, что buf не ноль-терминирован...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
XaleRS
Дата 22.11.2012, 22:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 14.4.2008

Репутация: нет
Всего: нет



feodorv, 
ок)) будем менять)
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0518 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.