Thanks for your kind reply. The attachment is a simple example show eventpool 
file descriptor leak, please check, thanks.
Run following command compile this example.
 # gcc -Wall -I /usr/local/samba/include/ exmain.c -L /usr/local/samba/lib/ 
-lmapi
 # ./a.out
 # lsof -p $(pgrep a.out) 
 
 
>> The calling sequence as follows:
>> 
>> MAPIInitialize->MapiLogonEx->OpenMsgStore->...->mapi_object_release->MAPIUn
>> initialize
>Can you show a simple compilable example that reproduces the problem?
>
>Brad
>
>[BTW: I got your private email, but your provider won't accept mail that 
>doesn't have SPF.]



#include <unistd.h>
#include <stdio.h>
#include <inttypes.h>
#include <pthread.h>

#include <talloc.h>
#include <libmapi/libmapi.h>

// # gcc -Wall -I /usr/local/samba/include/ exmain.c -L /usr/local/samba/lib/ 
-lmapi
// # ./a.out
// # lsof -p $(pgrep a.out)

#define DEFAULT_PROFDB_LOCATION             "/tmp"
#define DEFAULT_PROFDB_FILE                 "profiles.ldb"
#define DEFAULT_EXCHANGE_VERSION_NUMBER     0


struct exClient {
        char            username[32];      // generated by email
        char            password[32];
        char            serverip[20];
        char            emailaddress[48];  // [email protected]        
        char            *profname;         // equal to username
        char            *profdb;           // generated by domain
        char            *domain;           // generated by emailaddress
        unsigned int    n_curmailcount;

        struct mapi_context                 *m_mapi_ctx;   // MAPI context
        struct mapi_session             *m_session;    // Login Session 
};

void init_exclient(struct exClient *oclient)
{
        memset (oclient->username, 0, sizeof(oclient->username));
        memset (oclient->password, 0, sizeof(oclient->password));
        memset (oclient->emailaddress, 0, sizeof(oclient->emailaddress));
        memset (oclient->serverip, 0, sizeof(oclient->serverip));

        oclient->profname         = NULL;
        oclient->profdb           = NULL;
        oclient->domain           = NULL;
        oclient->n_curmailcount   = -1;

        oclient->m_mapi_ctx       = NULL;
        oclient->m_session        = NULL;       
}

int gen_exclient(struct exClient* oclient,
        const char* emailaddress, const char* password, const char* serveraddr,
        const char* profdb_location)
{
        strncpy (oclient->emailaddress, emailaddress, 
sizeof(oclient->emailaddress));
        strncpy (oclient->password, password, sizeof(oclient->password));
        strncpy (oclient->serverip, serveraddr, sizeof(oclient->serverip));

        int length;
        const char* delim = "@";
        char  profbuffer[256] = "\0", email[64] = "\0", *p;
        strncpy (email, emailaddress, sizeof(email));
        if ((p = strtok (email, delim)) != NULL) {
                strncpy (oclient->username, p, sizeof(oclient->username));
        }
        
        oclient->profname = oclient->username;
        if ((oclient->domain= strpbrk (oclient->emailaddress, delim)) != NULL) {
                oclient->domain++;
        }
        else {
                printf("email:%s Invalid mail address !", emailaddress);
                return 1;
        }

        if (profdb_location != NULL) {
                sprintf (profbuffer, "%s/%s.%s", profdb_location, 
oclient->domain, DEFAULT_PROFDB_FILE);
        }
        else {
                sprintf (profbuffer, "%s/%s.%s", DEFAULT_PROFDB_LOCATION, 
oclient->domain, DEFAULT_PROFDB_FILE);
        }               
        length = strlen(profbuffer);
        oclient->profdb = malloc (length+1);
        strcpy (oclient->profdb, profbuffer);
        oclient->profdb[length] = 0;

        return 0;
}

void dump_exclient(const struct exClient* oclient)
{
        printf ("\n");
        printf ("username       : %s\n", oclient->username);
        printf ("password       : %s\n", oclient->password);
        printf ("serverip       : %s\n", oclient->serverip);
        printf ("email          : %s\n", oclient->emailaddress);
        printf ("profname       : %s\n", oclient->profname);
        printf ("profdb         : %s\n", oclient->profdb);
        printf ("domain         : %s\n", oclient->domain);
}

static uint32_t callback(struct SRowSet *rowset, void *private)
{
        uint32_t                  i;
        struct SPropValue *lpProp;
        const char                *label = "username checked matches several 
usernames, select the first one";

        printf("Warning: %s:", label);
        for (i = 0; i < rowset->cRows; i++) {
                lpProp = get_SPropValue_SRow(&(rowset->aRow[i]), 
PR_DISPLAY_NAME);
                if (lpProp && lpProp->value.lpszA) {
                        printf("\t[%u] %s", i, lpProp->value.lpszA);
                }
        }
        
        return 0;
}

bool profcreate(const struct exClient * oclient, uint32_t flags)
{
        enum MAPISTATUS         retval;
        struct mapi_context     *mapi_ctx;
        struct mapi_session     *session = NULL;
        TALLOC_CTX              *mem_ctx;
        struct mapi_profile     profile;
        const char              *locale;
        uint32_t                cpid;
        uint32_t                lcid;
        char                    *cpid_str;
        char                    *lcid_str;
        char            workstation[128] = "\0";
        char                    exchange_version_str[8];

        mem_ctx = talloc_named(NULL, 0, "profcreate");

        retval = MAPIInitialize(&mapi_ctx, oclient->profdb);
        if (retval != MAPI_E_SUCCESS) {
                printf ("email:%s <profcreate> MAPIInitialize error: 0x%X\n", 
oclient->emailaddress,retval);
                talloc_free(mem_ctx);
                return false;
        }

        /* Sanity check */
        retval = OpenProfile(mapi_ctx, &profile, oclient->profname, NULL);
        if (retval == MAPI_E_SUCCESS) {
                printf("email:%s <profcreate> profile \"%s\" already exists\n", 
oclient->emailaddress,oclient->profname);
                MAPIUninitialize(mapi_ctx);
                talloc_free(mem_ctx);
                return true;
        }

        retval = CreateProfile(mapi_ctx, oclient->profname, oclient->username, 
oclient->password, flags);
        if (retval != MAPI_E_SUCCESS) {
                printf ("email:%s <profcreate> CreateProfile error: 0x%X\n", 
oclient->emailaddress,retval);
                MAPIUninitialize(mapi_ctx);
                talloc_free(mem_ctx);
                return false;
        }

        gethostname(workstation, sizeof(workstation));
        sprintf (exchange_version_str, "%d", DEFAULT_EXCHANGE_VERSION_NUMBER);
        mapi_profile_add_string_attr(mapi_ctx, oclient->profname, "binding", 
oclient->serverip);
        mapi_profile_add_string_attr(mapi_ctx, oclient->profname, "domain",  
oclient->domain);
        mapi_profile_add_string_attr(mapi_ctx, oclient->profname, 
"workstation", workstation);
        mapi_profile_add_string_attr(mapi_ctx, oclient->profname, "seal", 
"false");
        mapi_profile_add_string_attr(mapi_ctx, oclient->profname, 
"exchange_version", exchange_version_str);

        locale = mapi_get_system_locale();
        if (locale) {
                cpid = mapi_get_cpid_from_locale(locale);
                lcid = mapi_get_lcid_from_locale(locale);
        }

        if (!locale || !cpid || !lcid) {
                printf("email:%s <profcreate> Invalid Language supplied or 
unknown system language\nDeleting profile\n",oclient->emailaddress);
                if ((retval = DeleteProfile(mapi_ctx, oclient->profname)) != 
MAPI_E_SUCCESS) {
                        printf("email:%s <profcreate> DeleteProfile error: 
0x%X\n", oclient->emailaddress,retval);
                }
                talloc_free(mem_ctx);
                MAPIUninitialize(mapi_ctx);
                return false;
        }

        cpid_str = talloc_asprintf(mem_ctx, "%d", cpid);
        lcid_str = talloc_asprintf(mem_ctx, "0x%.4x", lcid);

        mapi_profile_add_string_attr(mapi_ctx, oclient->profname, "codepage", 
cpid_str);
        mapi_profile_add_string_attr(mapi_ctx, oclient->profname, "language", 
lcid_str);
        mapi_profile_add_string_attr(mapi_ctx, oclient->profname, "method", 
lcid_str);

        talloc_free(cpid_str);
        talloc_free(lcid_str);

        retval = MapiLogonProvider(mapi_ctx, &session, oclient->profname, 
oclient->password, PROVIDER_ID_NSPI);
        if (retval != MAPI_E_SUCCESS) {
                printf("email:%s <profcreate> MapiLogonProvider error: 
0x%X\nDeleting profile\n", oclient->emailaddress,retval);
                if ((retval = DeleteProfile(mapi_ctx, oclient->profname)) != 
MAPI_E_SUCCESS) {
                        printf("email:%s <profcreate> DeleteProfile error: 
0x%X\n", oclient->emailaddress,retval);
                }
                MAPIUninitialize(mapi_ctx);
                talloc_free(mem_ctx);

                return false;
        }

        retval = ProcessNetworkProfile(session, oclient->username, 
(mapi_profile_callback_t) callback, NULL);
        if (retval != MAPI_E_SUCCESS && retval != 0x1) {
                printf("email:%s <profcreate> ProcessNetworkProfile error: 
0x%X\nDeleting profile\n", oclient->emailaddress,retval);
                if ((retval = DeleteProfile(mapi_ctx, oclient->profname)) != 
MAPI_E_SUCCESS) {
                        printf("email:%s <profcreate> DeleteProfile error: 
0x%X\n", oclient->emailaddress,retval);
                }
                MAPIUninitialize(mapi_ctx);
                talloc_free(mem_ctx);
                return false;
        }

        MAPIUninitialize(mapi_ctx);
        talloc_free(mem_ctx);   
        return true;
}

bool proflookup(const struct exClient * oclient)
{
        enum MAPISTATUS     retval;
        struct mapi_context *mapi_ctx;
        struct mapi_profile profile;

        if ((retval = MAPIInitialize(&mapi_ctx, oclient->profdb)) != 
MAPI_E_SUCCESS) {
                printf("email:%s <proflookup> MAPIInitialize error : 0x%X\n", 
oclient->emailaddress,retval);
                return false;
        }

        retval  = OpenProfile(mapi_ctx, &profile, oclient->profname, NULL);
        if (retval != MAPI_E_SUCCESS) {
                MAPIUninitialize(mapi_ctx);
                if(retval != MAPI_E_INVALID_PARAMETER) {
                        printf("email:%s <proflookup> OpenProfile error : 
0x%X\n", oclient->emailaddress,retval);
                }
                else 
                        printf("email:%s <proflookup> OpenProfile error : 
MAPI_E_INVALID_PARAMETER\n",oclient->emailaddress);
                return false;
        }

        MAPIUninitialize(mapi_ctx);
        return true;
}


int loginserver(struct exClient *oclient)
{
        enum MAPISTATUS                 retval;
        bool                            need_profcreate = false;
        
        // Check profile database exists
        if (access(oclient->profdb, F_OK) != 0) {
                need_profcreate = true;
        }
        // Check specific user's profile exists
        if (!proflookup(oclient) != 0) {
                need_profcreate = true;
        }
        // If profile database or specific user's profile not exist, create it
        if (need_profcreate) {
                if (!profcreate(oclient, 0)) {
                        printf ("email:%s <loginserver> create profile 
failed.\n", oclient->emailaddress);
                        return -1;
                }
                else {
                        printf ("Profile \"%s\" completed and added to 
database.\n",    oclient->profname);
                }
        }

        // Initialize MAPI
        retval = MAPIInitialize(&(oclient->m_mapi_ctx), oclient->profdb);
        if (retval != MAPI_E_SUCCESS) {
                printf ("email:%s <loginserver> Initialize MAPI failed: 
0x%X\n", oclient->emailaddress,retval);
                return -1;
        }

        // Log on EMSMDB and NSPI
        retval = MapiLogonEx(oclient->m_mapi_ctx, &(oclient->m_session), 
oclient->profname, NULL);
        if (retval != MAPI_E_SUCCESS) {
                MAPIUninitialize(oclient->m_mapi_ctx);
                printf("email:%s <loginserver> Logon EMSMDB and NSPI failed: 
0x%X\n", oclient->emailaddress,retval);
                return -1;
        }
        
        return 0;
}


int fetchmail(struct exClient *oclient)
{
        enum MAPISTATUS                 retval;
        TALLOC_CTX                      *mem_ctx;
        mapi_id_t                                               id_inbox;
        
        mapi_object_t                   obj_store;      
        mapi_object_t                                   obj_inbox;
        mapi_object_t                                   obj_table;
        
        struct SRowSet                                  rowset;
        struct SPropTagArray                    *SPropTagArray;

        uint32_t                                    i, ret=0, mailcount=0, 
newmail=0;
        const uint64_t                      *mid;
        const char                          *subject;
        char                            subject_show[10] = "\0";

        mem_ctx = talloc_named(NULL, 0, "fetchmail");

        printf ("email:%s Fetch mail from exchange server, Open Message 
Store.\n", oclient->emailaddress);
        // Open Message Store
        mapi_object_init(&obj_store);
        retval = OpenMsgStore(oclient->m_session, &obj_store);
        if (retval != MAPI_E_SUCCESS) {
                talloc_free(mem_ctx);
                printf("email:%s <fetchmail> OpenMsgStore error: 0x%X\n", 
oclient->emailaddress,retval);
                return 1;
        }

        // Find Inbox default folder
        retval = GetDefaultFolder(&obj_store, &id_inbox, olFolderInbox);
        if (retval != MAPI_E_SUCCESS) {
                mapi_object_release(&obj_store);
                talloc_free(mem_ctx);
                printf("email:%s <fetchmail> GetDefaultFolder error: 0x%X\n", 
oclient->emailaddress,retval);
                return 1;
        }

        // Open Inbox folder
        mapi_object_init(&obj_inbox);
        retval = OpenFolder(&obj_store, id_inbox, &obj_inbox);
        if (retval != MAPI_E_SUCCESS) {
                mapi_object_release(&obj_store);
                talloc_free(mem_ctx);
                printf("email:%s <fetchmail> OpenFolder error: 0x%X\n", 
oclient->emailaddress,retval);
                return 1;
        }

        // Retrieve Inbox content table
        mapi_object_init(&obj_table);
        retval = GetContentsTable(&obj_inbox, &obj_table, 0, &mailcount);
        if (retval != MAPI_E_SUCCESS) {
                mapi_object_release(&obj_inbox);
                mapi_object_release(&obj_store);                
                talloc_free(mem_ctx);
                printf("email:%s <fetchmail> GetContentsTable error: 0x%X\n", 
oclient->emailaddress,retval);
                return 1;
        }
        if (mailcount<=oclient->n_curmailcount || oclient->n_curmailcount==-1) {
                ret = 0;
                if (oclient->n_curmailcount == -1) oclient->n_curmailcount = 
mailcount; // first login
                if (mailcount < oclient->n_curmailcount) {
                        oclient->n_curmailcount = mailcount; // update current 
mail count
                        printf ("email:%s Current inbox mail count: %d, 
DECREASED\n", oclient->emailaddress, mailcount);
                }
                else {
                        printf ("email:%s Current inbox mail count: %d, 
UNCHANGED\n", oclient->emailaddress, mailcount);
                }
                goto end;
        }
        
        newmail = mailcount - oclient->n_curmailcount;
        oclient->n_curmailcount = mailcount;
        printf ("email:%s Current inbox mail count: %d, %d New 
Mail:\n",oclient->emailaddress, mailcount, newmail);

        // Create the MAPI table view
        SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_MID, PR_SUBJECT);
        retval = SetColumns(&obj_table, SPropTagArray);
        MAPIFreeBuffer(SPropTagArray);
        if (retval != MAPI_E_SUCCESS) {
                ret = 1;
                printf("email:%s <fetchmail> SetColumns error: 0x%X\n", 
oclient->emailaddress,retval);
                goto end;
        }

        // Iterate through rows 
        while ((retval = QueryRows(&obj_table, 0x32, TBL_ADVANCE, &rowset)) 
                != -1 && rowset.cRows) {
                int n = newmail<rowset.cRows ? newmail : rowset.cRows;
                for (i = 0; i < n; i++) {
                        mid     = (const uint64_t 
*)find_SPropValue_data(&rowset.aRow[i], PR_MID);
                        subject = (const char 
*)find_SPropValue_data(&rowset.aRow[i], PR_SUBJECT);
                        if (subject == NULL)
                                strcpy(subject_show, "null");
                        else 
                                strncpy(subject_show, subject, 6);
                        if (strlen (subject_show) == 6) {
                                strcat (subject_show, "...");
                                subject_show[9] = 0;
                        }                               
                        printf("  subject: %s [MID: 0x%016"PRIx64"]\n", 
subject_show, mid?*mid:0);
                }
        }
        
end:
        // Note: release sequence is very important
        mapi_object_release(&obj_table);
        mapi_object_release(&obj_inbox);
        mapi_object_release(&obj_store);
        talloc_free(mem_ctx);

        MAPIUninitialize(oclient->m_mapi_ctx);
        
        return ret;
}

void* simple_thread(void* param)
{

        struct exClient* client = (struct exClient*)param;

        dump_exclient(client);
        while (true) {
                if (loginserver(client) != 0) break;
                if (fetchmail(client) != 0)   break;

                sleep (5);
        }
        return NULL;
}

int main(int argc, char *argv[])
{
        struct exClient oclient;
        init_exclient(&oclient);
        if (gen_exclient (&oclient, "[email protected]", 
"hesine-01", "172.27.235.199", NULL))
                return 1;
        dump_exclient(&oclient);

        pthread_t      th;
        pthread_attr_t thattr;
        pthread_attr_init(&thattr);
        pthread_create(&th, &thattr, simple_thread, &oclient);

        pthread_join (th, NULL);        

        return 0;
}

_______________________________________________
devel mailing list
[email protected]
http://mailman.openchange.org/listinfo/devel

Reply via email to