~ubuntu-branches/ubuntu/maverick/evolution-data-server/maverick-proposed

« back to all changes in this revision

Viewing changes to libdb/examples_c/ex_repquote/ex_rq_main.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-05-17 17:02:06 UTC
  • mfrom: (1.1.79 upstream) (1.6.12 experimental)
  • Revision ID: james.westby@ubuntu.com-20100517170206-4ufr52vwrhh26yh0
Tags: 2.30.1-1ubuntu1
* Merge from debian experimental. Remaining change:
  (LP: #42199, #229669, #173703, #360344, #508494)
  + debian/control:
    - add Vcs-Bzr tag
    - don't use libgnome
    - Use Breaks instead of Conflicts against evolution 2.25 and earlier.
  + debian/evolution-data-server.install,
    debian/patches/45_libcamel_providers_version.patch:
    - use the upstream versioning, not a Debian-specific one 
  + debian/libedata-book1.2-dev.install, debian/libebackend-1.2-dev.install,
    debian/libcamel1.2-dev.install, debian/libedataserverui1.2-dev.install:
    - install html documentation
  + debian/rules:
    - don't build documentation it's shipped with the tarball

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*-
2
 
 * See the file LICENSE for redistribution information.
3
 
 *
4
 
 * Copyright (c) 2001-2002
5
 
 *      Sleepycat Software.  All rights reserved.
6
 
 *
7
 
 * $Id$
8
 
 */
9
 
 
10
 
#include <sys/types.h>
11
 
#include <pthread.h>
12
 
 
13
 
#include <errno.h>
14
 
#include <signal.h>
15
 
#include <stdlib.h>
16
 
#include <string.h>
17
 
#include <unistd.h>
18
 
 
19
 
#include <db.h>
20
 
 
21
 
#include "ex_repquote.h"
22
 
 
23
 
/*
24
 
 * Process globals (we could put these in the machtab I suppose.
25
 
 */
26
 
int master_eid;
27
 
char *myaddr;
28
 
 
29
 
static int env_init __P((const char *, const char *, DB_ENV **, machtab_t *,
30
 
    u_int32_t));
31
 
static void usage __P((const char *));
32
 
 
33
 
int
34
 
main(argc, argv)
35
 
        int argc;
36
 
        char *argv[];
37
 
{
38
 
        extern char *optarg;
39
 
        extern int optind;
40
 
        DB_ENV *dbenv;
41
 
        DBT local;
42
 
        enum { MASTER, CLIENT, UNKNOWN } whoami;
43
 
        all_args aa;
44
 
        connect_args ca;
45
 
        machtab_t *machtab;
46
 
        pthread_t all_thr, conn_thr;
47
 
        repsite_t site, *sitep, self, *selfp;
48
 
        struct sigaction sigact;
49
 
        int maxsites, nsites, ret, priority, totalsites;
50
 
        char *c, ch;
51
 
        const char *home, *progname;
52
 
        void *astatus, *cstatus;
53
 
 
54
 
        master_eid = DB_EID_INVALID;
55
 
 
56
 
        dbenv = NULL;
57
 
        whoami = UNKNOWN;
58
 
        machtab = NULL;
59
 
        selfp = sitep = NULL;
60
 
        maxsites = nsites = ret = totalsites = 0;
61
 
        priority = 100;
62
 
        home = "TESTDIR";
63
 
        progname = "ex_repquote";
64
 
 
65
 
        while ((ch = getopt(argc, argv, "Ch:Mm:n:o:p:")) != EOF)
66
 
                switch (ch) {
67
 
                case 'M':
68
 
                        whoami = MASTER;
69
 
                        master_eid = SELF_EID;
70
 
                        break;
71
 
                case 'C':
72
 
                        whoami = CLIENT;
73
 
                        break;
74
 
                case 'h':
75
 
                        home = optarg;
76
 
                        break;
77
 
                case 'm':
78
 
                        if ((myaddr = strdup(optarg)) == NULL) {
79
 
                                fprintf(stderr,
80
 
                                    "System error %s\n", strerror(errno));
81
 
                                goto err;
82
 
                        }
83
 
                        self.host = optarg;
84
 
                        self.host = strtok(self.host, ":");
85
 
                        if ((c = strtok(NULL, ":")) == NULL) {
86
 
                                fprintf(stderr, "Bad host specification.\n");
87
 
                                goto err;
88
 
                        }
89
 
                        self.port = atoi(c);
90
 
                        selfp = &self;
91
 
                        break;
92
 
                case 'n':
93
 
                        totalsites = atoi(optarg);
94
 
                        break;
95
 
                case 'o':
96
 
                        site.host = optarg;
97
 
                        site.host = strtok(site.host, ":");
98
 
                        if ((c = strtok(NULL, ":")) == NULL) {
99
 
                                fprintf(stderr, "Bad host specification.\n");
100
 
                                goto err;
101
 
                        }
102
 
                        site.port = atoi(c);
103
 
                        if (sitep == NULL || nsites >= maxsites) {
104
 
                                maxsites = maxsites == 0 ? 10 : 2 * maxsites;
105
 
                                if ((sitep = realloc(sitep,
106
 
                                    maxsites * sizeof(repsite_t))) == NULL) {
107
 
                                        fprintf(stderr, "System error %s\n",
108
 
                                            strerror(errno));
109
 
                                        goto err;
110
 
                                }
111
 
                        }
112
 
                        sitep[nsites++] = site;
113
 
                        break;
114
 
                case 'p':
115
 
                        priority = atoi(optarg);
116
 
                        break;
117
 
                case '?':
118
 
                default:
119
 
                        usage(progname);
120
 
                }
121
 
 
122
 
        /* Error check command line. */
123
 
        if (whoami == UNKNOWN) {
124
 
                fprintf(stderr, "Must specify -M or -C.\n");
125
 
                goto err;
126
 
        }
127
 
 
128
 
        if (selfp == NULL)
129
 
                usage(progname);
130
 
 
131
 
        if (home == NULL)
132
 
                usage(progname);
133
 
 
134
 
        /*
135
 
         * Turn off SIGPIPE so that we don't kill processes when they
136
 
         * happen to lose a connection at the wrong time.
137
 
         */
138
 
        memset(&sigact, 0, sizeof(sigact));
139
 
        sigact.sa_handler = SIG_IGN;
140
 
        if ((ret = sigaction(SIGPIPE, &sigact, NULL)) != 0) {
141
 
                fprintf(stderr,
142
 
                    "Unable to turn off SIGPIPE: %s\n", strerror(ret));
143
 
                goto err;
144
 
        }
145
 
 
146
 
        /*
147
 
         * We are hardcoding priorities here that all clients have the
148
 
         * same priority except for a designated master who gets a higher
149
 
         * priority.
150
 
         */
151
 
        if ((ret =
152
 
            machtab_init(&machtab, priority, totalsites)) != 0)
153
 
                goto err;
154
 
 
155
 
        /*
156
 
         * We can know open our environment, although we're not ready to
157
 
         * begin replicating.  However, we want to have a dbenv around
158
 
         * so that we can send it into any of our message handlers.
159
 
         */
160
 
        if ((ret = env_init(progname, home, &dbenv, machtab, DB_RECOVER)) != 0)
161
 
                goto err;
162
 
 
163
 
        /*
164
 
         * Now sets up comm infrastructure.  There are two phases.  First,
165
 
         * we open our port for listening for incoming connections.  Then
166
 
         * we attempt to connect to every host we know about.
167
 
         */
168
 
 
169
 
        ca.dbenv = dbenv;
170
 
        ca.home = home;
171
 
        ca.progname = progname;
172
 
        ca.machtab = machtab;
173
 
        ca.port = selfp->port;
174
 
        if ((ret = pthread_create(&conn_thr, NULL, connect_thread, &ca)) != 0)
175
 
                goto err;
176
 
 
177
 
        aa.dbenv = dbenv;
178
 
        aa.progname = progname;
179
 
        aa.home = home;
180
 
        aa.machtab = machtab;
181
 
        aa.sites = sitep;
182
 
        aa.nsites = nsites;
183
 
        if ((ret = pthread_create(&all_thr, NULL, connect_all, &aa)) != 0)
184
 
                goto err;
185
 
 
186
 
        /*
187
 
         * We have now got the entire communication infrastructure set up.
188
 
         * It's time to declare ourselves to be a client or master.
189
 
         */
190
 
        if (whoami == MASTER) {
191
 
                if ((ret = dbenv->rep_start(dbenv, NULL, DB_REP_MASTER)) != 0) {
192
 
                        dbenv->err(dbenv, ret, "dbenv->rep_start failed");
193
 
                        goto err;
194
 
                }
195
 
                if ((ret = domaster(dbenv, progname)) != 0) {
196
 
                        dbenv->err(dbenv, ret, "Master failed");
197
 
                        goto err;
198
 
                }
199
 
        } else {
200
 
                memset(&local, 0, sizeof(local));
201
 
                local.data = myaddr;
202
 
                local.size = strlen(myaddr) + 1;
203
 
                if ((ret =
204
 
                    dbenv->rep_start(dbenv, &local, DB_REP_CLIENT)) != 0) {
205
 
                        dbenv->err(dbenv, ret, "dbenv->rep_start failed");
206
 
                        goto err;
207
 
                }
208
 
                /* Sleep to give ourselves a minute to find a master. */
209
 
                sleep(5);
210
 
                if ((ret = doclient(dbenv, progname, machtab)) != 0) {
211
 
                        dbenv->err(dbenv, ret, "Client failed");
212
 
                        goto err;
213
 
                }
214
 
 
215
 
        }
216
 
 
217
 
        /* Wait on the connection threads. */
218
 
        if (pthread_join(all_thr, &astatus) || pthread_join(conn_thr, &cstatus))
219
 
                ret = errno;
220
 
        if (ret == 0 &&
221
 
            ((int)astatus != EXIT_SUCCESS || (int)cstatus != EXIT_SUCCESS))
222
 
                ret = -1;
223
 
 
224
 
err:    if (machtab != NULL)
225
 
                free(machtab);
226
 
        if (dbenv != NULL)
227
 
                (void)dbenv->close(dbenv, 0);
228
 
        return (ret);
229
 
}
230
 
 
231
 
/*
232
 
 * In this application, we specify all communication via the command line.
233
 
 * In a real application, we would expect that information about the other
234
 
 * sites in the system would be maintained in some sort of configuration
235
 
 * file.  The critical part of this interface is that we assume at startup
236
 
 * that we can find out 1) what host/port we wish to listen on for connections,
237
 
 * 2) a (possibly empty) list of other sites we should attempt to connect to.
238
 
 * 3) whether we are a master or client (if we don't know, we should come up
239
 
 * as a client and see if there is a master out there) and 4) what our
240
 
 * Berkeley DB home environment is.
241
 
 *
242
 
 * These pieces of information are expressed by the following flags.
243
 
 * -m host:port (required; m stands for me)
244
 
 * -o host:port (optional; o stands for other; any number of these may be
245
 
 *      specified)
246
 
 * -[MC] M for master/C for client
247
 
 * -h home directory
248
 
 * -n nsites (optional; number of sites in replication group; defaults to 0
249
 
 *      in which case we try to dynamically compute the number of sites in
250
 
 *      the replication group.)
251
 
 * -p priority (optional: defaults to 100)
252
 
 */
253
 
static void
254
 
usage(progname)
255
 
        const char *progname;
256
 
{
257
 
        fprintf(stderr, "usage: %s ", progname);
258
 
        fprintf(stderr, "[-CM][-h home][-o host:port][-m host:port]%s",
259
 
            "[-n nsites][-p priority]\n");
260
 
        exit(EXIT_FAILURE);
261
 
}
262
 
 
263
 
/* Open and configure an environment.  */
264
 
int
265
 
env_init(progname, home, dbenvp, machtab, flags)
266
 
        const char *progname, *home;
267
 
        DB_ENV **dbenvp;
268
 
        machtab_t *machtab;
269
 
        u_int32_t flags;
270
 
{
271
 
        DB_ENV *dbenv;
272
 
        int ret;
273
 
        char *prefix;
274
 
 
275
 
        if ((prefix = malloc(strlen(progname) + 2)) == NULL) {
276
 
                fprintf(stderr,
277
 
                    "%s: System error: %s\n", progname, strerror(errno));
278
 
                return (errno);
279
 
        }
280
 
        sprintf(prefix, "%s:", progname);
281
 
 
282
 
        if ((ret = db_env_create(&dbenv, 0)) != 0) {
283
 
                fprintf(stderr, "%s: env create failed: %s\n",
284
 
                    progname, db_strerror(ret));
285
 
                return (ret);
286
 
        }
287
 
        dbenv->set_errfile(dbenv, stderr);
288
 
        dbenv->set_errpfx(dbenv, prefix);
289
 
        /* (void)dbenv->set_verbose(dbenv, DB_VERB_REPLICATION, 1); */
290
 
        (void)dbenv->set_cachesize(dbenv, 0, CACHESIZE, 0);
291
 
        /* (void)dbenv->set_flags(dbenv, DB_TXN_NOSYNC, 1); */
292
 
 
293
 
        dbenv->app_private = machtab;
294
 
        (void)dbenv->set_rep_transport(dbenv, SELF_EID, quote_send);
295
 
 
296
 
        flags |= DB_CREATE | DB_THREAD |
297
 
            DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN;
298
 
 
299
 
        ret = dbenv->open(dbenv, home, flags, 0);
300
 
 
301
 
        *dbenvp = dbenv;
302
 
        return (ret);
303
 
}