2
* $Id: adrbklib.h 138 2006-09-22 22:12:03Z mikes@u.washington.edu $
4
* ========================================================================
5
* Copyright 2006 University of Washington
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
11
* http://www.apache.org/licenses/LICENSE-2.0
13
* ========================================================================
16
#ifndef PITH_ADRBKLIB_INCLUDED
17
#define PITH_ADRBKLIB_INCLUDED
20
#include "../pith/indxtype.h"
21
#include "../pith/remtype.h"
22
#include "../pith/store.h"
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
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
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.
63
* Notes about RFC1522 encoding:
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.
81
* Notes about RemoteViaImap address books:
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...).
104
#define NFIELDS 11 /* one more than num of data fields in addrbook entry */
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.
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 */
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.
135
typedef enum {NotSet, Single, List} Tag;
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) */
143
char *addr; /* for simple Single entries */
144
char **list; /* for distribution lists */
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) */
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 */
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;
173
typedef struct expanded_list {
175
struct expanded_list *next;
179
typedef enum {Local, Imap} AdrbkType;
182
#ifndef IMAP_IDLE_TIMEOUT
183
#define IMAP_IDLE_TIMEOUT (10L * 60L) /* seconds */
185
#ifndef FILE_VALID_CHK_INTERVAL
186
#define FILE_VALID_CHK_INTERVAL ( 15L) /* seconds */
188
#ifndef LOW_FREQ_CHK_INTERVAL
189
#define LOW_FREQ_CHK_INTERVAL (240) /* minutes */
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 */
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 */
220
* The definitions starting here have to do with the virtual scrolling
221
* region view into the addressbooks. That is, the display.
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
236
* Data structures for the display of the address book. There's one
237
* of these structures per line on the screen.
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
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
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
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 {
281
adrbk_cntr_t ab_element_number; /* which addrbook entry */
282
adrbk_cntr_t ab_list_offset; /* which member of the list */
284
char *text_ptr; /* a UTF-8 string */
285
}union_to_save_space;
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
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
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
305
#define entry_is_deleted exp_is_expanded
306
#define entry_set_deleted exp_set_expanded
307
#define howmany_deleted exp_howmany_expanded
309
#define entry_is_added exp_is_expanded
310
#define entry_set_added exp_set_expanded
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).
317
typedef enum {Str, Abe} Build_To_Arg_Type;
318
typedef struct build_to {
319
Build_To_Arg_Type type;
321
char *str; /* normal looking address string */
322
AdrBk_Entry *abe; /* addrbook entry */
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)
339
typedef enum {DlcNotSet,
340
DlcPersAdd, /* config screen only */
341
DlcGlobAdd, /* " " " */
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, /* " " " */
355
DlcTitleDashTopCmb, /* combined-style top level display */
356
DlcTitleCmb, /* " " " " " */
357
DlcTitleDashBottomCmb, /* " " " " " */
358
DlcTitleBlankBottomCmb, /* " " " " " */
359
DlcClickHereCmb, /* " " " " " */
360
DlcTitleBlankTopCmb, /* " " " " " */
361
DlcDirDelim1a, /* " " " " " */
362
DlcDirDelim1b, /* " " " " " */
363
DlcDirDelim1c, /* " " " " " */
365
DlcEmpty, /* display of a single address book */
366
DlcZoomEmpty, /* " */
367
DlcNoPermission, /* " */
370
DlcListClickHere, /* " */
371
DlcListEmpty, /* " */
373
DlcListBlankTop, /* " */
374
DlcListBlankBottom, /* " */
377
DlcOneBeforeBeginning, /* used in both */
378
DlcTwoBeforeBeginning, /* " " " */
379
DlcBeginning, /* " " " */
382
typedef enum {Initialize, FirstEntry, LastEntry, ArbitraryStartingPoint,
383
DoneWithCache, FlushDlcFromCache, Lookup} DlMgrOps;
384
typedef enum {Warp, DontWarp} HyperType;
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.
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.
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.
421
* Here are the types of lines and where they fall in the top-level display:
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
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:
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
464
* -------------------------------- DlcTitleDashBottomOld
465
* ---this is blank---------------- DlcTitleBlankBottom
466
* ClickHere DlcClickHereOld
467
* ---this is blank---------------- DlcTitleBlankTop
468
* -------------------------------- DlcTitleDashTopOld
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
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:
491
* if(no entries in addrbook)
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,
499
* (not a visible line) DlcEnd
500
* (not a visible line) DlcEnd
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
512
* List Header DlcListHead
513
* Unexpanded List DlcListClickHere
515
* Empty List DlcListEmpty
517
* List Entry 1 DlcListEnt
518
* List Entry 2 DlcListEnt
520
* List Header DlcListHead
521
* List Entry 1 DlcListEnt
522
* List Entry 2 DlcListEnt
523
* List Entry 3 DlcListEnt
525
* Simple Entry DlcSimple
527
* List Header DlcListHead
528
* Unexpanded List DlcListClickHere
529
* (not a visible line) DlcEnd
530
* (not a visible line) DlcEnd
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
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 */
548
typedef enum {Nickname, Fullname, Addr, Filecopy, Comment, Notused,
549
Def, WhenNoAddrDisplayed, Checkbox, Selected} ColumnType;
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).
556
typedef struct column_description {
559
int req_width; /* requested width (for fixed and percent types) */
560
int width; /* actual width to use */
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 */
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 */
579
* There is one of these per addressbook.
581
typedef struct peraddrbook {
585
char *abnick, /* kept internally in UTF-8 */
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 */
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.
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 */
629
long last_ent; /* index of last known entry */
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.
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 */
662
typedef struct save_state_struct {
665
DL_CACHE_S *dlc_to_warp_to;
669
typedef struct act_list {
678
typedef struct ta_abook_state {
685
* Many of these should really only have a single value but we give them
686
* an array for uniformity.
688
typedef struct _vcard_info {
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;
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.
716
#define NO_LINE (2147483645L)
717
#define CHANGED_CURRENT (NO_LINE + 1L)
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.
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
738
#define ONE_HUNDRED_DAYS (60L * 60L * 24L * 100L)
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.
751
#ifndef ABOOK_DELETED_EXPIRE_TIME
752
#define ABOOK_DELETED_EXPIRE_TIME ONE_HUNDRED_DAYS
757
typedef struct _cust_filt {
762
#define RUN_LDAP "LDAP: "
764
#define QRUN_LDAP "\"LDAP: "
766
#define LDAP_DISP "[ LDAP Lookup ]"
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.
776
* The on-disk address book has entries that look like:
778
* Nickname TAB Fullname TAB Address_Field TAB Fcc TAB Comment
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.
791
* fred TAB Flintstone, Fred TAB fred@bedrock.net TAB fcc-flintstone TAB comment
793
* fred TAB Flintstone, Fred TAB \n
794
* fred@bedrock.net TAB fcc-flintstone TAB \n
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
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 *);
853
#endif /* PITH_ADRBKLIB_INCLUDED */