1 /*
2  *	(c) Copyright 1990, Kim Fabricius Storm.  All rights reserved.
3  *      Copyright (c) 1996-2005 Michael T Pins.  All rights reserved.
4  *
5  *	DATABASE ORGANIZATION:
6  *
7  *	The central nn information is contained in following files:
8  *		DB_DIRECTORY/MASTER
9  *		DB_DIRECTORY/GROUPS
10  *		DB_DIRECTORY/DATA/nnn.x
11  *		DB_DIRECTORY/DATA/nnn.d
12  *
13  * 	The MASTER file consists of a header and one entry for each news
14  *	group.  The sequence of the group headers defines the group
15  *	number associated with the group.
16  *
17  * 	The GROUPS file contains the names of the news groups; the names
18  *	occur in the same sequence as in the MASTER file.
19  *
20  *	For each news group, the DATA directory contains two files whose
21  *	name is constructed from the group number 'nnn':
22  *
23  *		nnn.x	Index file
24  *		nnn.d	Data file
25  *
26  *	The index file provides a a mapping from article numbers to offsets
27  *	in the data file.
28  *
29  *	The data file contains the actual header data.  Each article is
30  *	represented by a Header, an array of Cross Postings, and the
31  *	strings representing the sender name and the article subject:
32  *
33  *		header
34  *		group_number 1 [ if cross posted ]
35  *		group_number 2
36  *		...
37  *		sender name (null terminated) [if sender_length > 0]
38  *		subject (null terminated) [if subject_length > 0]
39  *
40  *	For a digest, cross posted groups are only specified for the
41  *	first entry (the header entry).
42  *
43  *	On disk, the article_number is negative for digest article
44  *	header and zero for following sub articles.
45  *
46  *	The format of the index and data files are specified below.
47  *
48  *	Unless NETWORK_DATABASE is defined, the database will
49  *	will contain machine dependent binary data.
50  */
51 
52 #ifndef _NN_DB_H
53 #define _NN_DB_H 1
54 
55 #ifdef NETWORK_DATABASE
56 typedef int32   cross_post_number;
57 
58 #ifdef NETWORK_BYTE_ORDER
59 #define NETW_CROSS_INT(cp) cp
60 #define NETW_CROSS_EXT(cp) cp
61 #else
62 #define NETW_CROSS_INT(cp) ntohl(cp)
63 #define NETW_CROSS_EXT(cp) htonl(cp)
64 #endif
65 
66 #else
67 typedef group_number cross_post_number;
68 #define NETW_CROSS_INT(cp) cp
69 #define NETW_CROSS_EXT(cp) cp
70 #endif
71 
72 typedef struct {
73     article_number  dh_number;
74 
75     time_stamp      dh_date;	/* encoded Date: filed (not a time_t value!!) */
76 
77     off_t           dh_hpos;	/* absolute offset for first byte of header */
78     off_t           dh_lpos;	/* absolute offset for last byte of article */
79     int16           dh_fpos;	/* relative offset for first byte in article
80 				 * text */
81 
82     int16           dh_lines;
83     int8            dh_replies;
84 
85     int8            dh_cross_postings;
86     int8            dh_subject_length;
87     int8            dh_sender_length;
88 }               data_header;
89 
90 #define DBUF_SIZE	255
91 
92 typedef struct {
93     int             dh_type;
94 
95 #define	DH_NORMAL		0
96 #define	DH_DIGEST_HEADER	1
97 #define DH_SUB_DIGEST		2
98 
99     cross_post_number dh_cross[DBUF_SIZE + 1];
100     char            dh_sender[DBUF_SIZE + 1];
101     char            dh_subject[DBUF_SIZE + 1];
102 }               data_dynamic_data;
103 
104 
105 #ifndef NOV
106 int             open_groups(int);
107 void            close_groups(void);
108 void            db_rewrite_groups(int, group_header *);
109 int             db_parse_group(register group_header *, int);
110 void            db_write_master(void);
111 int             db_write_art(FILE * f);
112 long            get_data_offset(group_header *, article_number);
113 int             db_write_offset(FILE *, long *);
114 #endif
115 
116 int             init_group(register group_header *);
117 void            open_master(int);
118 void            db_expand_master(void);
119 void            close_master(void);
120 int             update_group(group_header *);
121 void            sort_groups(void);
122 group_header   *lookup_no_alias(char *);
123 group_header   *lookup(char *);
124 int             art_collected(group_header *, article_number);
125 char           *db_data_path(char *, group_header *, char);
126 FILE           *open_data_file(group_header *, char, int);
127 void            db_write_group(register group_header *);
128 off_t           db_read_art(FILE *);
129 long            get_index_offset(group_header *, article_number);
130 int             db_read_offset(FILE *, long *);
131 
132 #ifdef  CACHE_PURPOSE
133 char           *purp_lookup(char *);
134 #endif
135 
136 #ifdef NOV
137 void            db_read_group(register group_header *, article_number, article_number);
138 #endif
139 
140 
141 extern data_header db_hdr;
142 extern data_dynamic_data db_data;
143 #endif				/* _NN_DB_H */
144