conf.c
上传用户:knt0001
上传日期:2022-01-28
资源大小:264k
文件大小:8k
源码类别:

Email客户端

开发平台:

C/C++

  1. /**
  2.     eMail is a command line SMTP client.
  3.     Copyright (C) 2001 - 2008 email by Dean Jones
  4.     Software supplied and written by http://www.cleancode.org
  5.     This file is part of eMail.
  6.     eMail is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.     eMail is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.     You should have received a copy of the GNU General Public License
  15.     along with eMail; if not, write to the Free Software
  16.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17. **/
  18. #if HAVE_CONFIG_H
  19. # include "config.h"
  20. #endif
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <unistd.h>
  25. #include <pwd.h>
  26. #include <sys/utsname.h>
  27. #include <sys/types.h>
  28. #include "email.h"
  29. #include "conf.h"
  30. #include "utils.h"
  31. #include "error.h"
  32. #define MAX_CONF_VARS 20
  33. /* There are the variables accepted in the configuration file */
  34. static char conf_vars[MAX_CONF_VARS][MAXBUF] = {
  35. "SMTP_SERVER",
  36. "SMTP_PORT",
  37. "SENDMAIL_BIN",
  38. "MY_NAME",
  39. "MY_EMAIL",
  40. "REPLY_TO",
  41. "SIGNATURE_FILE",
  42. "ADDRESS_BOOK",
  43. "SAVE_SENT_MAIL",
  44. "TEMP_DIR",
  45. "GPG_BIN",
  46. "GPG_PASS",
  47. "SMTP_AUTH",
  48. "USE_TLS",
  49. "SMTP_AUTH_USER",
  50. "SMTP_AUTH_PASS",
  51. "VCARD"
  52. };
  53. /**
  54.  * Make sure that var is part of a possible 
  55.  * configuration variable in the configure file
  56. **/
  57. static int
  58. checkVar(dstrbuf *var)
  59. {
  60. int i;
  61. for (i = 0; i < MAX_CONF_VARS; i++) {
  62. if (strcasecmp(var->str, conf_vars[i]) == 0) {
  63. return 0;
  64. }
  65. }
  66. /*
  67. for (i=0; i < MAX_DEP_CONF_VARS; i++) {
  68. if (strcasecmp(var->str, dep_conf_vars[i]) == 0) {
  69. warning("Deprecated variable: %sn", var->str);
  70. return 0;
  71. }
  72. }
  73. */
  74. return -1;
  75. }
  76. /**
  77.  * Check the hash values to make sure they aren't 
  78.  * NULL.  IF they aren't, then Hash them, other
  79.  * wise, ERROR 
  80. **/
  81. static int
  82. hashit(const char *var, const char *val)
  83. {
  84. if ((*var == '') && (*val == '')) {
  85. /* Nothing to hash */
  86. return -1;
  87. } else if ((*var == '') || (*val == '')) {
  88. /* Something went wrong */
  89. return ERROR;
  90. }
  91. /* Don't store if there is something already there. */
  92. if (!getConfValue(var)) {
  93. setConfValue(var, xstrdup(val));
  94. }
  95. return 0;
  96. }
  97. /**
  98.  * Read the configuration file char by char and make
  99.  * sure each char is taken care of properly.
  100.  * Hash each token we get.  Newlines are considered the
  101.  * end of the expression if a  is not found.
  102. **/
  103. int
  104. readConfig(FILE *in)
  105. {
  106. int ch, line=1;
  107. int retval=0;
  108. dstrbuf *var, *val;
  109. dstrbuf *ptr;   /* start with var first */
  110. var = DSB_NEW;
  111. val = DSB_NEW;
  112. ptr = var;
  113. while ((ch = fgetc(in)) != EOF) {
  114. switch (ch) {
  115. case '#':
  116. while ((ch = fgetc(in)) != 'n')
  117. ; /* Deal with newline below */
  118. break;
  119. case '\':
  120. ch = fgetc(in);
  121. if (ch == 'r') {
  122. ch = fgetc(in);
  123. }
  124. if (ch != 'n') {
  125. dsbCatChar(ptr, ch);
  126. }
  127. line++;
  128. /* If this char is a newline, 
  129.    we don't want to handle it below */
  130. ch = 0; 
  131. break;
  132. case ''':
  133. if (copyUpTo(ptr, ch, in) == 'n') {
  134. /* If newline was found before end quote */
  135. ch = line;
  136. goto exit;
  137. }
  138. break;
  139. case '"':
  140. if (copyUpTo(ptr, ch, in) == 'n') {
  141. /* Newline was found before end quote. ERROR */
  142. ch = line;
  143. goto exit;
  144. }
  145. break;
  146. case '=':
  147. if (val->len != 0) {
  148. ch = line;
  149. goto exit;
  150. } else if (checkVar(var) < 0) {
  151. fatal("Variable: '%s' is not validn", var);
  152. ch = line;
  153. goto exit;
  154. }
  155. ptr = val;
  156. break;
  157. case ' ':
  158. /* Nothing for spaces */
  159. break;
  160. case 't':
  161. /* Nothing for tabs */
  162. break;
  163. case 'r':
  164. /* Ignore */
  165. break;
  166. case 'n':
  167. /* Handle Newlines below */
  168. break;
  169. default:
  170. dsbCatChar(ptr, ch);
  171. break;
  172. }
  173. /* See about the newline, hash vals if possible */
  174. if (ch == 'n') {
  175. line++;
  176. retval = hashit(var->str, val->str);
  177. if (retval == -1) {
  178. /* No error, just keep going */
  179. continue;
  180. } else if (retval == ERROR) {
  181. ch = line;
  182. goto exit;
  183. }
  184. /* Everything went fine. */
  185. dsbDestroy(var);
  186. dsbDestroy(val);
  187. var = DSB_NEW;
  188. val = DSB_NEW;
  189. ptr = var;
  190. }
  191. }
  192. exit:
  193. dsbDestroy(var);
  194. dsbDestroy(val);
  195. return (ch);
  196. }
  197. /**
  198.  * Get the user name of the person running me
  199.  * Return Value: 
  200.  *    malloced string 
  201. **/
  202. static char *
  203. getSystemName(void)
  204. {
  205. int uid = getuid();
  206. char *name = NULL;
  207. struct passwd *ent;
  208. /* Try to get the "Real Name" of the user. Else, the user name */
  209. ent = getpwuid(uid);
  210. if (!ent) {
  211. name = xstrdup("Unknown User");
  212. } else if (ent->pw_gecos) {
  213. name = xstrdup(ent->pw_gecos);
  214. } else {
  215. name = xstrdup(ent->pw_name);
  216. }
  217. return name;
  218. }
  219. /**
  220.  * Get the email address of the person running me.
  221.  * this is done by getting the "user name" of the current
  222.  * person, and the host name running me.
  223.  * Return value:
  224.  *    malloced string
  225. **/
  226. static char *
  227. getSystemEmail(void)
  228. {
  229. int uid = getuid();
  230. char *email, *name, *host;
  231. struct utsname hinfo;
  232. struct passwd *ent;
  233. dstrbuf *buf = DSB_NEW;
  234. ent = getpwuid(uid);
  235. if (!ent) {
  236. name = "unknown";
  237. } else {
  238. name = ent->pw_name;
  239. }
  240. if (uname(&hinfo) < 0) {
  241. host = "localhost";
  242. } else {
  243. host = hinfo.nodename;
  244. }
  245. /* format it all */
  246. dsbPrintf(buf, "%s@%s", name, host);
  247. email = xstrdup(buf->str);
  248. dsbDestroy(buf);
  249. return email;
  250. }
  251. /**
  252.  * Figure out where the config is located and open it.
  253.  */
  254. FILE *
  255. openConfig(bool check)
  256. {
  257. FILE *config=NULL;
  258. char *file=NULL;
  259. if (conf_file == NULL) {
  260. dstrbuf *hconfig = expandPath("~/.email.conf");
  261. config = fopen(hconfig->str, "r");
  262. if (!config) {
  263. config = fopen(MAIN_CONFIG, "r");
  264. file = MAIN_CONFIG;
  265. } else {
  266. file = hconfig->str;
  267. }
  268. if (check) {
  269. printf("-- Opened config %sn", file);
  270. }
  271. dsbDestroy(hconfig);
  272. } else {
  273. config = fopen(conf_file, "r");
  274. if (check) {
  275. printf("-- Opened config %sn", conf_file);
  276. }
  277. }
  278. return config;
  279. }
  280. /**
  281.  * This function is used to just run through the configuration file
  282.  * and simply check the syntax.  No extra configuration takes place
  283.  * here.
  284. **/
  285. void
  286. checkConfig(void)
  287. {
  288. int line = 0;
  289. FILE *config = openConfig(true);
  290. /* Couldn't open any possible configuration file */
  291. if (!config) {
  292. fatal("Could not open any possible configuration file");
  293. properExit(ERROR);
  294. }
  295. line = readConfig(config);
  296. fclose(config);
  297. if (line > 0) {
  298. fatal("Line: %d of email.conf is improperly formatted.n", line);
  299. properExit(ERROR);
  300. }
  301. }
  302. /**
  303.  * this function will read the configuration file and store all values
  304.  * in a hash table.  If some values were specified on the comand line
  305.  * it will allow those to override what is in the configuration file.
  306.  * If any of the manditory configuration variables are not found on the
  307.  * command line or in the config file, it will set default values for them.
  308. **/
  309. void
  310. configure(void)
  311. {
  312. int line = 0;
  313. FILE *config = openConfig(false);
  314. /**
  315. * smtp server can be overwitten by command line option -r
  316. * in which we don't want to insist on a configuration file
  317. * being available.  If there isn't a config file, we will 
  318. * and an SMTP server was specified, we will set smtp_port
  319. * to 25 as a default if they didn't already specify it
  320. * on the command line as well.  If they didn't specify an
  321. * smtp server, we'll default to sendmail.
  322. **/
  323. if (!config) {
  324. if (!getConfValue("MY_NAME")) {
  325. setConfValue("MY_NAME", getSystemName());
  326. }
  327. if (!getConfValue("MY_EMAIL")) {
  328. setConfValue("MY_EMAIL", getSystemEmail());
  329. }
  330. /* If they didn't specify an smtp server, use sendmail */
  331. if (!getConfValue("SMTP_SERVER")) {
  332. setConfValue("SENDMAIL_BIN", xstrdup("/usr/lib/sendmail -t -i"));
  333. } else {
  334. if (!getConfValue("SMTP_PORT")) {
  335. setConfValue("SMTP_PORT", xstrdup("25"));
  336. }
  337. }
  338. } else {
  339. line = readConfig(config);
  340. fclose(config);
  341. if (line > 0) {
  342. fatal("email.conf: Format error: Line number %dn", line);
  343. properExit(ERROR);
  344. }
  345. /* If port wasn't in config file or specified on command line */
  346. if (!getConfValue("SMTP_PORT")) {
  347. setConfValue("SMTP_PORT", xstrdup("25"));
  348. }
  349. /* If name wasn't specified */
  350. if (!getConfValue("MY_NAME")) {
  351. setConfValue("MY_NAME", getSystemName());
  352. }
  353. /* If email address wasn't in the config file */
  354. if (!getConfValue("MY_EMAIL")) {
  355. setConfValue("MY_EMAIL", getSystemEmail());
  356. }
  357. }
  358. }