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

搜索引擎

开发平台:

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. **  long 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. */
  20. #include "swish.h"
  21. #include "index.h"
  22. #include "hash.h"
  23. #include "mem.h"
  24. #include "file.h"
  25. #include "string.h"
  26. #include "list.h"
  27. static void indexadir(char *dir);
  28. static void indexafile(char *path);
  29. static void printfiles(struct sortentry *e);
  30. static void printdirs(struct sortentry *e);
  31. static int ishtml(char *filename);
  32. static int isoktitle(char *title);
  33. /* file system specific configuration parameters
  34. **/
  35. static struct swline *pathconlist = 0;
  36. static struct swline *dirconlist = 0;
  37. static struct swline *fileconlist = 0;
  38. static struct swline *titconlist = 0;
  39. static struct swline *fileislist = 0;
  40. static struct swline *suffixlist = 0;
  41. static struct swline *nocontentslist = 0;
  42. /* Have we already indexed a file or directory?
  43. ** This function is used to avoid multiple index entries
  44. ** or endless looping due to symbolic links.
  45. */
  46. static int already_indexed(char *path)
  47. {
  48. #ifndef NO_SYMBOLIC_FILE_LINKS
  49. static struct dev_ino {
  50. dev_t  dev;
  51. ino_t  ino;
  52. struct dev_ino *next;
  53. } *inode_hash[BIGHASHSIZE], *p;
  54. struct stat buf;
  55. char key[34];           /* Hash key -- allow for 64 bit inodes */
  56. unsigned hashval;
  57. if ( stat( path, &buf ) )
  58. return 0;
  59. /* Create hash key:  string contains device and inode. */
  60. sprintf( key, "%lx/%lx", (unsigned long)buf.st_dev,
  61. (unsigned long)buf.st_ino  );
  62. hashval = bighash(key); /* Search hash for this file. */
  63. for ( p = inode_hash[hashval]; p != NULL; p = p->next )
  64. if ( p->dev == buf.st_dev &&
  65. p->ino == buf.st_ino    )
  66. {                               /* We found it. */
  67. if ( verbose == 3 )
  68. printf( "Skipping %s:  %sn",
  69. path, "Already indexed." );
  70. return 1;
  71. }
  72. /* Not found, make new entry. */
  73. p = (struct dev_ino*)emalloc(sizeof(struct dev_ino));
  74. p->dev = buf.st_dev;
  75. p->ino = buf.st_ino;
  76. p->next = inode_hash[hashval];
  77. inode_hash[hashval] = p;
  78. #endif
  79. return 0;
  80. }
  81. /* Recursively goes into a directory and calls the word-indexing
  82. ** functions for each file that's found.
  83. */
  84. static void indexadir(char *dir)
  85. {
  86. int badfile;
  87. DIR *dfd;
  88. #ifdef NEXTSTEP
  89. struct direct *dp;
  90. #else
  91. struct dirent *dp;
  92. #endif
  93. static char s[MAXFILELEN], title[MAXSTRLEN];
  94. struct sortentry *sortfilelist, *sortdirlist;
  95. struct swline *tmplist;
  96. sortfilelist = sortdirlist = NULL;
  97. if (islink(dir) && !followsymlinks)
  98. return;
  99. if ( already_indexed(dir) )
  100. return;
  101. if (dir[strlen(dir) - 1] == '/')
  102. dir[strlen(dir) - 1] = '';
  103. if ((dfd = opendir(dir)) == NULL)
  104. return;
  105. while ((dp = readdir(dfd)) != NULL && dirconlist != NULL) {
  106. badfile = 0;
  107. tmplist = dirconlist;
  108. while (tmplist != NULL) {
  109. if (matchARegex(dp->d_name, tmplist->line)) {
  110. badfile = 1;
  111. break;
  112. }
  113. tmplist = tmplist->next;
  114. }
  115. if (badfile)
  116. return;
  117. }
  118. closedir(dfd);
  119. dfd = opendir(dir);
  120. while ((dp = readdir(dfd)) != NULL) {
  121. if ((dp->d_name)[0] == '.')
  122. continue;
  123. if (islink(dp->d_name) && !followsymlinks)
  124. continue;
  125. badfile = 0;
  126. tmplist = fileislist;
  127. while (tmplist != NULL) {
  128. if (matchARegex(dp->d_name, tmplist->line)) {
  129. badfile = 1;
  130. break;
  131. }
  132. tmplist = tmplist->next;
  133. }
  134. if (badfile)
  135. continue;
  136. badfile = 0;
  137. tmplist = fileconlist;
  138. while (tmplist != NULL) {
  139. if (matchARegex(dp->d_name, tmplist->line)) {
  140. badfile = 1;
  141. break;
  142. }
  143. tmplist = tmplist->next;
  144. }
  145. if (badfile)
  146. continue;
  147. sprintf(s, "%s%s%s", dir, dir[strlen(dir) - 1] == '/' ?
  148. "" : "/", dp->d_name);
  149. if (islink(s) && !followsymlinks)
  150. continue;
  151. badfile = 0;
  152. tmplist = pathconlist;
  153. while (tmplist != NULL) {
  154. if (matchARegex(s, tmplist->line)) {
  155. badfile = 1;
  156. break;
  157. }
  158. tmplist = tmplist->next;
  159. }
  160. if (badfile)
  161. continue;
  162. if (!isdirectory(s)) {
  163. if ( already_indexed(s) )
  164. continue;
  165. if (!isoksuffix(dp->d_name, suffixlist))
  166. continue;
  167. if (ishtml(s)) {
  168. strcpy(title, (char *) parsetitle(s, s));
  169. if (!isoktitle(title))
  170. continue;
  171. }
  172. else {
  173. if (strrchr(s, '/') != NULL)
  174. strcpy(title, strrchr(s, '/') + 1);
  175. else
  176. strcpy(title, s);
  177. }
  178. sortfilelist = (struct sortentry *)
  179. addsortentry(sortfilelist, s, title);
  180. }
  181. else {
  182. sortdirlist = (struct sortentry *)
  183. addsortentry(sortdirlist, s, s);
  184. }
  185. }
  186. closedir(dfd);
  187. printfiles(sortfilelist);
  188. printdirs(sortdirlist);
  189. }
  190. /* Calls the word-indexing function for a single file.
  191. */
  192. static void indexafile(char *path)
  193. {
  194. int badfile;
  195. char *t, title[MAXSTRLEN];
  196. struct sortentry *fileentry;
  197. struct swline *tmplist;
  198. if (islink(path) && !followsymlinks)
  199. return;
  200. if ( already_indexed(path) )
  201. return;
  202. if (path[strlen(path) - 1] == '/')
  203. path[strlen(path) - 1] = '';
  204. badfile = 0;
  205. tmplist = fileislist;
  206. while (tmplist != NULL) {
  207. if (!matchARegex(path, tmplist->line)) {
  208. badfile = 1;
  209. break;
  210. }
  211. tmplist = tmplist->next;
  212. }
  213. if (badfile)
  214. return;
  215. badfile = 0;
  216. tmplist = fileconlist;
  217. while (tmplist != NULL) {
  218. if (matchARegex(path, tmplist->line)) {
  219. badfile = 1;
  220. break;
  221. }
  222. tmplist = tmplist->next;
  223. }
  224. if (badfile)
  225. return;
  226. badfile = 0;
  227. tmplist = pathconlist;
  228. while (tmplist != NULL) {
  229. if (matchARegex(path, tmplist->line)) {
  230. badfile = 1;
  231. break;
  232. }
  233. tmplist = tmplist->next;
  234. }
  235. if (badfile)
  236. return;
  237. if (!isoksuffix(path, suffixlist))
  238. return;
  239. if (ishtml(path)) {
  240. strcpy(title, (char *) parsetitle(path, path));
  241. if (!isoktitle(title))
  242. return;
  243. }
  244. else {
  245. if ((t = strrchr(path, '/')) != NULL)
  246. strcpy(title, t + 1);
  247. else
  248. strcpy(title, path);
  249. }
  250. fileentry = (struct sortentry *) emalloc(sizeof(struct sortentry));
  251. fileentry->filename = (char *) mystrdup(path);
  252. fileentry->title = (char *) mystrdup(title);
  253. fileentry->left = fileentry->right = NULL;
  254. printfiles(fileentry);
  255. }
  256. /* Indexes the words in the tree of files in alphabetical order.
  257. */
  258. static void printfiles(struct sortentry *e)
  259. {
  260. int wordcount;
  261. char *s;
  262. FILE *fp;
  263. if (e != NULL) {
  264. printfiles(e->left);
  265. if (verbose == 3) {
  266. if ((s = (char *) strrchr(e->filename, '/')) == NULL)
  267. printf("  %s", e->filename);
  268. else
  269. printf("  %s", s + 1);
  270. }
  271. if ((fp = fopen(e->filename, "r" )) != NULL ) {
  272. wordcount = countwords(fp, e->filename, e->title,
  273. isoksuffix(e->filename, nocontentslist) && nocontentslist != NULL);
  274. fclose(fp);
  275. }
  276. if (verbose == 3) {
  277. if (wordcount)
  278. printf(" (%d words)n", wordcount);
  279. else
  280. printf(" (no words)n");
  281. fflush(stdout);
  282. }
  283. free(e->filename);
  284. free(e->title);
  285. printfiles(e->right);
  286. free(e);
  287. }
  288. }
  289. /* Prints out the directory names as things are getting indexed.
  290. ** Calls indexadir() so directories in the tree are indexed,
  291. ** in alphabetical order...
  292. */
  293. static void printdirs(struct sortentry *e)
  294. {
  295. if (e != NULL) {
  296. printdirs(e->left);
  297. if (verbose == 3)
  298. printf("nIn dir "%s":n", e->filename);
  299. else if (verbose == 2)
  300. printf("Checking dir "%s"...n", e->filename);
  301. indexadir(e->filename);
  302. free(e->filename);
  303. free(e->title);
  304. printdirs(e->right);
  305. free(e);
  306. }
  307. }
  308. /* This checks is a filename has one of the following suffixes:
  309. ** "htm", "HTM", "html", "HTML", "shtml", "SHTML".
  310. */
  311. int ishtml(filename)
  312. char *filename;
  313. {
  314. char *c, suffix[MAXSUFFIXLEN];
  315. c = (char *) strrchr(filename, '.');
  316. if (c == NULL)
  317. return 0;
  318. strcpy(suffix, c + 1);
  319. if (suffix[0] == '')
  320. return 0;
  321. if (!strncmp(suffix, "htm", 3))
  322. return 1;
  323. else if (!strncmp(suffix, "HTM", 3))
  324. return 1;
  325. else if (!strncmp(suffix, "shtml", 5))
  326. return 1;
  327. else if (!strncmp(suffix, "SHTML", 5))
  328. return 1;
  329. return 0;
  330. }
  331. /* Check if a particular title should be ignored
  332. ** according to the settings in the configuration file.
  333. */
  334. int isoktitle(title)
  335. char *title;
  336. {
  337. int badfile;
  338. struct swline *tmplist;
  339. badfile = 0;
  340. tmplist = titconlist;
  341. while (tmplist != NULL) {
  342. if (matchARegex(title, tmplist->line)) {
  343. badfile = 1;
  344. break;
  345. }
  346. tmplist = tmplist->next;
  347. }
  348. if (badfile)
  349. return 0;
  350. else
  351. return 1;
  352. }
  353. /********************************************************/
  354. /* "Public" functions */
  355. /********************************************************/
  356. void fs_indexpath(char *path)
  357. {
  358.     if (isdirectory(path)) {
  359. if (verbose >= 2)
  360. printf("nChecking dir "%s"...n",
  361. path);
  362. indexadir(path);
  363.     }
  364.     else if (isfile(path)) {
  365. if (verbose >= 2)
  366. printf("nChecking file "%s"...n",
  367. path);
  368. indexafile(path);
  369.     }
  370. }
  371. int fs_vgetc(void *vp)
  372. {
  373. return fgetc((FILE *)vp);
  374. }
  375. int fs_vsize(void *vp)
  376. {
  377. struct stat stbuf;
  378. return fstat(fileno((FILE *)vp), &stbuf) ? -1 : stbuf.st_size;
  379. }
  380. int fs_parseconfline(char *line)
  381. {
  382.     int rv = 0;
  383.     
  384. if (grabCmdOptions(line, "IndexOnly", &suffixlist)) { rv = 1; }
  385. else if (lstrstr(line, "FileRules")) 
  386. {
  387. if (grabCmdOptions(line, "pathname contains", &pathconlist)) { rv = 1; }
  388. else if (grabCmdOptions(line, "directory contains", &dirconlist)) { rv = 1; }
  389. else if (grabCmdOptions(line, "filename contains", &fileconlist)) { rv = 1; }
  390. else if (grabCmdOptions(line, "title contains", &titconlist)) { rv = 1; }
  391. else if (grabCmdOptions(line, "filename is", &fileislist)) { rv = 1; }
  392. else if (grabCmdOptions(line, "pathname contains", &pathconlist)) { rv = 1; }
  393. }
  394.     
  395.     return rv;
  396. }
  397. struct _indexing_data_source_def FileSystemIndexingDataSource = {
  398.   "File-System",
  399.   "fs",
  400.   fs_indexpath,
  401.   fs_vgetc,
  402.   fs_vsize,
  403.   fs_parseconfline
  404. };