calculate the directories in a central manner.
[citadel.git] / citadel / config.c
1 /*
2  * $Id$
3  *
4  * This function reads the citadel.config file.  It should be called at
5  * the beginning of EVERY Citadel program.
6  *
7  */
8
9 #include "sysdep.h"
10 #include <stdlib.h>
11 #include <sys/stat.h>
12 #include <unistd.h>
13 #include <stdio.h>
14 #include <errno.h>
15 #include <string.h>
16 #include <limits.h>
17 #include "citadel.h"
18 #include "server.h"
19 #include "serv_extensions.h"
20 #include "config.h"
21
22 struct config config;
23 /* CTDLDIR */
24 char ctdl_home_directory[PATH_MAX] = "";
25 char ctdl_bio_dir[PATH_MAX]="bio";
26 char ctdl_bb_dir[PATH_MAX]="bitbucket";
27 char ctdl_data_dir[PATH_MAX]="data";
28 char ctdl_file_dir[PATH_MAX]="files";
29 char ctdl_hlp_dir[PATH_MAX]="help";
30 char ctdl_image_dir[PATH_MAX]="images";
31 char ctdl_info_dir[PATH_MAX]="info";
32 char ctdl_key_dir[PATH_MAX]="keys";
33 char ctdl_message_dir[PATH_MAX]="messages";
34 char ctdl_usrpic_dir[PATH_MAX]="userpics";
35 char ctdl_etc_dir[PATH_MAX]="";
36 char ctdl_run_dir[PATH_MAX]="";
37 char ctdl_spool_dir[PATH_MAX]="network";
38 char ctdl_netout_dir[PATH_MAX]="network/spoolout";
39 char ctdl_netin_dir[PATH_MAX]="network/spoolin";
40
41 int home_specified = 0;
42
43 /*
44  * get_config() is called during the initialization of any program which
45  * directly accesses Citadel data files.  It verifies the system's integrity
46  * and reads citadel.config into memory.
47  */
48 void get_config(void) {
49         FILE *cfp;
50         struct stat st;
51
52         if (chdir(home_specified ? ctdl_home_directory : CTDLDIR) != 0) {
53                 fprintf(stderr,
54                         "This program could not be started.\n"
55                         "Unable to change directory to %s\n"
56                         "Error: %s\n",
57                         (home_specified ? ctdl_home_directory : CTDLDIR),
58                         strerror(errno));
59                 exit(1);
60         }
61         cfp = fopen(
62 #ifndef HAVE_ETC_DIR
63                                 "."
64 #else
65                                 ETC_DIR
66 #endif
67                                 "/citadel.config", "rb");
68         if (cfp == NULL) {
69                 fprintf(stderr, "This program could not be started.\n"
70                         "Unable to open %s/citadel.config\n"
71                         "Error: %s\n",
72                         (home_specified ? ctdl_home_directory : CTDLDIR),
73                         strerror(errno));
74                 exit(1);
75         }
76         fread((char *) &config, sizeof(struct config), 1, cfp);
77         if (fstat(fileno(cfp), &st)) {
78                 perror("citadel.config");
79                 exit(1);
80         }
81 #ifndef __CYGWIN__
82         if (st.st_uid != CTDLUID || st.st_mode != (S_IFREG | S_IRUSR | S_IWUSR)) {
83                 fprintf(stderr, "check the permissions on citadel.config\n");
84                 exit(1);
85         }
86 #endif
87         fclose(cfp);
88
89         if (config.c_setup_level < REV_MIN) {
90                 fprintf(stderr, "config: Your data files are out of date.  ");
91                 fprintf(stderr, "Run setup to update them.\n");
92                 fprintf(stderr,
93                         "        This program requires level %d.%02d\n",
94                         (REV_LEVEL / 100), (REV_LEVEL % 100));
95                 fprintf(stderr,
96                         "        Data files are currently at %d.%02d\n",
97                         (config.c_setup_level / 100),
98                         (config.c_setup_level % 100));
99                 exit(1);
100         }
101
102         /* Default maximum message length is 10 megabytes.  This is site
103          * configurable.  Also check to make sure the limit has not been
104          * set below 8192 bytes.
105          */
106         if (config.c_maxmsglen <= 0)
107                 config.c_maxmsglen = 10485760;
108         if (config.c_maxmsglen < 8192)
109                 config.c_maxmsglen = 8192;
110
111         /* Default lower and upper limits on number of worker threads */
112
113         if (config.c_min_workers < 3)           /* no less than 3 */
114                 config.c_min_workers = 5;
115
116         if (config.c_max_workers == 0)                  /* default maximum */
117                 config.c_max_workers = 256;
118
119         if (config.c_max_workers < config.c_min_workers)   /* max >= min */
120                 config.c_max_workers = config.c_min_workers;
121
122         /* Networking more than once every five minutes just isn't sane */
123         if (config.c_net_freq == 0L)
124                 config.c_net_freq = 3600L;      /* once per hour default */
125         if (config.c_net_freq < 300L) 
126                 config.c_net_freq = 300L;
127 }
128
129
130 /*
131  * Occasionally, we will need to write the config file, because some operations
132  * change site-wide parameters.
133  */
134 void put_config(void)
135 {
136         FILE *cfp;
137
138         if ((cfp = fopen(
139 #ifndef HAVE_ETC_DIR
140                                          "."
141 #else
142                                          ETC_DIR
143 #endif
144                                          "/citadel.config", "rb+")) == NULL)
145                 perror("citadel.config");
146         else {
147                 fwrite((char *) &config, sizeof(struct config), 1, cfp);
148                 fclose(cfp);
149         }
150 }