summaryrefslogtreecommitdiffstats
path: root/include/pttstruct.h
blob: ca5ed91164865db93f16de2acb7f2a2ac602cb68 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
/* $Id$ */
#ifndef INCLUDE_STRUCT_H
#define INCLUDE_STRUCT_H


#define IDLEN      12             /* Length of bid/uid */

/* 競標資訊 */
#define SALE_COMMENTED 0x1
typedef struct bid_t {
    int     high;
    int     buyitnow;
    int     usermax;
    int     increment;
    char    userid[IDLEN + 1];
    time4_t enddate;
    char    payby; /* 1 cash 2 check or mail 4 wire 8 credit 16 postoffice */
    char    flag;
    char    pad[2];
    int     shipping;
}bid_t;

/* 小雞的資料 */
typedef struct chicken_t {
    char    name[20];
    char    type;             /* 物種 */
    unsigned char   tech[16]; /* 技能 */
    time4_t birthday;         /* 生日 */
    time4_t lastvisit;        /* 上次照顧時間 */
    int     oo;               /* 補品 */
    int     food;             /* 食物 */
    int     medicine;         /* 藥品 */
    int     weight;           /* 體重 */
    int     clean;            /* 乾淨 */
    int     run;              /* 敏捷度 */
    int     attack;           /* 攻擊力 */
    int     book;             /* 知識 */
    int     happy;            /* 快樂 */
    int     satis;            /* 滿意度 */
    int     temperament;      /* 氣質 */
    int     tiredstrong;      /* 疲勞度 */
    int     sick;             /* 病氣指數 */
    int     hp;               /* 血量 */
    int     hp_max;           /* 滿血量 */
    int     mm;               /* 法力 */
    int     mm_max;           /* 滿法力 */
    time4_t cbirth;           /* 實際計算用的生日 */
    int     pad[2];           /* 留著以後用 */
} chicken_t;

#define PASSLEN    14             /* Length of encrypted passwd field */
#define REGLEN     38             /* Length of registration data */

#define PASSWD_VERSION  2275

typedef struct userec_t {
    unsigned int    version;    /* version number of this sturcture, we
                     * use revision number of project to denote.*/

    char    userid[IDLEN + 1];
    char    realname[20];
    char    username[24];
    char    passwd[PASSLEN];
    unsigned int    uflag;
    unsigned int    uflag2;
    unsigned int    userlevel;
    unsigned int    numlogins;
    unsigned int    numposts;
    time4_t firstlogin;
    time4_t lastlogin;
    char    lasthost[16];
    int     money;
    char    remoteuser[3];           /* 保留 目前沒用到的 */
    char    proverb;
    char    email[50];
    char    address[50];
    char    justify[REGLEN + 1];
    unsigned char   month;
    unsigned char   day;
    unsigned char   year;
    unsigned char   sex;
    unsigned char   state;
    unsigned char   pager;
    unsigned char   invisible;
    unsigned int    exmailbox; // TODO short 就夠了
    chicken_t       mychicken;
    time4_t lastsong;
    unsigned int    loginview;
    unsigned char   channel;      /* TODO unused */
    unsigned short  vl_count;     /* ViolateLaw counter */
    unsigned short  five_win;
    unsigned short  five_lose;
    unsigned short  five_tie;
    unsigned short  chc_win;
    unsigned short  chc_lose;
    unsigned short  chc_tie;
    int     mobile;
    char    mind[4];        /* not a null-terminate string */
    char    ident[11];
    unsigned char   signature;

    unsigned char   goodpost;       /* 評價為好文章數 */
    unsigned char   badpost;        /* 評價為壞文章數 */
    unsigned char   goodsale;       /* 競標 好的評價  */
    unsigned char   badsale;        /* 競標 壞的評價  */
    char    myangel[IDLEN+1];           /* 我的小天使 */
    unsigned short  chess_elo_rating;   /* 象棋等級分 */
    unsigned int    withme;
    char    pad[34];
} userec_t;
/* these are flags in userec_t.uflag */
#define PAGER_FLAG      0x4     /* true if pager was OFF last session */
#define CLOAK_FLAG      0x8     /* true if cloak was ON last session */
#define FRIEND_FLAG     0x10    /* true if show friends only */
#define BRDSORT_FLAG    0x20    /* true if the boards sorted alphabetical */
#define MOVIE_FLAG      0x40    /* true if show movie */
/* useless flag */
//#define COLOR_FLAG      0x80    /* true if the color mode open */
//#define MIND_FLAG       0x100   /* true if mind search mode open <-Heat*/

/* these are flags in userec_t.uflag2 */
#define WATER_MASK      000003  /* water mask */
#define WATER_ORIG      0x0
#define WATER_NEW       0x1
#define WATER_OFO       0x2
#define WATERMODE(mode) ((cuser.uflag2 & WATER_MASK) == mode)
#define FAVNOHILIGHT    0x10   /* false if hilight favorite */
#define FAVNEW_FLAG     0x20   /* true if add new board into one's fav */
#define FOREIGN         0x100  /* true if a foreign */
#define LIVERIGHT       0x200  /* true if get "liveright" already */
#define REJ_OUTTAMAIL   0x400 /* true if don't accept outside mails */
#define REJECT_OUTTAMAIL (cuser.uflag2 & REJ_OUTTAMAIL)

/* flags in userec_t.withme */
#define WITHME_ALLFLAG  0x55555555
#define WITHME_TALK 0x00000001
#define WITHME_NOTALK   0x00000002
#define WITHME_FIVE 0x00000004
#define WITHME_NOFIVE   0x00000008
#define WITHME_PAT  0x00000010
#define WITHME_NOPAT    0x00000020
#define WITHME_CHESS    0x00000040
#define WITHME_NOCHESS  0x00000080
#define WITHME_DARK 0x00000100
#define WITHME_NODARK   0x00000200
#define WITHME_GO   0x00000400
#define WITHME_NOGO 0x00000800

#ifdef PLAY_ANGEL
#define REJ_QUESTION    0x800 /* true if don't want to be angel for a while */
#define REJECT_QUESTION (cuser.uflag2 & REJ_QUESTION)
#define ANGEL_MASK      0x3000
#define ANGEL_R_MAEL    0x1000 /* true if reject male */
#define ANGEL_R_FEMAEL  0x2000 /* true if reject female */
#define ANGEL_STATUS()  ((cuser.uflag2 & ANGEL_MASK) >> 12)
#define ANGEL_SET(X)    (cuser.uflag2 = (cuser.uflag2 & ~ANGEL_MASK) | \
                          (((X) & 3) << 12))
#endif

#define BTLEN      48             /* Length of board title */

typedef struct boardheader_t {
    char    brdname[IDLEN + 1];          /* bid */
    char    title[BTLEN + 1];
    char    BM[IDLEN * 3 + 3];           /* BMs' userid, token '/' */
    unsigned int    brdattr;             /* board的屬性 */
    char    chesscountry;
    unsigned char   vote_limit_posts;    /* 連署 : 文章篇數下限 */
    unsigned char   vote_limit_logins;   /* 連署 : 登入次數下限 */
    char    pad[1];                      /* 沒用到的 */
    time4_t bupdate;                     /* note update time */
    unsigned char   post_limit_posts;    /* 發表文章 : 文章篇數下限 */
    unsigned char   post_limit_logins;   /* 發表文章 : 登入次數下限 */
    char    pad2[1];                     /* 沒用到的 */
    unsigned char   bvote;               /* 正舉辦 Vote 數 */
    time4_t vtime;                       /* Vote close time */
    unsigned int    level;               /* 可以看此板的權限 */
    int     unused;                      /* 還沒用到 */
    int     gid;                         /* 看板所屬的類別 ID */
    int     next[2];                     /* 在同一個gid下一個看板 動態產生*/
    int     firstchild[2];           /* 屬於這個看板的第一個子看板 */
    int     parent;
    int     childcount;                  /* 有多少個child */
    int     nuser;                       /* 多少人在這板 */
    int     postexpire;                  /* postexpire */
    time4_t endgamble;
    char    posttype[33];
    char    posttype_f;
    char    pad3[50];
} boardheader_t;

#define BRD_NOZAP       000000001         /* 不可zap  */
#define BRD_NOCOUNT     000000002         /* 不列入統計 */
#define BRD_NOTRAN      000000004         /* 不轉信 */
#define BRD_GROUPBOARD  000000010         /* 群組板 */
#define BRD_HIDE        000000020         /* 隱藏板 (看板好友才可看) */
#define BRD_POSTMASK    000000040         /* 限制發表或閱讀 */
#define BRD_ANONYMOUS   000000100         /* 匿名板 */
#define BRD_DEFAULTANONYMOUS 000000200    /* 預設匿名板 */
#define BRD_BAD     000000400         /* 違法改進中看板 */
#define BRD_VOTEBOARD   000001000         /* 連署機看板 */
#define BRD_WARNEL      000002000         /* 連署機看板 */
#define BRD_TOP         000004000         /* 熱門看板群組 */
#define BRD_NORECOMMEND 000010000         /* 不可推薦 */
#define BRD_BLOG        000020000         /* BLOG */
#define BRD_BMCOUNT 000040000     /* 板主設定列入記錄 */
#define BRD_SYMBOLIC    000100000     /* symbolic link to board */
#define BRD_NOBOO       000200000         /* 不可噓 */
#define BRD_LOCALSAVE   000400000         /* 預設 Local Save */
#define BRD_RESTRICTEDPOST 001000000      /* 板友才能發文 */
#define BRD_GUESTPOST   002000000         /* guest能 post */

#define BRD_LINK_TARGET(x)  ((x)->postexpire)
#define GROUPOP()               (currmode & MODE_GROUPOP)

#ifdef CHESSCOUNTRY
#define CHESSCODE_NONE   0
#define CHESSCODE_FIVE   1
#define CHESSCODE_CCHESS 2
#define CHESSCODE_MAX    2
#endif /* defined(CHESSCOUNTRY) */


#define TTLEN      64             /* Length of title */
#define FNLEN      33             /* Length of filename  */

typedef struct fileheader_t {
    char    filename[FNLEN];         /* M.9876543210.A */
    char    recommend;               /* important level */
    char    owner[IDLEN + 2];        /* uid[.] */
    char    date[6];                 /* [02/02] or space(5) */
    char    title[TTLEN + 1];
    union {
    int money;
    int anon_uid;
    /* different order to match alignment */
#ifdef _BIG_ENDIAN
    struct {
        unsigned char pad[2];   /* money & 0xffff0000 */
        unsigned char logins;   /* money & 0xff00 */
        unsigned char posts;    /* money & 0xff */
    } vote_limits;
    struct {
        unsigned int flag:1;
        unsigned int ref:31;
    } refer;
#else
    struct {
        unsigned char posts;    /* money & 0xff */
        unsigned char logins;   /* money & 0xff00 */
        unsigned char pad[2];   /* money & 0xffff0000 */
    } vote_limits;
    struct {
        unsigned int ref:31;
        unsigned int flag:1;
    } refer;
#endif
    }       multi;          /* rocker: if bit32 on ==> reference */
    /* XXX dirty, split into flag and money if money of each file is less than 16bit? */
    unsigned char   filemode;        /* must be last field @ boards.c */
} fileheader_t;

#define FILE_LOCAL      0x1     /* local saved */
#define FILE_READ       0x1     /* already read : mail only */
#define FILE_MARKED     0x2     /* opus: 0x8 */
#define FILE_DIGEST     0x4     /* digest */
#define FILE_HOLD       0x8     /* unused */
#define FILE_BOTTOM     0x8     /* push_bottom */
#define FILE_SOLVED 0x10    /* problem solved, sysop/BM only */
#define FILE_HIDE       0x20    /* hild */
#define FILE_BID        0x20    /* for bid */
#define FILE_BM         0x40    /* BM only */
#define FILE_MULTI      0x100   /* multi send for mail */
#define FILE_VOTE       0x40    /* for vote */
#define FILE_ANONYMOUS  0x80   /* anonymous file */

#define STRLEN     80             /* Length of most string data */


/* uhash is a userid->uid hash table -- jochang */

#define HASH_BITS 16

union xitem_t {
    struct {                    /* bbs_item */
    char    fdate[9];       /* [mm/dd/yy] */
    char    editor[13];      /* user ID */
    char    fname[31];
    } B;
    struct {                    /* gopher_item */
    char    path[81];
    char    server[48];
    int     port;
    } G;
};

typedef struct {
    char    title[63];
    union   xitem_t X;
} item_t;

typedef struct {
    item_t  *item[MAX_ITEMS];
    char    mtitle[STRLEN];
    char    *path;
    int     num, page, now, level;
} gmenu_t;

#define FAVMAX   1024         /* Max boards of Myfavorite */
#define FAVGMAX    32             /* Max groups of Myfavorite */
#define FAVGSLEN    8         /* Max Length of Description String */

/* values of msgque_t::msgmode */
#define MSGMODE_TALK      0
#define MSGMODE_WRITE     1
#ifdef PLAY_ANGEL
#define MSGMODE_FROMANGEL 2
#define MSGMODE_TOANGEL   3
#endif

typedef struct msgque_t {
    pid_t   pid;
    char    userid[IDLEN + 1];
    char    last_call_in[76];
    int     msgmode;
} msgque_t;

/* user data in shm */
typedef struct userinfo_t {
    int     uid;                  /* Used to find user name in passwd file */
    pid_t   pid;                  /* kill() to notify user of talk request */
    int     sockaddr;             /* ... */
    int     destuid;              /* talk uses this to identify who called */
    int     destuip;              /* dest index in utmpshm->uinfo[] */
    unsigned char   active;         /* When allocated this field is true */
    unsigned char   invisible;      /* Used by cloaking function in Xyz menu */
    unsigned char   sockactive;     /* Used to coordinate talk requests */
    unsigned char   angel;
    unsigned int    userlevel;
    unsigned char   mode;           /* UL/DL, Talk Mode, Chat Mode, ... */
    unsigned char   pager;          /* pager toggle, YEA, or NA */
    unsigned char   in_chat;        /* for in_chat commands   */
    unsigned char   sig;            /* signal type */
    char    userid[IDLEN + 1];
    char    chatid[11];             /* chat id, if in chat mode */
    char    username[24];
    char    from[27];               /* machine name the user called in from */
    int     from_alias;
    char    birth;                   /* 是否是生日 Ptt*/
    short   nFriends;                /* 下面 friend[] 只用到前幾個,
                                        用來 bsearch */
    int     friend[MAX_FRIEND];
    int     friend_online[MAX_FRIEND];/* point到線上好友 utmpshm的位置 */
                      /* 好友比較的cache 前兩個bit是狀態 */
    int     reject[MAX_REJECT];
    unsigned short  int     chess_elo_rating;
    int     lock;
    int     friendtotal;              /* 好友比較的cache 大小 */ 
    char    msgcount;
    msgque_t        msgs[MAX_MSGS];
    unsigned int    withme;
    time4_t lastact;               /* 上次使用者動的時間 */
    unsigned int    brc_id;
    unsigned char   lockmode;       /* 不准 multi_login 玩的東西 */
    char    turn;                    /* for gomo */
    char    mateid[IDLEN + 1];       /* for gomo */

    /* 為了 sync 回 .PASSWDS 時使用 */
    unsigned short  int     five_win;
    unsigned short  int     five_lose;
    unsigned short  int     five_tie;
    unsigned short  int     chc_win;
    unsigned short  int     chc_lose;
    unsigned short  int     chc_tie;

    unsigned char goodpost;
    char pad_1;
    unsigned char badpost;
    char pad_2;
    unsigned char goodsale;
    char pad_3;
    unsigned char badsale;
    char pad_4;

    char    mailalert;
    char    sex;
    char    color;
    char    mind[4];
#ifdef NOKILLWATERBALL
    time4_t wbtime;
#endif
} userinfo_t;

typedef struct water_t {
    pid_t   pid;
    char    userid[IDLEN + 1];
    int     top, count;
    msgque_t        msg[MAX_REVIEW];
    userinfo_t      *uin;     // Ptt:這可以取代alive
} water_t;

typedef struct {
    fileheader_t    *header;
    char    mtitle[STRLEN];
    char    *path;
    int     num, page, now, level;
} menu_t;

/* Used to pass commands to the readmenu.
 * direct mapping, indexed by ascii code. */
#define onekey_size ((int) 'z')
typedef int (* onekey_t)();

#define ANSILINELEN (511)                /* Maximum Screen width in chars */

/* anti_crosspost */
typedef struct crosspost_t {
    int     checksum[4]; /* 0 -> 'X' cross post  1-3 -> 檢查文章行 */
    short   times;       /* 第幾次 */
    short   last_bid;    /* crossport to which board */
} crosspost_t;

#define SORT_BY_ID    0
#define SORT_BY_CLASS 1
#define SORT_BY_STAT  1
#define SORT_BY_IDLE  2
#define SORT_BY_FROM  3
#define SORT_BY_FIVE  4
#define SORT_BY_SEX   5

typedef struct keeploc_t {
    unsigned int hashkey;
    int     top_ln;
    int     crs_ln;
} keeploc_t;

#define VALID_USHM_ENTRY(X) ((X) >= 0 && (X) < USHM_SIZE)
#define USHM_SIZE       (MAX_ACTIVE + 4)
/* USHM_SIZE 比 MAX_ACTIVE 大是為了防止檢查人數上限時, 又同時衝進來
 * 會造成找 shm 空位的無窮迴圈. 
 * -> 若是這樣, +4 夠嗎?
 * 又, 因 USHM 中用 hash, 空間稍大時效率較好. 
 * -> 若是因為 hashing, slot 也許要更多, 譬如兩倍? */

/* MAX_BMs is dirty hardcode 4 in mbbsd/cache.c:is_BM_cache() */
#define MAX_BMs         4                 /* for BMcache, 一個看板最多幾板主 */

typedef struct {
    /* uhash */
    char    userid[MAX_USERS][IDLEN + 1];
    int     next_in_hash[MAX_USERS];
    int     money[MAX_USERS];
    int     hash_head[1 << HASH_BITS];
    int     number;             /* # of users total */
    int     loaded;             /* .PASSWD has been loaded? */

    /* utmpshm */
    userinfo_t      uinfo[USHM_SIZE];
    int             sorted[2][8][USHM_SIZE];
                    /* 第一維double buffer 由currsorted指向目前使用的
               第二維sort type */
    int     currsorted;
    time4_t UTMPuptime;
    int     UTMPnumber;
    char    UTMPneedsort;
    char    UTMPbusystate;

    /* brdshm */
    int     BMcache[MAX_BOARD][MAX_BMs];
    boardheader_t   bcache[MAX_BOARD];
    int     bsorted[2][MAX_BOARD]; /* 0: by name 1: by class */ /* 裡頭存的是 bid-1 */
#if HOTBOARDCACHE
    unsigned char    nHOTs;
    int              HBcache[HOTBOARDCACHE];
#endif
    time4_t busystate_b[MAX_BOARD];
    int     total[MAX_BOARD];
    unsigned char  n_bottom[MAX_BOARD]; /* number of bottom */
    int     hbfl[MAX_BOARD][MAX_FRIEND + 1]; /* hidden board friend list, 0: load time, 1-MAX_FRIEND: uid */
    time4_t lastposttime[MAX_BOARD];
    time4_t Buptime;
    time4_t Btouchtime;
    int     Bnumber;
    int     Bbusystate;
    time4_t close_vote_time;

    /* pttcache */
    char    notes[MAX_MOVIE][200*11];
    char    today_is[20];
    int     n_notes[MAX_MOVIE_SECTION];      /* 一節中有幾個 看板 */
    int     next_refresh[MAX_MOVIE_SECTION]; /* 下一次要refresh的 看板 */
    msgque_t loginmsg;  /* 進站水球 */
    int     max_film;
    int     max_history;
    time4_t Puptime;
    time4_t Ptouchtime;
    int     Pbusystate;

    int     GLOBALVAR[10];                   /*  mbbsd間的 global variable
                         用以做統計等資料 (非常態)  */

    union {
    int     v[256];
    struct {
        int     dymaxactive;  /* 動態設定最大人數上限     */
        int     toomanyusers; /* 超過人數上限不給進的個數 */
        int     noonlineuser; /* 站上使用者不高亮度顯示   */
#ifdef OUTTA_TIMER
        time4_t now;
#endif
        int     nWelcomes;
    } e;
    } GV2;

    /* 故鄉 fromcache */
    unsigned int    home_ip[MAX_FROM];
    unsigned int    home_mask[MAX_FROM];
    char            home_desc[MAX_FROM][32];
    int             home_num;

    int     max_user;
    time4_t max_time;
    time4_t Fuptime;
    time4_t Ftouchtime;
    int     Fbusystate;

#ifdef I18N    
    /* i18n(internationlization) */
    char    *i18nstrptr[MAX_LANG][MAX_STRING];
    char    i18nstrbody[22 * MAX_LANG * MAX_STRING]; 
        /* Based on the statistis, we found the lengh of one string
           is 22 bytes approximately.
        */
#endif    
} SHM_t;

typedef struct {
    unsigned char oldlen;                /* previous line length */
    unsigned char len;                   /* current length of line */
    unsigned char mode;                  /* status of line, as far as update */
    unsigned char smod;                  /* start of modified data */
    unsigned char emod;                  /* end of modified data */
    unsigned char sso;                   /* start stand out */
    unsigned char eso;                   /* end stand out */
    /* data 必需是最後一個欄位, see screen_backup() */
    unsigned char data[ANSILINELEN + 1];
} screenline_t;

typedef struct {
    int r, c;
} rc_t;

#define BRD_ROW           10
#define BRD_COL           9

typedef int board_t[BRD_ROW][BRD_COL];

/* name.c 中運用的資料結構 */
typedef struct word_t {
    char    *word;
    struct  word_t  *next;
} word_t;

typedef struct commands_t {
    int     (*cmdfunc)();
    int     level;
    char    *desc;                   /* next/key/description */
} commands_t;

typedef struct MailQueue {
    char    filepath[FNLEN];
    char    subject[STRLEN];
    time4_t mailtime;
    char    sender[IDLEN + 1];
    char    username[24];
    char    rcpt[50];
    int     method;
    char    *niamod;
} MailQueue;

enum  {MQ_TEXT, MQ_UUENCODE, MQ_JUSTIFY};

typedef struct
{ 
    time4_t chrono;
    int     recno;
} TagItem;

/* type in gomo.c, structure passing through socket */
typedef struct {
    char            x;
    char            y;
} Horder_t;

#ifdef OUTTACACHE
typedef struct {
    int     index; // 在 SHM->uinfo[index]
    int     uid;   // 避免在 cache server 上不同步, 再確認用.
    int     friendstat;
    int     rfriendstat;
} ocfs_t;
#endif

#endif