~ubuntu-branches/debian/stretch/alpine/stretch

« back to all changes in this revision

Viewing changes to pith/adrbklib.h

  • Committer: Bazaar Package Importer
  • Author(s): Asheesh Laroia
  • Date: 2007-02-17 13:17:42 UTC
  • Revision ID: james.westby@ubuntu.com-20070217131742-99x5c6cpg1pbkdhw
Tags: upstream-0.82+dfsg
ImportĀ upstreamĀ versionĀ 0.82+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: adrbklib.h 138 2006-09-22 22:12:03Z mikes@u.washington.edu $
 
3
 *
 
4
 * ========================================================================
 
5
 * Copyright 2006 University of Washington
 
6
 *
 
7
 * Licensed under the Apache License, Version 2.0 (the "License");
 
8
 * you may not use this file except in compliance with the License.
 
9
 * You may obtain a copy of the License at
 
10
 *
 
11
 *     http://www.apache.org/licenses/LICENSE-2.0
 
12
 *
 
13
 * ========================================================================
 
14
 */
 
15
 
 
16
#ifndef PITH_ADRBKLIB_INCLUDED
 
17
#define PITH_ADRBKLIB_INCLUDED
 
18
 
 
19
 
 
20
#include "../pith/indxtype.h"
 
21
#include "../pith/remtype.h"
 
22
#include "../pith/store.h"
 
23
 
 
24
 
 
25
/*
 
26
 *  Some notes:
 
27
 *
 
28
 * The order that the address book is stored in on disk is the order that
 
29
 * the entries will be displayed in. When an address book is opened,
 
30
 * if it is ReadWrite the sort order is checked and it is sorted if it is
 
31
 * out of order.
 
32
 *
 
33
 * Considerable complexity that previously existed in the address book
 
34
 * code has been removed. Cpu speeds have improved significantly and
 
35
 * memory has increased dramatically, as well. The cost of the complexity
 
36
 * of the lookup file and hashtables and all that stuff is thought to be
 
37
 * more than the benefits. See pre-5.00 pine adrbklib.h for the way it
 
38
 * used to be.
 
39
 *
 
40
 * The display code has remained the same.
 
41
 * There is also some allocation happening
 
42
 * in addrbook.c. In particular, the display is a window into an array
 
43
 * of rows, at least one row per addrbook entry plus more for lists.
 
44
 * Each row is an AddrScrn_Disp structure and those should typically take
 
45
 * up 6 or 8 bytes. A cached copy of addrbook entries is not kept, just
 
46
 * the element number to look it up (and often get it out of the EntryRef
 
47
 * cache). In order to avoid having to allocate all those rows, this is
 
48
 * also in the form of a cache. Only 3 * screen_length rows are kept in
 
49
 * the cache, and the cache is always a simple interval of rows. That is,
 
50
 * rows between valid_low and valid_high are all in the cache. Row numbers
 
51
 * in the display list are a little mysterious. There is no origin. That
 
52
 * is, you don't necessarily know where the start or end of the display
 
53
 * is. You only know how to go forward and backward and how to "warp"
 
54
 * to new locations in the display and go forward and backward from there.
 
55
 * This is because we don't know how many rows there are all together. It
 
56
 * is also a way to avoid searching through everything to get somewhere.
 
57
 * If you want to go to the End, you warp there and start backwards instead
 
58
 * of reading through all the entries to get there. If you edit an entry
 
59
 * so that it sorts into a new location, you warp to that new location to
 
60
 * save processing all of the entries in between.
 
61
 *
 
62
 *
 
63
 * Notes about RFC1522 encoding:
 
64
 *
 
65
 * If the fullname field contains other than US-ASCII characters, it is
 
66
 * encoded using the rules of RFC1522 or its successor. The value actually
 
67
 * stored in the file is encoded, even if it matches the character set of
 
68
 * the user. This is so it is easy to pass the entry around or to change
 
69
 * character sets without invalidating entries in the address book. When
 
70
 * a fullname is displayed, it is first decoded. If the fullname field is
 
71
 * encoded as being from a character set other than the user's character
 
72
 * set, that will be retained until the user edits the field. Then it will
 
73
 * change over to the user's character set. The comment field works in
 
74
 * the same way, as do the "phrase" fields of any addresses. On outgoing
 
75
 * mail, the correct character set will be retained if you use ComposeTo
 
76
 * from the address book screen. However, if you use a nickname from the
 
77
 * composer or ^T from the composer, the character set will be lost if it
 
78
 * is different from the user's character set.
 
79
 *
 
80
 *
 
81
 * Notes about RemoteViaImap address books:
 
82
 *
 
83
 * There are currently two types of address books, Local and Imap. Local means
 
84
 * it is in a local file. Imap means it is stored in a folder on a remote
 
85
 * IMAP server. The folder is a regular folder containing mail messages but
 
86
 * the messages are special. The first message is a header message. The last
 
87
 * message is the address book data. In between messages are old versions of
 
88
 * the address book data. The address book data is stored in the message as
 
89
 * it would be on disk, with no fancy mime encoding or anything. When it is
 
90
 * used the data from the last message in the folder is copied to a local file
 
91
 * and then it is used just like a local file. The local file is a cache for
 
92
 * the remote data. We can tell the remote data has been changed by looking
 
93
 * at the Date of the last message in the remote folder. If we see it has
 
94
 * changed we copy the whole file over again and replace the cache file.
 
95
 * A possibly quicker way to tell if it has changed is if the UID has
 
96
 * changed or the number of messages in the folder has changed. We use those
 
97
 * methods if possible since they don't require opening a new stream and
 
98
 * selecting the folder.  There is one metadata file for address book data.
 
99
 * The name of that file is stored in the pinerc file. It contains the names
 
100
 * of the cache files for RemoveViaImap address books plus other caching
 
101
 * information for those address books (uid...).
 
102
 */
 
103
 
 
104
#define NFIELDS 11 /* one more than num of data fields in addrbook entry */
 
105
 
 
106
/*
 
107
 * The type a_c_arg_t is a little confusing. It's the type we use in
 
108
 * place of adrbk_cntr_t when we want to pass an adrbk_cntr_t in an argument.
 
109
 * We were running into problems with the integral promotion of adrbk_cntr_t
 
110
 * args. A_c_arg_t has to be large enough to hold a promoted adrbk_cntr_t.
 
111
 * So, if adrbk_cntr_t is unsigned short, then a_c_arg_t needs to be int if
 
112
 * int is larger than short, or unsigned int if short is same size as int.
 
113
 * Since usign16_t always fits in a short, a_c_arg_t of unsigned int should
 
114
 * always work for !HUGE. For HUGE, UINT32 will be either an unsigned int
 
115
 * or an unsigned long. If it is an unsigned long, then a_c_arg_t better be
 
116
 * an unsigned long, too. If it is an unsigned int, then a_c_arg_t could
 
117
 * be an unsigned int, too. However, if we just make it unsigned long, then
 
118
 * it will be the same in all cases and big enough in all cases.
 
119
 */
 
120
 
 
121
#define adrbk_cntr_t UINT32  /* addrbook counter type                */
 
122
typedef unsigned long a_c_arg_t;     /* type of arg passed for adrbk_cntr_t  */
 
123
#define NO_NEXT ((adrbk_cntr_t)-1)
 
124
#define MAX_ADRBK_SIZE (2000000000L) /* leave room for extra display lines   */
 
125
 
 
126
/*
 
127
 * The value NO_NEXT is reserved to mean that there is no next address, or that
 
128
 * there is no address number to return. This is similar to getc returning
 
129
 * -1 when there is no char to get, but since we've defined this to be
 
130
 * unsigned we need to reserve one of the valid values for this purpose.
 
131
 * With current implementation it needs to be all 1's, so memset initialization
 
132
 * will work correctly.
 
133
 */
 
134
 
 
135
typedef enum {NotSet, Single, List} Tag;
 
136
 
 
137
 
 
138
/* This is what is actually used by the routines that manipulate things */
 
139
typedef struct adrbk_entry {
 
140
    char *nickname;    /* UTF-8                                         */
 
141
    char *fullname;    /* of simple addr or list (stored in UTF-8)      */
 
142
    union addr {
 
143
        char *addr;    /* for simple Single entries                     */
 
144
        char **list;   /* for distribution lists                        */
 
145
    } addr;
 
146
    char *fcc;         /* fcc specific for when sending to this address */
 
147
    char *extra;       /* comments field (stored in UTF-8)              */
 
148
    char  referenced;  /* for detecting loops during lookup             */
 
149
    Tag   tag;         /* single addr (Single) or a list (List)         */
 
150
} AdrBk_Entry;
 
151
 
 
152
 
 
153
typedef struct abook_tree_node {
 
154
    struct abook_tree_node *down;       /* next letter of nickname */
 
155
    struct abook_tree_node *right;      /* alternate letter of nickname */
 
156
    char                    value;      /* character at this node */
 
157
    adrbk_cntr_t            entrynum;   /* use NO_NEXT as no-data indicator */
 
158
} AdrBk_Trie;
 
159
 
 
160
 
 
161
/* information useful for displaying the addrbook */
 
162
typedef struct width_stuff {
 
163
    int max_nickname_width;
 
164
    int max_fullname_width;
 
165
    int max_addrfield_width;
 
166
    int max_fccfield_width;
 
167
    int third_biggest_fullname_width;
 
168
    int third_biggest_addrfield_width;
 
169
    int third_biggest_fccfield_width;
 
170
} WIDTH_INFO_S;
 
171
 
 
172
 
 
173
typedef struct expanded_list {
 
174
    adrbk_cntr_t          ent;
 
175
    struct expanded_list *next;
 
176
} EXPANDED_S;
 
177
 
 
178
 
 
179
typedef enum {Local, Imap} AdrbkType;
 
180
 
 
181
 
 
182
#ifndef IMAP_IDLE_TIMEOUT
 
183
#define IMAP_IDLE_TIMEOUT       (10L * 60L)     /* seconds */
 
184
#endif
 
185
#ifndef FILE_VALID_CHK_INTERVAL
 
186
#define FILE_VALID_CHK_INTERVAL (      15L)     /* seconds */
 
187
#endif
 
188
#ifndef LOW_FREQ_CHK_INTERVAL
 
189
#define LOW_FREQ_CHK_INTERVAL   (240)           /* minutes */
 
190
#endif
 
191
 
 
192
typedef struct adrbk {
 
193
    AdrbkType     type;                /* type of address book               */
 
194
    char         *orig_filename;       /* passed in filename                 */
 
195
    char         *filename;            /* addrbook filename                  */
 
196
    char         *our_filecopy;        /* session copy of filename contents  */
 
197
    FILE         *fp;                  /* fp for our_filecopy                */
 
198
    adrbk_cntr_t  count;               /* how many entries in addrbook       */
 
199
    adrbk_cntr_t  del_count;           /* how many #DELETED entries in abook */
 
200
    AdrBk_Entry  *arr;                 /* array of entries                   */
 
201
    AdrBk_Entry  *del;                 /* array of deleted entries           */
 
202
    AdrBk_Trie   *nick_trie;
 
203
    AdrBk_Trie   *addr_trie;
 
204
    time_t        last_change_we_know_about;/* to look for others changing it*/
 
205
    time_t        last_local_valid_chk;/* when valid check was done          */
 
206
    unsigned      flags;               /* see defines in alpine.h (DEL_FILE...)*/
 
207
    WIDTH_INFO_S  widths;              /* helps addrbook.c format columns    */
 
208
    int           sort_rule;
 
209
    EXPANDED_S   *exp;                 /* this is for addrbook.c to use.  A
 
210
                               list of expanded list entry nums is kept here */
 
211
    EXPANDED_S   *checks;              /* this is for addrbook.c to use.  A
 
212
                               list of checked entry nums is kept here */
 
213
    EXPANDED_S   *selects;             /* this is for addrbook.c to use.  A
 
214
                               list of selected entry nums is kept here */
 
215
    REMDATA_S    *rd;
 
216
} AdrBk;
 
217
 
 
218
 
 
219
/*
 
220
 * The definitions starting here have to do with the virtual scrolling
 
221
 * region view into the addressbooks. That is, the display.
 
222
 *
 
223
 * We could make every use of an AdrBk_Entry go through a function call
 
224
 * like adrbk_get_ae(). Instead, we try to be smart and avoid the extra
 
225
 * function calls by knowing when the addrbook entry is still valid, either
 
226
 * because we haven't called any functions that could invalidate it or because
 
227
 * we have locked it in the cache. If we do lock it, we need to be careful
 
228
 * that it eventually gets unlocked. That can be done by an explicit
 
229
 * adrbk_get_ae(Unlock) call, or it is done implicitly when the address book
 
230
 * is written out. The reason it can get invalidated is that the abe that
 
231
 * we get returned to us is just a pointer to a cached addrbook entry, and
 
232
 * that entry can be flushed from the cache by other addrbook activity.
 
233
 * So we need to be careful to make sure the abe is certain to be valid
 
234
 * before using it.
 
235
 *
 
236
 * Data structures for the display of the address book. There's one
 
237
 * of these structures per line on the screen.
 
238
 *
 
239
 * Types: Title -- The title line for the different address books. It has
 
240
 *                 a ptr to the text of the Title line.
 
241
 * ClickHereCmb -- This is the line that says to click here to
 
242
 *                 expand.  It changes types into the individual expanded
 
243
 *                 components once it is expanded.  It doesn't have any data
 
244
 *                 other than an implicit title. This is only used with the
 
245
 *                 combined-style addrbook display.
 
246
 * ListClickHere --This is the line that says to click here to
 
247
 *                 expand the members of a distribution list. It changes
 
248
 *                 types into the individual expanded ListEnt's (if any)
 
249
 *                 when it is expanded. It has a ptr to an AdrBk_Entry.
 
250
 *    ListEmpty -- Line that says this is an empty distribution list. No data.
 
251
 *        Empty -- Line that says this is an empty addressbook. No data.
 
252
 *    ZoomEmpty -- Line that says no addrs in zoomed view. No data.
 
253
 * AddFirstGLob -- Place holder for adding an abook. No data.
 
254
 * AddFirstPers -- Place holder for adding an abook. No data.
 
255
 *   DirServers -- Place holder for accessing directory servers. No data.
 
256
 *       Simple -- A single addressbook entry. It has a ptr to an AdrBk_Entry.
 
257
 *                 When it is displayed, the fields are usually:
 
258
 *                 <nickname>       <fullname>       <address or another nic>
 
259
 *     ListHead -- The head of an address list. This has a ptr to an
 
260
 *                 AdrBk_Entry.
 
261
 *                 <blank line> followed by
 
262
 *                 <nickname>       <fullname>       "DISTRIBUTION LIST:"
 
263
 *      ListEnt -- The rest of an address list. It has a pointer to its
 
264
 *                 ListHead element and a ptr (other) to this specific address
 
265
 *                 (not a ptr to another AdrBk_Entry).
 
266
 *                 <blank>          <blank>          <address or another nic>
 
267
 *         Text -- A ptr to text. For example, the ----- lines and
 
268
 *                 whitespace lines.
 
269
 *    NoAbooks  -- There are no address books at all.
 
270
 *   Beginnning -- The (imaginary) elements before the first real element
 
271
 *          End -- The (imaginary) elements after the last real element
 
272
 */
 
273
typedef enum {DlNotSet, Empty, ZoomEmpty, AddFirstPers, AddFirstGlob,
 
274
              AskServer, Title, Simple, ListHead, ListClickHere,
 
275
              ListEmpty, ListEnt, Text, Beginning, End, NoAbooks,
 
276
              ClickHereCmb, TitleCmb} LineType;
 
277
/* each line of address book display is one of these structures */
 
278
typedef struct addrscrn_disp {
 
279
    union {
 
280
        struct {
 
281
            adrbk_cntr_t  ab_element_number; /* which addrbook entry     */
 
282
            adrbk_cntr_t  ab_list_offset;    /* which member of the list */
 
283
        }addrbook_entry;
 
284
        char        *text_ptr;               /* a UTF-8 string */
 
285
    }union_to_save_space;
 
286
    LineType       type;
 
287
} AddrScrn_Disp;
 
288
#define usst union_to_save_space.text_ptr
 
289
#define elnum union_to_save_space.addrbook_entry.ab_element_number
 
290
#define l_offset union_to_save_space.addrbook_entry.ab_list_offset
 
291
 
 
292
#define entry_is_checked    exp_is_expanded
 
293
#define entry_get_next      exp_get_next
 
294
#define entry_set_checked   exp_set_expanded
 
295
#define entry_unset_checked exp_unset_expanded
 
296
#define any_checked         exp_any_expanded
 
297
#define howmany_checked     exp_howmany_expanded
 
298
 
 
299
#define entry_is_selected   exp_is_expanded
 
300
#define entry_set_selected  exp_set_expanded
 
301
#define entry_unset_selected exp_unset_expanded
 
302
#define any_selected        exp_any_expanded
 
303
#define howmany_selected    exp_howmany_expanded
 
304
 
 
305
#define entry_is_deleted    exp_is_expanded
 
306
#define entry_set_deleted   exp_set_expanded
 
307
#define howmany_deleted     exp_howmany_expanded
 
308
 
 
309
#define entry_is_added      exp_is_expanded
 
310
#define entry_set_added     exp_set_expanded
 
311
 
 
312
/*
 
313
 * Argument to expand_address and build_address_internal is a BuildTo,
 
314
 * which is either a char * address or an AdrBk_Entry * (if we have already
 
315
 * looked it up in an addrbook).
 
316
 */
 
317
typedef enum {Str, Abe} Build_To_Arg_Type;
 
318
typedef struct build_to {
 
319
    Build_To_Arg_Type type;
 
320
    union {
 
321
        char        *str;  /* normal looking address string */
 
322
        AdrBk_Entry *abe;  /* addrbook entry */
 
323
    }arg;
 
324
} BuildTo;
 
325
 
 
326
 
 
327
/* Display lines used up by each top-level addrbook, counting blanks */
 
328
#define LINES_PER_ABOOK (3)
 
329
/* How many of those lines are visible (not blank) */
 
330
#define VIS_LINES_PER_ABOOK (2)
 
331
/* How many extra lines are between the personal and global sections */
 
332
#define XTRA_LINES_BETWEEN (1)
 
333
/* How many lines does the PerAdd line take, counting blank line */
 
334
#define LINES_PER_ADD_LINE (2)
 
335
/* Extra title lines above first entry that are shown when the combined-style
 
336
   display is turned on. */
 
337
#define XTRA_TITLE_LINES_IN_OLD_ABOOK_DISP (4)
 
338
 
 
339
typedef enum {DlcNotSet,
 
340
              DlcPersAdd,               /* config screen only */
 
341
              DlcGlobAdd,               /*    "      "    "   */
 
342
 
 
343
              DlcTitle,                 /* top level displays */
 
344
              DlcTitleNoPerm,           /*  "    "      "     */
 
345
              DlcSubTitle,              /*  "    "      "     */
 
346
              DlcTitleBlankTop,         /*  "    "      "     */
 
347
              DlcGlobDelim1,            /*  "    "      "     */
 
348
              DlcGlobDelim2,            /*  "    "      "     */
 
349
              DlcDirDelim1,             /*  "    "      "     */
 
350
              DlcDirDelim2,             /*  "    "      "     */
 
351
              DlcDirAccess,             /*  "    "      "     */
 
352
              DlcDirSubTitle,           /*  "    "      "     */
 
353
              DlcDirBlankTop,           /*  "    "      "     */
 
354
 
 
355
              DlcTitleDashTopCmb,       /* combined-style top level display */
 
356
              DlcTitleCmb,              /*     "      "    "    "      "    */
 
357
              DlcTitleDashBottomCmb,    /*     "      "    "    "      "    */
 
358
              DlcTitleBlankBottomCmb,   /*     "      "    "    "      "    */
 
359
              DlcClickHereCmb,          /*     "      "    "    "      "    */
 
360
              DlcTitleBlankTopCmb,      /*     "      "    "    "      "    */
 
361
              DlcDirDelim1a,            /*     "      "    "    "      "    */
 
362
              DlcDirDelim1b,            /*     "      "    "    "      "    */
 
363
              DlcDirDelim1c,            /*     "      "    "    "      "    */
 
364
 
 
365
              DlcEmpty,                 /* display of a single address book */
 
366
              DlcZoomEmpty,             /*    "                             */
 
367
              DlcNoPermission,          /*    "                             */
 
368
              DlcSimple,                /*    "                             */
 
369
              DlcListHead,              /*    "                             */
 
370
              DlcListClickHere,         /*    "                             */
 
371
              DlcListEmpty,             /*    "                             */
 
372
              DlcListEnt,               /*    "                             */
 
373
              DlcListBlankTop,          /*    "                             */
 
374
              DlcListBlankBottom,       /*    "                             */
 
375
              DlcNoAbooks,              /*    "                             */
 
376
 
 
377
              DlcOneBeforeBeginning,    /* used in both */
 
378
              DlcTwoBeforeBeginning,    /*  "   "   "   */
 
379
              DlcBeginning,             /*  "   "   "   */
 
380
              DlcEnd} DlCacheType;
 
381
 
 
382
typedef enum {Initialize, FirstEntry, LastEntry, ArbitraryStartingPoint,
 
383
              DoneWithCache, FlushDlcFromCache, Lookup} DlMgrOps;
 
384
typedef enum {Warp, DontWarp} HyperType;
 
385
 
 
386
/*
 
387
 * The DlCacheTypes are the types that a dlcache element can be labeled.
 
388
 * The idea is that there needs to be enough information in the single
 
389
 * cache element by itself so that you can figure out what the next and
 
390
 * previous dl rows are by just knowing this one row.
 
391
 *
 
392
 * In the top-level display, there are DlcTitle lines or DlcTitleNoPerm
 
393
 * lines, which are the same except we know that we can't access the
 
394
 * address book in the latter case. DlcSubTitle lines follow each of the
 
395
 * types of Title lines, and Titles within a section are separated by
 
396
 * DlcTitleBlankTop lines, which belong to (have the same adrbk_num as)
 
397
 * the Title they are above.
 
398
 * If there are no address books and no directory servers defined, we
 
399
 * have a DlcNoAbooks line. When we are displaying an individual address
 
400
 * book (not in the top-level display) there is another set of types. An
 
401
 * empty address book consists of one line of type DlcEmpty. An address
 
402
 * book without read permission is a DlcNoPermission. Simple address book
 
403
 * entries consist of a single DlcSimple line. Lists begin with a
 
404
 * DlcListHead. If the list is not expanded the DlcListHead is followed by
 
405
 * a DlcListClickHere. If it is known to be a list with no members the
 
406
 * DlcListHead is followed by a DlcListEmpty. If there are members and
 
407
 * the list is expanded, each list member is a single line of type
 
408
 * DlcListEnt. Two lists are separated by a DlcListBlankBottom belonging
 
409
 * to the first list. A list followed or preceded by a DlcSimple address
 
410
 * row has a DlcListBlank(Top or Bottom) separating it from the
 
411
 * DlcSimple. Above the top row of the display is an imaginary line of
 
412
 * type DlcOneBeforeBeginning. Before that is a DlcTwoBeforeBeginning. And
 
413
 * before that all the lines are just DlcBeginning lines. After the last
 
414
 * display line is a DlcEnd.
 
415
 *
 
416
 * The DlcDirAccess's are indexed by adrbk_num (re-used for this).
 
417
 * Adrbk_num -1 means access all of the servers.
 
418
 * Adrbk_num 0 ... n_serv -1 means access all a particular server.
 
419
 * Adrbk_num n_serv means access as if from composer using config setup.
 
420
 *
 
421
 * Here are the types of lines and where they fall in the top-level display:
 
422
 *
 
423
 * (not a visible line)                 DlcBeginning
 
424
 * (not a visible line)                 DlcBeginning
 
425
 * (not a visible line)                 DlcTwoBeforeBeginning
 
426
 * (not a visible line)                 DlcOneBeforeBeginning
 
427
 *     Title                            DlcTitle (or TitleNoPerm)
 
428
 *       Subtitle                       DlcSubTitle
 
429
 * ---this is blank----------------     DlcTitleBlankTop
 
430
 *     Title                            DlcTitle (or TitleNoPerm)
 
431
 *       Subtitle                       DlcSubTitle
 
432
 * ---this is blank----------------     DlcGlobDelim1
 
433
 * ---this is blank----------------     DlcGlobDelim2
 
434
 *     Title                            DlcTitle (or TitleNoPerm)
 
435
 *       Subtitle                       DlcSubTitle
 
436
 * ---this is blank----------------     DlcTitleBlankTop
 
437
 *     Title                            DlcTitle (or TitleNoPerm)
 
438
 *       Subtitle                       DlcSubTitle
 
439
 * ---this is blank----------------     DlcDirDelim1
 
440
 * ---this is blank----------------     DlcDirDelim2
 
441
 *     Directory (query server 1)       DlcDirAccess (adrbk_num 0)
 
442
 *       Subtitle                       DlcDirSubTitle (adrbk_num 0)
 
443
 * ---this is blank----------------     DlcDirBlankTop
 
444
 *     Directory (query server 2)       DlcDirAccess (adrbk_num 1)
 
445
 *       Subtitle                       DlcDirSubTitle (adrbk_num 1)
 
446
 * (not a visible line)                 DlcEnd
 
447
 * (not a visible line)                 DlcEnd
 
448
 *
 
449
 *
 
450
 * There is a combined-style display triggered by the F_CMBND_ABOOK_DISP
 
451
 * feature. It's a mixture of the top-level and open addrbook displays. When an
 
452
 * addrbook is opened the rest of the addrbooks don't disappear from the
 
453
 * screen. In this view, the ClickHere lines can be replaced with the entire
 
454
 * contents of the addrbook, but the other stuff remains on the screen, too.
 
455
 * Here are the types of lines and where they fall in the
 
456
 * combined-style display:
 
457
 *
 
458
 * (not a visible line)                 DlcBeginning
 
459
 * (not a visible line)                 DlcBeginning
 
460
 * (not a visible line)                 DlcTwoBeforeBeginning
 
461
 * (not a visible line)                 DlcOneBeforeBeginning
 
462
 * --------------------------------     DlcTitleDashTopOld
 
463
 *     Title                            DlcTitleOld
 
464
 * --------------------------------     DlcTitleDashBottomOld
 
465
 * ---this is blank----------------     DlcTitleBlankBottom
 
466
 *     ClickHere                        DlcClickHereOld
 
467
 * ---this is blank----------------     DlcTitleBlankTop
 
468
 * --------------------------------     DlcTitleDashTopOld
 
469
 *     Title                            DlcTitleOld
 
470
 * --------------------------------     DlcTitleDashBottomOld
 
471
 * ---this is blank----------------     DlcTitleBlankBottom
 
472
 *     ClickHere                        DlcClickHereOld
 
473
 * ---this is blank----------------     DlcDirDelim1
 
474
 * --------------------------------     DlcDirDelim1a
 
475
 * Directories                          DlcDirDelim1b
 
476
 * --------------------------------     DlcDirDelim1c
 
477
 * ---this is blank----------------     DlcDirDelim2
 
478
 *     Directory (query server 1)       DlcDirAccess (adrbk_num 0)
 
479
 *       Subtitle                       DlcDirSubTitle (adrbk_num 0)
 
480
 * ---this is blank----------------     DlcDirBlankTop
 
481
 *     Directory (query server 2)       DlcDirAccess (adrbk_num 1)
 
482
 *       Subtitle                       DlcDirSubTitle (adrbk_num 1)
 
483
 * (not a visible line)                 DlcEnd
 
484
 * (not a visible line)                 DlcEnd
 
485
 *
 
486
 * If there are no addrbooks in either of the two sections, or no Directory
 
487
 * servers, then that section is left out of the display. If there is only
 
488
 * one address book and no Directories, then the user goes directly into the
 
489
 * single addressbook view which looks like:
 
490
 *
 
491
 * if(no entries in addrbook)
 
492
 *
 
493
 * (not a visible line)                 DlcBeginning
 
494
 * (not a visible line)                 DlcBeginning
 
495
 * (not a visible line)                 DlcTwoBeforeBeginning
 
496
 * (not a visible line)                 DlcOneBeforeBeginning
 
497
 *     Empty or NoPerm or NoAbooks      DlcEmpty, DlcZoomEmpty, DlcNoPermission,
 
498
 *                                      or DlcNoAbooks
 
499
 * (not a visible line)                 DlcEnd
 
500
 * (not a visible line)                 DlcEnd
 
501
 *
 
502
 * else
 
503
 *
 
504
 * (not a visible line)                 DlcBeginning
 
505
 * (not a visible line)                 DlcBeginning
 
506
 * (not a visible line)                 DlcTwoBeforeBeginning
 
507
 * (not a visible line)                 DlcOneBeforeBeginning
 
508
 *     Simple Entry                     DlcSimple
 
509
 *     Simple Entry                     DlcSimple
 
510
 *     Simple Entry                     DlcSimple
 
511
 *                                      DlcListBlankTop
 
512
 *     List Header                      DlcListHead
 
513
 *          Unexpanded List             DlcListClickHere
 
514
 *          or
 
515
 *          Empty List                  DlcListEmpty
 
516
 *          or
 
517
 *          List Entry 1                DlcListEnt
 
518
 *          List Entry 2                DlcListEnt
 
519
 *                                      DlcListBlankBottom
 
520
 *     List Header                      DlcListHead
 
521
 *          List Entry 1                DlcListEnt
 
522
 *          List Entry 2                DlcListEnt
 
523
 *          List Entry 3                DlcListEnt
 
524
 *                                      DlcListBlankBottom
 
525
 *     Simple Entry                     DlcSimple
 
526
 *                                      DlcListBlankTop
 
527
 *     List Header                      DlcListHead
 
528
 *          Unexpanded List             DlcListClickHere
 
529
 * (not a visible line)                 DlcEnd
 
530
 * (not a visible line)                 DlcEnd
 
531
 *
 
532
 * The config screen view is similar to the top-level view except there
 
533
 * is no directory section (it has it's own config screen) and if there
 
534
 * are zero personal addrbooks or zero global addrbooks then a placeholder
 
535
 * line of type DlcPersAdd or DlcGlobAdd takes the place of the DlcTitle
 
536
 * line.
 
537
 */
 
538
typedef struct dl_cache {
 
539
    long         global_row; /* disp_list row number */
 
540
    adrbk_cntr_t dlcelnum;   /* which elnum from that addrbook */
 
541
    adrbk_cntr_t dlcoffset;  /* offset in a list, only for ListEnt rows */
 
542
    short        adrbk_num;  /* which address book we're related to */
 
543
    DlCacheType  type;       /* type of this row */
 
544
    AddrScrn_Disp dl;        /* the actual dl that goes with this row */
 
545
} DL_CACHE_S;
 
546
 
 
547
 
 
548
typedef enum {Nickname, Fullname, Addr, Filecopy, Comment, Notused,
 
549
              Def, WhenNoAddrDisplayed, Checkbox, Selected} ColumnType;
 
550
 
 
551
/*
 
552
 * Users can customize the addrbook display, so this tells us which data
 
553
 * is in a particular column and how wide the column is. There is an
 
554
 * array of these per addrbook, of length NFIELDS (number of possible cols).
 
555
 */
 
556
typedef struct column_description {
 
557
    ColumnType type;
 
558
    WidthType  wtype;
 
559
    int        req_width; /* requested width (for fixed and percent types) */
 
560
    int        width;     /* actual width to use */
 
561
    int        old_width;
 
562
} COL_S;
 
563
 
 
564
 
 
565
/* address book attributes for peraddrbook type */
 
566
#define GLOBAL          0x1     /* else it is personal */
 
567
#define REMOTE_VIA_IMAP 0x2     /* else it is a local file  */
 
568
 
 
569
 
 
570
typedef enum {TotallyClosed, /* hash tables not even set up yet               */
 
571
              Closed,     /* data not read in, no display list                */
 
572
              NoDisplay,  /* data is accessible, no display list              */
 
573
              HalfOpen,   /* data not accessible, initial display list is set */
 
574
              ThreeQuartOpen, /* like HalfOpen without partial_close          */
 
575
              Open        /* data is accessible and display list is set       */
 
576
             } OpenStatus;
 
577
 
 
578
/*
 
579
 * There is one of these per addressbook.
 
580
 */
 
581
typedef struct peraddrbook {
 
582
    unsigned            type;
 
583
    AccessType          access;
 
584
    OpenStatus          ostatus;
 
585
    char               *abnick,              /* kept internally in UTF-8 */
 
586
                       *filename;
 
587
    AdrBk              *address_book;        /* the address book handle */
 
588
    int                 gave_parse_warnings;
 
589
    COL_S               disp_form[NFIELDS];  /* display format */
 
590
    int                 nick_is_displayed;   /* these are for convenient, */
 
591
    int                 full_is_displayed;   /* fast access.  Could get   */
 
592
    int                 addr_is_displayed;   /* same info from disp_form. */
 
593
    int                 fcc_is_displayed;
 
594
    int                 comment_is_displayed;
 
595
    STORE_S            *so;                  /* storage obj for addrbook
 
596
                                                temporarily stored here   */
 
597
} PerAddrBook;
 
598
 
 
599
 
 
600
/*
 
601
 * This keeps track of the state of the screen and information about all
 
602
 * the address books. We usually only have one of these but sometimes
 
603
 * we save a version of this state (with save_state) and re-call the
 
604
 * address book functions. Then when we pop back up to where we were
 
605
 * (with restore_state) the screen and the state of the address books
 
606
 * is restored to what it was.
 
607
 */
 
608
typedef struct addrscreenstate {
 
609
    PerAddrBook   *adrbks;       /* array of addrbooks                    */
 
610
    int            initialized,  /* have we done at least simple init?    */
 
611
                   n_addrbk,     /* how many addrbooks are there          */
 
612
                   how_many_personals, /* how many of those are personal? */
 
613
                   cur,          /* current addrbook                      */
 
614
                   cur_row,      /* currently selected line               */
 
615
                   old_cur_row,  /* previously selected line              */
 
616
                   l_p_page;     /* lines per (screen) page               */
 
617
    long           top_ent;      /* index in disp_list of top entry on screen */
 
618
    int            ro_warning,   /* whether or not to give warning        */
 
619
                   checkboxes,   /* whether or not to display checkboxes  */
 
620
                   selections,   /* whether or not to display selections  */
 
621
                   do_bold,      /* display selections in bold            */
 
622
                   no_op_possbl, /* user can't do anything with current conf */
 
623
                   zoomed,       /* zoomed into view only selected entries */
 
624
                   config,       /* called from config screen             */
 
625
                   n_serv,       /* how many directory servers are there  */
 
626
                   n_impl,       /* how many of those have impl bit set   */
 
627
                   selected_is_history;
 
628
#ifdef  _WINDOWS
 
629
    long           last_ent;     /* index of last known entry             */
 
630
#endif
 
631
} AddrScrState;
 
632
 
 
633
 
 
634
/*
 
635
 * AddrBookScreen and AddrBookConfig are the maintenance screens, all the
 
636
 * others are selection screens. The AddrBookConfig screen is an entry
 
637
 * point from the Setup/Addressbooks command in the main menu. Those that
 
638
 * end in Com are called from the pico HeaderEditor, either while in the
 
639
 * composer or while editing an address book entry.  SelectManyNicks
 
640
 * returns a comma-separated list of nicknames. SelectAddrLccCom and
 
641
 * SelectNicksCom return a comma-separated list of nicknames.
 
642
 * SelectNickTake, SelectNickCom, and SelectNick all return a single
 
643
 * nickname.  The ones that returns multiple nicknames or multiple
 
644
 * addresses all allow ListMode. They are SelectAddrLccCom,
 
645
 * SelectNicksCom, and SelectMultNoFull.
 
646
 */
 
647
typedef enum {AddrBookScreen,      /* maintenance screen                     */
 
648
              AddrBookConfig,      /* config screen                          */
 
649
              SelectAddrLccCom,    /* returns list of nicknames of lists     */
 
650
              SelectNicksCom,      /* just like SelectAddrLccCom, but allows
 
651
                                      selecting simple *and* list entries    */
 
652
              SelectNick,          /* returns single nickname                */
 
653
              SelectNickTake,      /* Same as SelectNick but different help  */
 
654
              SelectNickCom,       /* Same as SelectNick but from composer   */
 
655
              SelectManyNicks,     /* Returns list of nicks */
 
656
              SelectAddr,          /* Returns single address */
 
657
              SelectAddrNoFull,    /* Returns single address without fullname */
 
658
              SelectMultNoFull     /* Returns mult addresses without fullname */
 
659
             } AddrBookArg;
 
660
 
 
661
 
 
662
typedef struct save_state_struct {
 
663
    AddrScrState *savep;
 
664
    OpenStatus   *stp;
 
665
    DL_CACHE_S   *dlc_to_warp_to;
 
666
} SAVE_STATE_S;
 
667
 
 
668
 
 
669
typedef struct act_list {
 
670
    PerAddrBook *pab;
 
671
    adrbk_cntr_t num,
 
672
                 num_in_dst;
 
673
    unsigned int skip:1,
 
674
                 dup:1;
 
675
} ACTION_LIST_S;
 
676
 
 
677
 
 
678
typedef struct ta_abook_state {
 
679
    PerAddrBook  *pab;
 
680
    SAVE_STATE_S  state;
 
681
} TA_STATE_S;
 
682
 
 
683
 
 
684
/*
 
685
 * Many of these should really only have a single value but we give them
 
686
 * an array for uniformity.
 
687
 */
 
688
typedef struct _vcard_info {
 
689
    char **nickname;
 
690
    char **fullname;
 
691
    char  *first;
 
692
    char  *middle;
 
693
    char  *last;
 
694
    char **fcc;
 
695
    char **note;
 
696
    char **title;
 
697
    char **tel;
 
698
    char **email;
 
699
} VCARD_INFO_S;
 
700
 
 
701
 
 
702
extern AddrScrState as;
 
703
extern jmp_buf      addrbook_changed_unexpectedly;
 
704
extern long         msgno_for_pico_callback;
 
705
extern BODY        *body_for_pico_callback;
 
706
extern ENVELOPE    *env_for_pico_callback;
 
707
extern int          ab_nesting_level;
 
708
 
 
709
 
 
710
/*
 
711
 * These constants are supposed to be suitable for use as longs where the longs
 
712
 * are representing a line number or message number.
 
713
 * These constants aren't suitable for use with type adrbk_cntr_t. There is
 
714
 * a constant called NO_NEXT which you probably want for that.
 
715
 */
 
716
#define NO_LINE         (2147483645L)
 
717
#define CHANGED_CURRENT (NO_LINE + 1L)
 
718
 
 
719
 
 
720
/*
 
721
 * The do-while stuff is so these are statements and can be written with
 
722
 * a following ; like a regular statement without worrying about braces and all.
 
723
 */
 
724
#define SKIP_SPACE(p) do{while(*p && *p == SPACE)p++;}while(0)
 
725
#define SKIP_TO_TAB(p) do{while(*p && *p != TAB)p++;}while(0)
 
726
#define RM_END_SPACE(start,end)                                             \
 
727
            do{char *_ptr = end;                                            \
 
728
               while(--_ptr >= start && *_ptr == SPACE)*_ptr = '\0';}while(0)
 
729
#define REPLACE_NEWLINES_WITH_SPACE(p)                                      \
 
730
                do{register char *_qq;                                      \
 
731
                   for(_qq = p; *_qq; _qq++)                                \
 
732
                       if(*_qq == '\n' || *_qq == '\r')                     \
 
733
                           *_qq = SPACE;}while(0)
 
734
#define DELETED "#DELETED-"
 
735
#define DELETED_LEN 9
 
736
 
 
737
 
 
738
#define ONE_HUNDRED_DAYS (60L * 60L * 24L * 100L)
 
739
 
 
740
/*
 
741
 * When address book entries are deleted, they are left in the file
 
742
 * with the nickname prepended with a string like #DELETED-96/01/25#, 
 
743
 * which stands for year 96, month 1, day 25 of the month. When one of
 
744
 * these entries is more than ABOOK_DELETED_EXPIRE_TIME seconds old,
 
745
 * then it will be totally removed from the address book the next time
 
746
 * an adrbk_write() is done. This is for emergencies where somebody
 
747
 * deletes something from their address book and would like to get it
 
748
 * back. You get it back by editing the nickname field manually to remove
 
749
 * the extra 18 characters off the front.
 
750
 */
 
751
#ifndef ABOOK_DELETED_EXPIRE_TIME
 
752
#define ABOOK_DELETED_EXPIRE_TIME   ONE_HUNDRED_DAYS
 
753
#endif
 
754
 
 
755
 
 
756
#ifdef  ENABLE_LDAP
 
757
typedef struct _cust_filt {
 
758
    char *filt;
 
759
    int   combine;
 
760
} CUSTOM_FILT_S;
 
761
 
 
762
#define RUN_LDAP        "LDAP: "
 
763
#define LEN_RL          6
 
764
#define QRUN_LDAP       "\"LDAP: "
 
765
#define LEN_QRL         7
 
766
#define LDAP_DISP       "[ LDAP Lookup ]"
 
767
#endif
 
768
 
 
769
 
 
770
/*
 
771
 * There are no restrictions on the length of any of the fields, except that
 
772
 * there are some restrictions in the current input routines.
 
773
 */
 
774
 
 
775
/*
 
776
 * The on-disk address book has entries that look like:
 
777
 *
 
778
 * Nickname TAB Fullname TAB Address_Field TAB Fcc TAB Comment
 
779
 *
 
780
 * An entry may be broken over more than one line but only at certain
 
781
 * spots. A continuation line starts with spaces (spaces, not white space).
 
782
 * One place a line break can occur is after any of the TABs. The other
 
783
 * place is in the middle of a list of addresses, between addresses.
 
784
 * The Address_Field may be either a simple address without the fullname
 
785
 * or brackets, or it may be an address list. An address list is
 
786
 * distinguished by the fact that it begins with "(" and ends with ")".
 
787
 * Addresses within a list are comma separated and each address in the list
 
788
 * may be a full rfc822 address, including Fullname and so on.
 
789
 *
 
790
 * Examples:
 
791
 * fred TAB Flintstone, Fred TAB fred@bedrock.net TAB fcc-flintstone TAB comment
 
792
 * or
 
793
 * fred TAB Flintstone, Fred TAB \n
 
794
 *    fred@bedrock.net TAB fcc-flintstone TAB \n
 
795
 *    comment
 
796
 * somelist TAB Some List TAB (fred, \n
 
797
 *    Barney Rubble <barney@bedrock.net>, wilma@bedrock.net) TAB \n
 
798
 *    fcc-for-some-list TAB comment
 
799
 */
 
800
 
 
801
 
 
802
/* exported prototypes */
 
803
AdrBk         *adrbk_open(PerAddrBook *, char *, char *, size_t, int);
 
804
int            adrbk_is_in_sort_order(AdrBk *, int, int);
 
805
adrbk_cntr_t   adrbk_count(AdrBk *);
 
806
AdrBk_Entry   *adrbk_get_ae(AdrBk *, a_c_arg_t);
 
807
AdrBk_Entry   *adrbk_lookup_by_nick(AdrBk *, char *, adrbk_cntr_t *);
 
808
AdrBk_Entry   *adrbk_lookup_by_addr(AdrBk *, char *, adrbk_cntr_t *);
 
809
char          *adrbk_formatname(char *, char **, char **);
 
810
void           adrbk_clearrefs(AdrBk *);
 
811
AdrBk_Entry   *adrbk_newentry(void);
 
812
AdrBk_Entry   *copy_ae(AdrBk_Entry *);
 
813
int            adrbk_add(AdrBk *, a_c_arg_t, char *, char *, char *, char *,
 
814
                         char *, Tag, adrbk_cntr_t *, int *, int, int, int);
 
815
int            adrbk_append(AdrBk *, char *, char *, char *, 
 
816
                            char *, char *, Tag, adrbk_cntr_t *);
 
817
int            adrbk_delete(AdrBk *, a_c_arg_t, int, int, int, int);
 
818
int            adrbk_listdel(AdrBk *, a_c_arg_t, char *);
 
819
int            adrbk_listdel_all(AdrBk *, a_c_arg_t, int);
 
820
int            adrbk_nlistadd(AdrBk *, a_c_arg_t, char **,int,int,int);
 
821
void           adrbk_check_validity(AdrBk *, long);
 
822
MAILSTREAM    *adrbk_handy_stream(char *);
 
823
void           adrbk_close(AdrBk *);
 
824
void           adrbk_partial_close(AdrBk *);
 
825
void           note_closed_adrbk_stream(MAILSTREAM *);
 
826
int            adrbk_write(AdrBk *, int, int, int);
 
827
void           free_ae(AdrBk_Entry **);
 
828
void           exp_free(EXPANDED_S *);
 
829
int            exp_is_expanded(EXPANDED_S *, a_c_arg_t);
 
830
int            exp_howmany_expanded(EXPANDED_S *);
 
831
int            exp_any_expanded(EXPANDED_S *);
 
832
adrbk_cntr_t   exp_get_next(EXPANDED_S **);
 
833
void           exp_set_expanded(EXPANDED_S *, a_c_arg_t);
 
834
void           exp_unset_expanded(EXPANDED_S *, a_c_arg_t);
 
835
int            adrbk_sort(AdrBk *, a_c_arg_t, adrbk_cntr_t *, int);
 
836
int            any_ab_open(void);
 
837
void           init_ab_if_needed(void);
 
838
int            init_addrbooks(OpenStatus, int, int, int);
 
839
void           addrbook_reset(void);
 
840
AccessType     adrbk_access(PerAddrBook *);
 
841
void           trim_remote_adrbks(void);
 
842
void           completely_done_with_adrbks(void);
 
843
void           init_abook(PerAddrBook *, OpenStatus);
 
844
int            adrbk_check_all_validity_now(void);
 
845
int            adrbk_check_and_fix(PerAddrBook *, int, int, int);
 
846
int            adrbk_check_and_fix_all(int, int, int);
 
847
void           adrbk_maintenance(void);
 
848
char         **parse_addrlist(char *);
 
849
char          *skip_to_next_addr(char *);
 
850
void           add_forced_entries(AdrBk *);
 
851
 
 
852
 
 
853
#endif /* PITH_ADRBKLIB_INCLUDED */