~ubuntu-branches/debian/sid/openchange/sid

« back to all changes in this revision

Viewing changes to .pc/03_no_popt/utils/mapitest/mapitest.c

  • Committer: Package Import Robot
  • Author(s): Jelmer Vernooij
  • Date: 2012-04-12 20:07:57 UTC
  • mfrom: (11 sid)
  • mto: This revision was merged to the branch mainline in revision 12.
  • Revision ID: package-import@ubuntu.com-20120412200757-k933d9trljmxj1l4
Tags: 1:1.0-4
* openchangeserver: Add dependency on openchangeproxy.
* Rebuild against newer version of Samba 4.
* Use dpkg-buildflags.
* Migrate to Git, update Vcs-Git header.
* Switch to debhelper 9.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Stand-alone MAPI testsuite
 
3
 
 
4
   OpenChange Project
 
5
 
 
6
   Copyright (C) Julien Kerihuel 2008
 
7
 
 
8
   This program is free software; you can redistribute it and/or modify
 
9
   it under the terms of the GNU General Public License as published by
 
10
   the Free Software Foundation; either version 3 of the License, or
 
11
   (at your option) any later version.
 
12
   
 
13
   This program is distributed in the hope that it will be useful,
 
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
   GNU General Public License for more details.
 
17
   
 
18
   You should have received a copy of the GNU General Public License
 
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
20
*/
 
21
 
 
22
#include "utils/mapitest/mapitest.h"
 
23
#include "utils/openchange-tools.h"
 
24
 
 
25
#include <samba/popt.h>
 
26
#include <param.h>
 
27
 
 
28
#include "config.h"
 
29
 
 
30
/**
 
31
        \file
 
32
        Core of %mapitest implementation
 
33
*/
 
34
 
 
35
/**
 
36
   Initialize %mapitest structure
 
37
 */
 
38
static void mapitest_init(TALLOC_CTX *mem_ctx, struct mapitest *mt)
 
39
{
 
40
        mt->mem_ctx = mem_ctx;
 
41
        mt->stream = NULL;
 
42
        memset(&mt->info, 0, sizeof (mt->info));
 
43
        mt->session = NULL;
 
44
 
 
45
        mt->session = NULL;
 
46
        mt->mapi_all = true;
 
47
        mt->confidential = false;
 
48
        mt->no_server = false;
 
49
        mt->color = false;
 
50
        mt->online = false;
 
51
        mt->mapi_suite = false;
 
52
        mt->cmdline_calls = NULL;
 
53
        mt->cmdline_suite = NULL;
 
54
        mt->subunit_output = false;
 
55
}
 
56
 
 
57
/**
 
58
  Initialize %mapitest output stream
 
59
 
 
60
  \param mt pointer to mapitest context
 
61
  \param filename filename to write to (can be null, for output to stdout)
 
62
*/
 
63
static void mapitest_init_stream(struct mapitest *mt, const char *filename)
 
64
{
 
65
        if (filename == NULL) {
 
66
                mt->stream = fdopen(STDOUT_FILENO, "a");
 
67
        } else {
 
68
                mt->stream = fopen(filename, "w+");
 
69
        }
 
70
 
 
71
        if (mt->stream == NULL) {
 
72
                err(errno, "fdopen/fopen");
 
73
        }
 
74
}
 
75
 
 
76
/**
 
77
  Clean up %mapitest output stream
 
78
 
 
79
  \param mt pointer to mapitest context
 
80
*/
 
81
static void mapitest_cleanup_stream(struct mapitest *mt)
 
82
{
 
83
        fclose(mt->stream);
 
84
}
 
85
 
 
86
 
 
87
static bool mapitest_get_testnames(TALLOC_CTX *mem_ctx, struct mapitest *mt,
 
88
                                   const char *parameter)
 
89
{
 
90
        struct mapitest_unit    *el = NULL;
 
91
        char                    *temptok = NULL;
 
92
 
 
93
        if ((temptok = strtok((char *)parameter, ";")) == NULL) {
 
94
                fprintf(stderr, "Invalid testname list [;]\n");
 
95
                return false;
 
96
        }
 
97
 
 
98
        el = talloc_zero(mem_ctx, struct mapitest_unit);
 
99
        el->name = talloc_strdup(mem_ctx, temptok);
 
100
        DLIST_ADD(mt->cmdline_calls, el);
 
101
 
 
102
        while ((temptok = strtok(NULL, ";")) != NULL) {
 
103
                el = talloc_zero(mem_ctx, struct mapitest_unit);
 
104
                el->name = talloc_strdup(mem_ctx, temptok);
 
105
                DLIST_ADD_END(mt->cmdline_calls, el, struct mapitest_unit *);
 
106
        }
 
107
 
 
108
        return true;
 
109
}
 
110
 
 
111
 
 
112
static void mapitest_list(struct mapitest *mt, const char *name)
 
113
{
 
114
        struct mapitest_suite           *sel;
 
115
        struct mapitest_test            *el;
 
116
 
 
117
        /* List all tests */
 
118
        if (!name) {
 
119
                for (sel = mt->mapi_suite; sel; sel = sel->next) {
 
120
                        printf("[*] Suite %s\n", sel->name);
 
121
                        printf("===================================\n");
 
122
                        printf("    * %-15s %s\n", "Name:", sel->name);
 
123
                        printf("    * %-15s %5s\n", "Description:", sel->description);
 
124
                        printf("    * Running Tests:\n");
 
125
                        for (el = sel->tests; el; el = el->next) {
 
126
                                printf("\t    - %-35s: %-10s\n", el->name, el->description);
 
127
                        }
 
128
                        printf("\n\n");
 
129
                }
 
130
        }
 
131
}
 
132
 
 
133
 
 
134
/**
 
135
 * Retrieve server specific information
 
136
 */
 
137
static bool mapitest_get_server_info(struct mapitest *mt,
 
138
                                     char *opt_profname,
 
139
                                     const char *password,
 
140
                                     bool opt_dumpdata,
 
141
                                     const char *opt_debug)
 
142
{
 
143
        TALLOC_CTX              *mem_ctx;
 
144
        enum MAPISTATUS         retval;
 
145
        struct emsmdb_info      *info = NULL;
 
146
        struct mapi_session     *session = NULL;
 
147
 
 
148
        /* if the user explicitly asked for just the no-server tests 
 
149
        to be run, then we're done here */
 
150
        if (mt->no_server == true) return 0;
 
151
 
 
152
        mem_ctx = talloc_named(NULL, 0, "mapitest_get_server_info");
 
153
 
 
154
        /* if no profile was specified, get the default */
 
155
        if (!opt_profname) {
 
156
                retval = GetDefaultProfile(mt->mapi_ctx, &opt_profname);
 
157
                if (retval != MAPI_E_SUCCESS) {
 
158
                        mapi_errstr("GetDefaultProfile", retval);
 
159
                        talloc_free(mem_ctx);
 
160
                        return false;
 
161
                }
 
162
        }
 
163
                
 
164
 
 
165
        /* debug options */
 
166
        SetMAPIDumpData(mt->mapi_ctx, opt_dumpdata);
 
167
 
 
168
        if (opt_debug) {
 
169
                SetMAPIDebugLevel(mt->mapi_ctx, atoi(opt_debug));
 
170
        }
 
171
 
 
172
        retval = MapiLogonEx(mt->mapi_ctx, &session, opt_profname, password);
 
173
        MAPIFreeBuffer(opt_profname);
 
174
        talloc_free(mem_ctx);
 
175
        if (retval != MAPI_E_SUCCESS) {
 
176
                mapi_errstr("MapiLogonEx", retval);
 
177
                return false;
 
178
        }
 
179
        mt->session = session;
 
180
        mt->profile = session->profile;
 
181
 
 
182
        info = emsmdb_get_info(session);
 
183
        memcpy(&mt->info, info, sizeof (struct emsmdb_info));
 
184
 
 
185
        /* extract org and org_unit from info.mailbox */
 
186
        mt->org = x500_get_dn_element(mt->mem_ctx, info->szDNPrefix, "/o=");
 
187
        mt->org_unit = x500_get_dn_element(mt->mem_ctx, info->szDNPrefix, "/ou=");
 
188
        
 
189
        return true;
 
190
}
 
191
 
 
192
 
 
193
 
 
194
/**
 
195
 *  main program
 
196
 */
 
197
int main(int argc, const char *argv[])
 
198
{
 
199
        enum MAPISTATUS         retval;
 
200
        int32_t                 num_tests_failed;
 
201
        TALLOC_CTX              *mem_ctx;
 
202
        struct mapitest         mt;
 
203
        poptContext             pc;
 
204
        int                     opt;
 
205
        bool                    ret;
 
206
        bool                    opt_dumpdata = false;
 
207
        const char              *opt_debug = NULL;
 
208
        const char              *opt_profdb = NULL;
 
209
        char                    *opt_profname = NULL;
 
210
        const char              *opt_password = NULL;
 
211
        const char              *opt_outfile = NULL;
 
212
        char                    *prof_tmp = NULL;
 
213
        bool                    opt_leak_report = false;
 
214
        bool                    opt_leak_report_full = false;
 
215
 
 
216
        enum { OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_PASSWORD,
 
217
               OPT_CONFIDENTIAL, OPT_OUTFILE, OPT_MAPI_CALLS,
 
218
               OPT_NO_SERVER, OPT_LIST_ALL, OPT_DUMP_DATA,
 
219
               OPT_DEBUG, OPT_COLOR, OPT_SUBUNIT, OPT_LEAK_REPORT,
 
220
               OPT_LEAK_REPORT_FULL };
 
221
 
 
222
        struct poptOption long_options[] = {
 
223
                POPT_AUTOHELP
 
224
                { "database",        'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB,       "set the profile database", NULL },
 
225
                { "profile",         'p', POPT_ARG_STRING, NULL, OPT_PROFILE,          "set the profile name", NULL },
 
226
                { "password",        'p', POPT_ARG_STRING, NULL, OPT_PASSWORD,         "set the profile or account password", NULL },
 
227
                { "confidential",      0, POPT_ARG_NONE,   NULL, OPT_CONFIDENTIAL,     "remove any sensitive data from the report", NULL },
 
228
                { "color",             0, POPT_ARG_NONE,   NULL, OPT_COLOR,            "color MAPI retval", NULL },
 
229
#if HAVE_SUBUNIT
 
230
                { "subunit",           0, POPT_ARG_NONE,   NULL, OPT_SUBUNIT,          "output in subunit protocol format", NULL },
 
231
#endif
 
232
                { "outfile",         'o', POPT_ARG_STRING, NULL, OPT_OUTFILE,          "set the report output file", NULL },
 
233
                { "mapi-calls",        0, POPT_ARG_STRING, NULL, OPT_MAPI_CALLS,       "test custom ExchangeRPC tests", NULL },
 
234
                { "list-all",          0, POPT_ARG_NONE,   NULL, OPT_LIST_ALL,         "list suite and tests - names and description", NULL },
 
235
                { "no-server",         0, POPT_ARG_NONE,   NULL, OPT_NO_SERVER,        "only run tests that do not require server connection", NULL },
 
236
                { "dump-data",         0, POPT_ARG_NONE,   NULL, OPT_DUMP_DATA,        "dump the hex data", NULL },
 
237
                { "debuglevel",      'd', POPT_ARG_STRING, NULL, OPT_DEBUG,            "set debug level", NULL },
 
238
                { "leak-report",       0, POPT_ARG_NONE,   NULL, OPT_LEAK_REPORT,      "enable talloc leak reporting on exit", NULL },
 
239
                { "leak-report-full",  0, POPT_ARG_NONE,   NULL, OPT_LEAK_REPORT_FULL, "enable full talloc leak reporting on exit", NULL },
 
240
                POPT_OPENCHANGE_VERSION
 
241
                { NULL, 0, 0, NULL, 0, NULL, NULL }
 
242
        };
 
243
 
 
244
        mem_ctx = talloc_named(NULL, 0, "mapitest");
 
245
        mapitest_init(mem_ctx, &mt);
 
246
        mapitest_register_modules(&mt);
 
247
 
 
248
        pc = poptGetContext("mapitest", argc, argv, long_options, 0);
 
249
 
 
250
        while ((opt = poptGetNextOpt(pc)) != -1) {
 
251
                switch (opt) {
 
252
                case OPT_DUMP_DATA:
 
253
                        opt_dumpdata = true;
 
254
                        break;
 
255
                case OPT_DEBUG:
 
256
                        opt_debug = poptGetOptArg(pc);
 
257
                        break;
 
258
                case OPT_PROFILE_DB:
 
259
                        opt_profdb = poptGetOptArg(pc);
 
260
                        break;
 
261
                case OPT_PROFILE:
 
262
                        prof_tmp = poptGetOptArg(pc);
 
263
                        opt_profname = talloc_strdup(mem_ctx, prof_tmp);
 
264
                        free(prof_tmp);
 
265
                        prof_tmp = NULL;
 
266
                        break;
 
267
                case OPT_PASSWORD:
 
268
                        opt_password = poptGetOptArg(pc);
 
269
                        break;
 
270
                case OPT_CONFIDENTIAL:
 
271
                        mt.confidential = true;
 
272
                        break;
 
273
                case OPT_OUTFILE:
 
274
                        opt_outfile = poptGetOptArg(pc);
 
275
                        break;
 
276
                case OPT_MAPI_CALLS:
 
277
                        ret = mapitest_get_testnames(mem_ctx, &mt, poptGetOptArg(pc));
 
278
                        if (ret == false) exit (-1);
 
279
                        mt.mapi_all = false;
 
280
                        break;
 
281
                case OPT_NO_SERVER:
 
282
                        mt.no_server = true;
 
283
                        break;
 
284
                case OPT_COLOR:
 
285
                        mt.color = true;
 
286
                        break;
 
287
                case OPT_SUBUNIT:
 
288
                        mt.subunit_output = true;
 
289
                        break;
 
290
                case OPT_LIST_ALL:
 
291
                        mapitest_list(&mt, NULL);
 
292
                        talloc_free(mem_ctx);
 
293
                        poptFreeContext(pc);
 
294
                        return 0;
 
295
                        break;
 
296
                case OPT_LEAK_REPORT:
 
297
                        opt_leak_report = true;
 
298
                        talloc_enable_leak_report();
 
299
                        break;
 
300
                case OPT_LEAK_REPORT_FULL:
 
301
                        opt_leak_report_full = true;
 
302
                        talloc_enable_leak_report_full();
 
303
                        break;
 
304
                }
 
305
        }
 
306
 
 
307
        poptFreeContext(pc);
 
308
 
 
309
        /* Sanity check */
 
310
        if (mt.cmdline_calls && (mt.mapi_all == true)) {
 
311
                fprintf(stderr, "mapi-calls and mapi-all can't be set at the same time\n");
 
312
                return -1;
 
313
        }
 
314
 
 
315
        /* Initialize MAPI subsystem */
 
316
        if (!opt_profdb) {
 
317
                opt_profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME"));
 
318
        }
 
319
 
 
320
        retval = MAPIInitialize(&(mt.mapi_ctx), opt_profdb);
 
321
        if (retval != MAPI_E_SUCCESS) {
 
322
                mapi_errstr("MAPIInitialize", retval);
 
323
                return -2;
 
324
        }
 
325
 
 
326
        mapitest_init_stream(&mt, opt_outfile);
 
327
        
 
328
        mt.online = mapitest_get_server_info(&mt, opt_profname, opt_password,
 
329
                                             opt_dumpdata, opt_debug);
 
330
 
 
331
        mapitest_print_headers(&mt);
 
332
 
 
333
        /* Do not run any tests if we couldn't find a profile or if
 
334
         * server is offline and connection to server was implicitly
 
335
         * specified */
 
336
        if (!opt_profname && mt.online == false && mt.no_server == false) {
 
337
                fprintf(stderr, "No MAPI profile found for online tests\n");
 
338
                return -2;
 
339
        }
 
340
 
 
341
        /* Run custom tests */
 
342
        if (mt.cmdline_calls) {
 
343
                struct mapitest_unit    *el;
 
344
                
 
345
                for (el = mt.cmdline_calls; el; el = el->next) {
 
346
                        printf("[*] %s\n", el->name);
 
347
                        mapitest_run_test(&mt, el->name);
 
348
                }
 
349
        } else {
 
350
                mapitest_run_all(&mt);
 
351
        }
 
352
 
 
353
        num_tests_failed = mapitest_stat_dump(&mt);
 
354
 
 
355
        mapitest_cleanup_stream(&mt);
 
356
 
 
357
        /* Uninitialize and free memory */
 
358
        MAPIUninitialize(mt.mapi_ctx);
 
359
        talloc_free(mt.mem_ctx);
 
360
 
 
361
        if (opt_leak_report) {
 
362
                talloc_report(NULL, stdout);
 
363
        }
 
364
 
 
365
        if (opt_leak_report_full) {
 
366
                talloc_report_full(NULL, stdout);
 
367
        }
 
368
 
 
369
        return num_tests_failed;
 
370
}