file.c
上传用户:qin5330
上传日期:2007-01-05
资源大小:114k
文件大小:12k
源码类别:

搜索引擎

开发平台:

Perl

  1. /*
  2. ** Copyright (C) 1995, 1996, 1997, 1998 Hewlett-Packard Company
  3. ** Originally by Kevin Hughes, kev@kevcom.com, 3/11/94
  4. **
  5. ** This program and library is free software; you can redistribute it and/or
  6. ** modify it under the terms of the GNU (Library) General Public License
  7. ** as published by the Free Software Foundation; either version 2
  8. ** of the License, or any later version.
  9. **
  10. ** This program 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 (Library) General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU (Library) General Public License
  16. ** along with this program; if not, write to the Free Software
  17. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18. **-------------------------------------------------------------
  19. ** Changed getdefaults to allow metaNames in the user
  20. ** configuration file
  21. ** G.Hill 4/16/97 ghill@library.berkeley.edu
  22. */
  23. #include "swish.h"
  24. #include "file.h"
  25. #include "mem.h"
  26. #include "string.h"
  27. #include "error.h"
  28. #include "list.h"
  29. #include "hash.h"
  30. #include "index.h"
  31. /* Is a file a directory?
  32. */
  33. int isdirectory(path)
  34. char *path;
  35. {
  36. struct stat stbuf;
  37. if (stat(path, &stbuf))
  38. return 0;
  39. return ((stbuf.st_mode & S_IFMT) == S_IFDIR) ? 1 : 0;
  40. }
  41. /* Is a file a regular file?
  42. */
  43. int isfile(path)
  44. char *path;
  45. {
  46. struct stat stbuf;
  47. if (stat(path, &stbuf))
  48. return 0;
  49. return ((stbuf.st_mode & S_IFMT) == S_IFREG) ? 1 : 0;
  50. }
  51. /* Is a file a link?
  52. */
  53. int islink(path)
  54. char *path;
  55. {
  56. #ifndef NO_SYMBOLIC_FILE_LINKS
  57. struct stat stbuf;
  58. if (lstat(path, &stbuf))
  59. return 0;
  60. return ((stbuf.st_mode & S_IFLNK) == S_IFLNK) ? 1 : 0;
  61. #else
  62. return 0;
  63. #endif
  64. }
  65. /* Get the size, in bytes, of a file.
  66. ** Return -1 if there's a problem.
  67. */
  68. int getsize(path)
  69. char *path;
  70. {
  71. struct stat stbuf;
  72. if (stat(path, &stbuf))
  73. return -1;
  74. return stbuf.st_size;
  75. }
  76. /* Add an entry to the metaEntryList with the given value and the
  77. ** appropriate index
  78. */
  79. void addMetaEntry(metaList, metaWord, isDocProp)
  80. struct metaEntry** metaList;
  81. char* metaWord;
  82. int isDocProp;
  83. {
  84. static int counter;
  85. int i;
  86. struct metaEntry* newEntry;
  87. struct metaEntry* tmpEntry;
  88. if (counter == 0)
  89. counter = 2;
  90. else if (counter == 1 ||  (!counter % 128) )
  91. counter++;
  92. for( i=0; metaWord[i]; i++)
  93. metaWord[i] =  tolower(metaWord[i]);
  94. tmpEntry = *metaList;
  95. while (tmpEntry)
  96. {
  97. if (strcmp(tmpEntry->metaName, metaWord) == 0)
  98. {
  99. #ifdef SUPPORT_DOC_PROPERTIES
  100. /*
  101.  * found a duplicate entry already in the list.
  102.  * Since there are two different config tags that can
  103.  * be used to get here (MetaNames and PropertyNames)
  104.  * and that might be using the same Meta tag name,
  105.  * we cannot assume that either one of these was
  106.  * called first.
  107.  * The semantics we want for the metaEntry are:
  108.  * isDocProperty = 1 if in PropertyNames, else 0
  109.  * isOnlyDocProperty = 1 if not in MetaNames, else 0
  110.  */
  111. if (isDocProp)
  112. {
  113. /* this is a DocumentProperty tag */
  114. if (!tmpEntry->isDocProperty)
  115. {
  116. tmpEntry->isDocProperty = 1;
  117. }
  118. }
  119. else
  120. {
  121. /* this is a MetaName tag */
  122. if (tmpEntry->isDocProperty)
  123. {
  124. tmpEntry->isOnlyDocProperty = 0;
  125. }
  126. }
  127. #endif
  128. return;
  129. }
  130. tmpEntry = tmpEntry->next;
  131. }
  132. newEntry = (struct metaEntry*) emalloc(sizeof(struct metaEntry));
  133. #ifdef SUPPORT_DOC_PROPERTIES
  134. /* isDocProp is true when we see the PropertyNames config tag */
  135. newEntry->isDocProperty = isDocProp;
  136. newEntry->isOnlyDocProperty = isDocProp;
  137. #endif
  138. newEntry->metaName = (char*)mystrdup(metaWord);
  139. newEntry->index = counter++;
  140. newEntry->next = NULL;
  141. if (*metaList)
  142. {
  143. for(tmpEntry=*metaList;tmpEntry->next!=NULL;tmpEntry=tmpEntry->next)
  144. ;
  145. tmpEntry->next = newEntry;
  146. }
  147. else
  148. *metaList = newEntry;
  149. return;
  150. }
  151. /*
  152.  * Some handy routines for parsing the Configuration File
  153.  */
  154. int grabYesNoField(line, commandTag, yesNoValue)
  155. char* line;
  156. char* commandTag;
  157. int* yesNoValue;
  158. {
  159. char value[MAXSTRLEN];
  160. if (getconfvalue(line, commandTag, value) != NULL)
  161. {
  162. *yesNoValue = (lstrstr(value, "yes")) ? 1 : 0;
  163. return 1; /* matched commandTag */
  164. }
  165. return 0;
  166. }
  167. int grabStringValueField(line, commandTag, singleValue)
  168. char* line;
  169. char* commandTag;
  170. char* singleValue;
  171. {
  172. /* line must be "<commandTag> <stringValue>" */
  173. char value[MAXSTRLEN];
  174. if (getconfvalue(line, commandTag, value) != NULL)
  175. {
  176. strcpy(singleValue, value);
  177. return 1; /* matched commandTag */
  178. }
  179. return 0;
  180. }
  181. int grabIntValueField(line, commandTag, singleValue, dontToIt)
  182. char* line;
  183. char* commandTag;
  184. int* singleValue;
  185. int dontToIt;
  186. {
  187. char value[MAXSTRLEN];
  188. if (!grabStringValueField(line, commandTag, value))
  189. return 0;
  190. if ((value[0]) && (value[0] != 'n') && !dontToIt)
  191. {
  192. *singleValue = atoi(value);
  193. }
  194. return 1; /* matched commandTag */
  195. }
  196. int grabCmdOptionsMega(line, 
  197.        commandTag,
  198.        listOfWords, 
  199.        gotAny, dontToIt)
  200. char* line;
  201. char* commandTag;
  202. struct swline **listOfWords;
  203. int* gotAny;
  204. int dontToIt;
  205. {
  206. /*
  207.  * parse the line if it contains commandTag 
  208.  * (commandTag is not required to be the first token in the line)
  209.  * Grab all of the words after commandTag and place them in the listOfWords.
  210.  * If "gotAny" is not NULL then set it to 1 if we grabbed any words.
  211.  * If dontDoIt is "1" then do not grab the words.
  212.  * Line may be "<commandTag> <stringValue> .." but it could also
  213.  * be "<other commands> <commandTag> <stringValue> .."
  214.  */
  215. line = lstrstr(line, commandTag); /* includes main command tag? */
  216. if (line == NULL)
  217. return 0;
  218. line += strlen(commandTag);
  219. /* grab all words after the command tag */
  220. if (!dontToIt)
  221. {
  222. char value[MAXSTRLEN];
  223. int skiplen;
  224. while (1) 
  225. {
  226. strcpy(value, getword(line, &skiplen));
  227. if (!skiplen | value[0] == '' || value[0] == 'n')
  228. {
  229. break;
  230. }
  231. else 
  232. {
  233. line += skiplen;
  234. *listOfWords = (struct swline *) addswline(*listOfWords, value);
  235. if (gotAny)
  236. *gotAny = 1;
  237. }
  238. }
  239. }
  240. return 1;
  241. }
  242. int grabCmdOptions(line, commandTag, listOfWords)
  243. char* line;
  244. char* commandTag;
  245. struct swline **listOfWords;
  246. {
  247. return grabCmdOptionsMega(line, commandTag, listOfWords, NULL, 0);
  248. }
  249. /* Reads the configuration file and puts all the right options
  250. ** in the right variables and structures.
  251. */
  252. void getdefaults(conffile, hasdir, hasindex, plimit, flimit, hasverbose)
  253. char *conffile;
  254. int *hasdir;
  255. int *hasindex;
  256. long *plimit;
  257. long *flimit;
  258. int hasverbose;
  259. {
  260. int skiplen, gotdir, gotindex;
  261. char *c, line[MAXSTRLEN], value[MAXSTRLEN];
  262. FILE *fp;
  263. int linenumber = 0;
  264. int baddirective = 0;
  265. gotdir = gotindex = 0;
  266. if ((fp = fopen(conffile, "r")) == NULL  ||
  267. !isfile(conffile) ) 
  268. {
  269. sprintf(errorstr, "Couldn't open the configuration file "%s".", conffile);
  270. progerr(errorstr);
  271. }
  272. while (fgets(line, MAXSTRLEN, fp) != NULL) 
  273. {
  274. linenumber++;
  275. if (line[0] == '#' || line[0] == 'n')
  276. continue;
  277. if (grabCmdOptionsMega(line, "IndexDir", &dirlist, &gotdir, *hasdir)) {}
  278. else if (grabCmdOptions(line, "NoContents", &nocontentslist)) {}
  279. else if (grabCmdOptionsMega(line, "IndexFile", &indexlist, &gotindex, *hasindex)) {}
  280. else if (grabIntValueField(line, "IndexReport", &verbose, hasverbose)) {}
  281. else if (grabIntValueField(line, "MinWordLimit", &minwordlimit, 0)) {}
  282. else if (grabIntValueField(line, "IndexComments", &indexComments, 0)) {}
  283. else if (grabIntValueField(line, "MaxWordLimit", &maxwordlimit, 0)) {}
  284. else if (grabStringValueField(line, "WordCharacters", wordchars)) {}
  285. else if (grabStringValueField(line, "BeginCharacters", beginchars)) {}
  286. else if (grabStringValueField(line, "EndCharacters", endchars)) {}
  287. else if (grabStringValueField(line, "IgnoreLastChar", ignorelastchar)) {}
  288. else if (grabStringValueField(line, "IgnoreFirstChar", ignorefirstchar)) {}
  289. else if (grabCmdOptions(line, "ReplaceRules", &replacelist)) { checkReplaceList(); }
  290. else if (grabYesNoField(line, "FollowSymLinks", &followsymlinks)) {}
  291. else if (grabStringValueField(line, "IndexName", indexn)) {}
  292. else if (grabStringValueField(line, "IndexDescription", indexd)) {}
  293. else if (grabStringValueField(line, "IndexPointer", indexp)) {}
  294. else if (grabStringValueField(line, "IndexAdmin", indexa)) {}
  295. else if (grabYesNoField(line, "UseStemming", &applyStemmingRules)) {} /* 11/24/98 MG */
  296. else if (grabYesNoField(line, "IgnoreTotalWordCountWhenRanking", &ignoreTotalWordCountWhenRanking)) {} /* 11/24/98 MG */
  297. else if (c = (char *) lstrstr(line, "MetaNames")) 
  298. {
  299. c += strlen("MetaNames");
  300. while (1) 
  301. {
  302. strcpy(value, (char *) getword(c, &skiplen));
  303. if (!skiplen | value[0] == '' || value[0] == 'n')
  304. {
  305. break;
  306. }
  307. else 
  308. {
  309. c += skiplen;
  310. addMetaEntry(&metaEntryList, value, 0);
  311. }
  312. }
  313. }
  314. #ifdef SUPPORT_DOC_PROPERTIES
  315. else if (c = (char *) lstrstr(line, "PropertyNames"))  /* 11/24/98 MG */
  316. {
  317. c += strlen("PropertyNames");
  318. while (1) 
  319. {
  320. strcpy(value, (char *) getword(c, &skiplen));
  321. if (!skiplen | value[0] == '' || value[0] == 'n')
  322. {
  323. break;
  324. }
  325. else 
  326. {
  327. c += skiplen;
  328. addMetaEntry(&metaEntryList, value, 1); /* isDocProp = 1 */
  329. }
  330. }
  331. }
  332. #endif
  333. else if (c = (char *) lstrstr(line, "IgnoreWords")) {
  334. c += strlen("IgnoreWords");
  335. while (1) {
  336. strcpy(value, (char *) getword(c, &skiplen));
  337. if (!skiplen || value[0] == '' || value[0] == 'n')
  338. break;
  339. else {
  340. c += skiplen;
  341. if (lstrstr(value, "SwishDefault"))
  342. readdefaultstopwords();
  343. else
  344. addstophash(value);
  345. }
  346. }
  347. }
  348. else if ((c = (char *) lstrstr(line, "IgnoreLimit"))) {
  349. c += strlen("IgnoreLimit");
  350. strcpy(value, (char *) getword(c, &skiplen));
  351. if (!skiplen || value[0] == '' || value[0] == 'n')
  352. continue;
  353. else {
  354. c += skiplen;
  355. *plimit = atoi(value);
  356. }
  357. strcpy(value, (char *) getword(c, &skiplen));
  358. if (!skiplen || value[0] == '' || value[0] == 'n')
  359. continue;
  360. else {
  361. c += skiplen;
  362. *flimit = atoi(value);
  363. }
  364. }
  365. /* IndexVerbose is supported for backwards compatibility */
  366. else if (c = (char *) lstrstr(line, "IndexVerbose")) {
  367. c += strlen("IndexVerbose");
  368. strcpy(value, (char *) getword(c, &skiplen));
  369. verbose = (lstrstr(value, "yes")) ? 3 : 0;
  370. }
  371. else if (!parseconfline(line)) {
  372. printf("Bad directive on line #%d: %s", linenumber, line );
  373. baddirective = 1;
  374. }
  375. }
  376. fclose(fp);
  377. if (baddirective)
  378. exit(1);
  379. if (gotdir && !(*hasdir))
  380. *hasdir = 1;
  381. if (gotindex && !(*hasindex))
  382. *hasindex = 1;
  383. }
  384. /* Checks that all the regex in the replace list are correct */
  385. void checkReplaceList() 
  386. {
  387. struct swline *tmpReplace;
  388. char rule[MAXSTRLEN], patt[MAXSTRLEN];
  389. regex_t re;
  390. int status;
  391. tmpReplace = replacelist;
  392. while (tmpReplace) {
  393. strcpy(rule,tmpReplace->line);
  394. /*  If it is not replace, just do nothing */
  395. if (lstrstr(rule,"append") || lstrstr(rule,"prepend") ) {
  396. if (tmpReplace->next){
  397. tmpReplace = tmpReplace->next;
  398. }
  399. else
  400. return;
  401. }
  402. if (lstrstr(rule,"replace")) {
  403. tmpReplace = tmpReplace->next;
  404. strcpy(patt,tmpReplace->line);
  405. if (patt == NULL) 
  406. return;
  407. status = regcomp(&re,patt, REG_EXTENDED);
  408. if (status != 0) {
  409. printf ("Illegal regular expression %sn", patt);
  410. exit(0);
  411. }
  412. if (tmpReplace->next) 
  413. tmpReplace = tmpReplace->next;
  414. else
  415. return;
  416. }
  417. tmpReplace = tmpReplace->next;
  418. }
  419. }
  420. /* This is similar to the previous one, just kept separated because */
  421. /* of the different structure of the list                           */
  422. void checkListRegex (list) 
  423. struct swline *list;
  424. {
  425. struct swline *tmpReplace;
  426. char patt[MAXSTRLEN];
  427. regex_t re;
  428. int status;
  429. tmpReplace = replacelist;
  430. while (tmpReplace) {
  431. strcpy(patt,tmpReplace->line);
  432. if (patt == NULL) 
  433. return;
  434. status = regcomp(&re,patt, REG_EXTENDED);
  435. if (status != 0) {
  436. printf ("Illegal regular expression %sn", patt);
  437. exit(0);
  438. }
  439. tmpReplace = tmpReplace->next;
  440. }
  441. }/* end of checkListRegex */