main.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. /*
  2. * Copyright (c) 2009 Openmoko Inc.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <sys/types.h>
  20. #include <sys/stat.h>
  21. #include <dirent.h>
  22. #include <unistd.h>
  23. #include <getopt.h>
  24. #include <stdarg.h>
  25. #include <string.h>
  26. #include <time.h>
  27. #include <mysql/mysql.h>
  28. #include "wiki_render.h"
  29. char *framebuffer;
  30. unsigned char *article_buf_pointer;
  31. void fb_refresh(void) {}
  32. static void help(void)
  33. {
  34. printf("Usage: wiki-xml-parser [options] ...\n"
  35. " -h --help\t\t\tPrint this help message\n"
  36. " -f --file\t\t\tXML file name to process (default \"enwiki-latest-pages-articles.xml\")\n"
  37. " -p --pass\t\t\tPass 0, 1, 2, 3, 4 or 5 (default 0)\n"
  38. "\t\t\t0 - Print article content\n"
  39. "\t\t\t1 - Scan HTML files and log in database\n"
  40. "\t\t\t2 - Render articles and generate both single article files and dat files\n"
  41. "\t\t\t3 - Generate ouptput files\n"
  42. "\t\t\t4 - Count the rendered article files (generated in pass 3)\n"
  43. "\t\t\t5 - Generate pedia.hsh from pedia.pfx and fnd\n"
  44. " -n --new\t\t\tStart from scratch (for pass 1). If not specified, default to continue from the last processed.\n"
  45. " -b --batch\t\t\tBatch (for pass 3, 0~7, 0 - 1~249999, 1 - 250000~499999, 2 - 500000~999999, etc)\n"
  46. " -g --begin\t\t\tBeginning idx to process (for pass 3)\n"
  47. " -e --end\t\t\tEnding idx to process (for pass 3)\n"
  48. " -m --messages\t\t\tMessage level (default 0, for no messages)\n"
  49. " -u --user\t\t\tDatabase user id (default root)\n"
  50. " -w --password\t\t\tDatabase password (default NULL)\n"
  51. " -s --server\t\t\tDatabase server (default localhost)\n"
  52. " -d --database\t\t\tDatabase name (default wikixml)\n"
  53. " -i --idx\t\t\tIdx of the entry to retrieve (for pass 0, default 1)\n"
  54. " -l --title\t\t\tTitle to retrieve (for pass 0)\n"
  55. " -q --seq\t\t\tSeq of the entry to retrieve (for pass 0)\n"
  56. );
  57. }
  58. static struct option opts[] = {
  59. { "help", 0, 0, 'h' },
  60. { "file", 1, 0, 'f' },
  61. { "pass", 1, 0, 'p' },
  62. { "new", 0, 0, 'n' },
  63. { "batch", 0, 0, 'b' },
  64. { "begin", 1, 0, 'g' },
  65. { "end", 1, 0, 'e' },
  66. { "titles", 1, 0, 't' },
  67. { "messages", 1, 0, 'm' },
  68. { "user", 1, 0, 'u' },
  69. { "password", 1, 0, 'w' },
  70. { "server", 1, 0, 's' },
  71. { "database", 1, 0, 'd' },
  72. { "idx", 1, 0, 'i' },
  73. { "title", 1, 0, 'l' },
  74. { "seq", 1, 0, 'q' },
  75. { NULL, 0, NULL, 0 }
  76. };
  77. int nMsgLevel;
  78. int msgLevel()
  79. {
  80. return nMsgLevel;
  81. }
  82. void showMsg(int currentLevel, char *format, ...)
  83. {
  84. va_list ap;
  85. if (currentLevel > nMsgLevel)
  86. return;
  87. //printf("[%ld]", clock());
  88. va_start(ap, format);
  89. vprintf(format, ap);
  90. va_end(ap);
  91. }
  92. void init_bigram_table(MYSQL *conn)
  93. {
  94. char sSQL[MAX_SQL_STR];
  95. int rc;
  96. char c1, c2;
  97. mysql_query(conn, "delete from bigram");
  98. mysql_query(conn, "alter table bigram AUTO_INCREMENT=1");
  99. mysql_commit(conn);
  100. for (c1 = '0'; c1 <= '9'; c1++)
  101. {
  102. for (c2 = '0'; c2 <= '9'; c2++)
  103. {
  104. sprintf(sSQL, "insert bigram (bigram_chars, occurrences) values ('%c%c', 0)",
  105. c1, c2);
  106. rc = mysql_query(conn, sSQL);
  107. }
  108. for (c2 = 'A'; c2 <= 'Z'; c2++)
  109. {
  110. sprintf(sSQL, "insert bigram (bigram_chars, occurrences) values ('%c%c', 0)",
  111. c1, c2);
  112. rc = mysql_query(conn, sSQL);
  113. }
  114. for (c2 = 'a'; c2 <= 'z'; c2++)
  115. {
  116. sprintf(sSQL, "insert bigram (bigram_chars, occurrences) values ('%c%c', 0)",
  117. c1, c2);
  118. rc = mysql_query(conn, sSQL);
  119. }
  120. }
  121. for (c1 = 'A'; c1 <= 'Z'; c1++)
  122. {
  123. for (c2 = '0'; c2 <= '9'; c2++)
  124. {
  125. sprintf(sSQL, "insert bigram (bigram_chars, occurrences) values ('%c%c', 0)",
  126. c1, c2);
  127. rc = mysql_query(conn, sSQL);
  128. }
  129. for (c2 = 'A'; c2 <= 'Z'; c2++)
  130. {
  131. sprintf(sSQL, "insert bigram (bigram_chars, occurrences) values ('%c%c', 0)",
  132. c1, c2);
  133. rc = mysql_query(conn, sSQL);
  134. }
  135. for (c2 = 'a'; c2 <= 'z'; c2++)
  136. {
  137. sprintf(sSQL, "insert bigram (bigram_chars, occurrences) values ('%c%c', 0)",
  138. c1, c2);
  139. rc = mysql_query(conn, sSQL);
  140. }
  141. }
  142. for (c1 = 'a'; c1 <= 'z'; c1++)
  143. {
  144. for (c2 = '0'; c2 <= '9'; c2++)
  145. {
  146. sprintf(sSQL, "insert bigram (bigram_chars, occurrences) values ('%c%c', 0)",
  147. c1, c2);
  148. rc = mysql_query(conn, sSQL);
  149. }
  150. for (c2 = 'A'; c2 <= 'Z'; c2++)
  151. {
  152. sprintf(sSQL, "insert bigram (bigram_chars, occurrences) values ('%c%c', 0)",
  153. c1, c2);
  154. rc = mysql_query(conn, sSQL);
  155. }
  156. for (c2 = 'a'; c2 <= 'z'; c2++)
  157. {
  158. sprintf(sSQL, "insert bigram (bigram_chars, occurrences) values ('%c%c', 0)",
  159. c1, c2);
  160. rc = mysql_query(conn, sSQL);
  161. }
  162. }
  163. mysql_commit(conn);
  164. }
  165. #define MAX_IDX_RANGE 1000
  166. void add_idx_to_range(long idx, long *idx_range_count, long idx_range[MAX_IDX_RANGE][2])
  167. {
  168. int nMatch = -1;
  169. int i;
  170. for (i = 0; i < *idx_range_count && nMatch < 0; i++)
  171. {
  172. if (idx < idx_range[i][0])
  173. nMatch = i;
  174. }
  175. if (nMatch >= 0)
  176. {
  177. if (idx == idx_range[nMatch][0] - 1)
  178. idx_range[nMatch][0] = idx;
  179. else
  180. {
  181. if (*idx_range_count < MAX_IDX_RANGE)
  182. *idx_range_count = *idx_range_count + 1;
  183. memrcpy(&idx_range[nMatch + 1][0], &idx_range[nMatch][0], sizeof(long) * 2 * (*idx_range_count - nMatch - 1));
  184. idx_range[nMatch][0] = idx;
  185. idx_range[nMatch][1] = idx;
  186. }
  187. }
  188. else
  189. {
  190. if (*idx_range_count == 0)
  191. {
  192. idx_range[0][0] = idx;
  193. idx_range[0][1] = idx;
  194. *idx_range_count = *idx_range_count + 1;
  195. }
  196. else if (idx == idx_range[*idx_range_count - 1][1] + 1)
  197. {
  198. idx_range[*idx_range_count - 1][1] = idx;
  199. }
  200. else if (*idx_range_count < MAX_IDX_RANGE)
  201. {
  202. idx_range[*idx_range_count][0] = idx;
  203. idx_range[*idx_range_count][1] = idx;
  204. *idx_range_count = *idx_range_count + 1;
  205. }
  206. }
  207. }
  208. #define MAX_FILE_PER_FOLDER 100
  209. void add_file_name(long name, char type, long file_names[MAX_FILE_PER_FOLDER], char file_types[MAX_FILE_PER_FOLDER], int *file_count)
  210. {
  211. int i;
  212. int nMatch = -1;
  213. for (i = 0; i < *file_count && nMatch < 0; i++)
  214. if (name < file_names[i])
  215. nMatch = i;
  216. if (nMatch >= 0)
  217. {
  218. if (*file_count < MAX_FILE_PER_FOLDER)
  219. *file_count = *file_count + 1;
  220. memrcpy(&file_names[nMatch + 1], &file_names[nMatch], sizeof(long) * (*file_count - nMatch - 1));
  221. memrcpy(&file_types[nMatch + 1], &file_types[nMatch], sizeof(char) * (*file_count - nMatch - 1));
  222. file_names[nMatch] = name;
  223. file_types[nMatch] = type;
  224. }
  225. else
  226. {
  227. if (*file_count < MAX_FILE_PER_FOLDER)
  228. {
  229. file_names[*file_count] = name;
  230. file_types[*file_count] = type;
  231. *file_count = *file_count + 1;
  232. }
  233. }
  234. }
  235. void count_files(char *dir, long *idx_range_count, long idx_range[MAX_IDX_RANGE][2], long *max_file_size)
  236. {
  237. struct dirent *de = NULL;
  238. DIR *d = NULL;
  239. char path[256];
  240. long file_names[MAX_FILE_PER_FOLDER];
  241. char file_types[MAX_FILE_PER_FOLDER];
  242. int file_count = 0;
  243. int i;
  244. struct stat file_stat;
  245. d = opendir(dir);
  246. if(d == NULL)
  247. return;
  248. // Loop while not NULL
  249. while ((de = readdir(d)) != NULL)
  250. {
  251. if (de->d_name[0] != '.')
  252. {
  253. add_file_name(atol(de->d_name), de->d_type, file_names, file_types, &file_count);
  254. }
  255. }
  256. for (i = 0; i < file_count; i++)
  257. {
  258. if (file_types[i] == DT_DIR)
  259. {
  260. sprintf(path, "%s/%ld", dir, file_names[i]);
  261. count_files(path, idx_range_count, idx_range, max_file_size);
  262. }
  263. else if (file_types[i] == DT_REG)
  264. {
  265. add_idx_to_range(file_names[i], idx_range_count, idx_range);
  266. sprintf(path, "%s/%ld", dir, file_names[i]);
  267. stat(path, &file_stat);
  268. if (file_stat.st_size > *max_file_size)
  269. *max_file_size = file_stat.st_size;
  270. }
  271. }
  272. closedir(d);
  273. }
  274. MYSQL *g_conn;
  275. int main(int argc, char **argv)
  276. {
  277. int pass = 0;
  278. int bNew = 0;
  279. long batch = -1;
  280. long idxStart = 0;
  281. long idxEnd = 0;
  282. long idx = 1;
  283. long seq = 0;
  284. long titlesToProcess = 0;
  285. char sFileName[1024];
  286. char sServer[256];
  287. char sDB[256];
  288. char sId[256];
  289. char sPassword[256];
  290. char sTitle[256];
  291. off64_t file_offset_for_pass_1;
  292. long max_article_idx;
  293. MYSQL *conn;
  294. MYSQL *conn2;
  295. MYSQL_RES *res;
  296. MYSQL_ROW row;
  297. char sSQL[MAX_SQL_STR];
  298. int rc;
  299. char c;
  300. time_t t;
  301. nMsgLevel = 0;
  302. printf("wiki-xml-parser - (C) 2009 by Openmoko Inc.\n"
  303. "This program is Free Software and has ABSOLUTELY NO WARRANTY\n\n");
  304. if (argc <2)
  305. {
  306. help();
  307. exit(2);
  308. }
  309. sFileName[0] = '\0';
  310. sServer[0] = '\0';
  311. sDB[0] = '\0';
  312. sId[0] = '\0';
  313. sPassword[0] = '\0';
  314. sTitle[0] = '\0';
  315. while (1) {
  316. int c, option_index = 0;
  317. c = getopt_long(argc, argv, "hf:p:nb:g:e:m:t:u:w:s:d:i:l:q:", opts,
  318. &option_index);
  319. if (c == -1)
  320. break;
  321. switch (c) {
  322. case 'h':
  323. help();
  324. exit(0);
  325. break;
  326. case 'f':
  327. strncpy(sFileName, optarg, sizeof(sFileName) - 1);
  328. sFileName[sizeof(sFileName) - 1] = '\0';
  329. break;
  330. case 'p':
  331. pass = atoi(optarg);
  332. break;
  333. case 'b':
  334. batch = atoi(optarg);
  335. break;
  336. case 'g':
  337. idxStart = atol(optarg);
  338. break;
  339. case 'e':
  340. idxEnd = atol(optarg);
  341. break;
  342. case 'n':
  343. bNew = 1;
  344. break;
  345. case 'm':
  346. nMsgLevel = atoi(optarg);
  347. break;
  348. case 't':
  349. titlesToProcess = atol(optarg);
  350. break;
  351. case 'u':
  352. strncpy(sId, optarg, sizeof(sId) - 1);
  353. sId[sizeof(sId) - 1] = '\0';
  354. break;
  355. case 'w':
  356. strncpy(sPassword, optarg, sizeof(sPassword) - 1);
  357. sPassword[sizeof(sPassword) - 1] = '\0';
  358. break;
  359. case 's':
  360. strncpy(sServer, optarg, sizeof(sServer) - 1);
  361. sServer[sizeof(sServer) - 1] = '\0';
  362. break;
  363. case 'd':
  364. strncpy(sDB, optarg, sizeof(sDB) - 1);
  365. sDB[sizeof(sDB) - 1] = '\0';
  366. break;
  367. case 'i':
  368. idx = atol(optarg);
  369. break;
  370. case 'q':
  371. seq = atol(optarg);
  372. break;
  373. case 'l':
  374. strncpy(sTitle, optarg, sizeof(sTitle) - 1);
  375. sServer[sizeof(sTitle) - 1] = '\0';
  376. break;
  377. default:
  378. help();
  379. exit(2);
  380. }
  381. }
  382. if (pass == 5)
  383. {
  384. generate_pedia_hsh();
  385. exit(0);
  386. }
  387. if (pass == 6)
  388. {
  389. reorg_pedia();
  390. exit(0);
  391. }
  392. if (!titlesToProcess)
  393. titlesToProcess = 1024;
  394. if (!sFileName[0])
  395. strcpy(sFileName, "enwiki-latest-pages-articles.xml");
  396. if (!sId[0])
  397. strcpy(sId, "root");
  398. if (!sServer[0])
  399. strcpy(sServer, "localhost");
  400. if (!sDB[0])
  401. strcpy(sDB, "wikixml");
  402. if (batch >= 0)
  403. {
  404. idxStart = MAX_ARTICLES_PER_DAT * batch;
  405. idxEnd = idxStart + MAX_ARTICLES_PER_DAT - 1;
  406. if (!idxStart)
  407. idxStart = 1;
  408. }
  409. else if (idxEnd < idxStart)
  410. idxEnd = idxStart;
  411. my_init();
  412. g_conn = mysql_init(NULL);
  413. if (!mysql_real_connect(g_conn, sServer, sId, sPassword, sDB, 0, NULL, 0))
  414. {
  415. showMsg(0, "Error connecting DB %s/%s using %s/%s\n", sServer, sDB, sId, sPassword);
  416. exit(1);
  417. }
  418. conn = mysql_init(NULL);
  419. if (!mysql_real_connect(conn, sServer, sId, sPassword, sDB, 0, NULL, 0))
  420. {
  421. showMsg(0, "Error connecting DB %s/%s using %s/%s\n", sServer, sDB, sId, sPassword);
  422. exit(1);
  423. }
  424. if (pass==0)
  425. {
  426. if (sTitle[0])
  427. sprintf(sSQL, "select title, text_start_offset, text_len, redirect_title, entry_type from entries where title='%s'", sTitle);
  428. else if (seq)
  429. sprintf(sSQL, "select title, text_start_offset, text_len, redirect_title, entry_type from entries where seq=%ld", seq);
  430. else
  431. sprintf(sSQL, "select title, text_start_offset, text_len, redirect_title, entry_type from entries where idx=%ld", idx);
  432. printf("SQL: %s\n", sSQL);
  433. rc = mysql_query(conn, sSQL);
  434. if (rc)
  435. {
  436. showMsg(0, "query entries error - %d (%s)\n", rc, mysql_error(conn));
  437. exit(1);
  438. }
  439. res = mysql_use_result(conn);
  440. if ((row = mysql_fetch_row(res)) != NULL)
  441. {
  442. FILE *fd;
  443. off64_t nArticleOffset;
  444. long nTextLen;
  445. char buf[1025];
  446. int len;
  447. if (!row[1])
  448. {
  449. if (row[4])
  450. printf("title: [%s], redirect: [%s]\n", row[0], row[3]);
  451. else
  452. printf("title: [%s], entry type: %s\n", row[0], row[4]);
  453. exit(0);
  454. }
  455. sscanf(row[1], "%Ld", &nArticleOffset);
  456. nTextLen = atol(row[2]);
  457. printf("offset: %Lx, len: %lx\n\n", nArticleOffset, nTextLen);
  458. fd = fopen64(sFileName, "rb");
  459. fseeko64(fd, nArticleOffset, SEEK_SET);
  460. printf("<mediawiki>\n<page>\n<title>%s</title>\n <revision>\n<text>", row[0]);
  461. while (nTextLen > 0)
  462. {
  463. if (nTextLen > 1024)
  464. len = fread(buf, 1, 1024, fd);
  465. else
  466. len = fread(buf, 1, nTextLen, fd);
  467. nTextLen -= 1024;
  468. buf[len] = '\0';
  469. printf(buf);
  470. }
  471. printf("\n</text>\n</revision>\n</page>\n</mediawiki>");
  472. }
  473. else
  474. printf("not found\n");
  475. exit(0);
  476. }
  477. else if (pass == 4)
  478. {
  479. long idx_range[MAX_IDX_RANGE][2];
  480. long idx_range_count = 0;
  481. long count = 0;
  482. int i;
  483. long max_file_size = 0;
  484. count_files("./dat", &idx_range_count, idx_range, &max_file_size);
  485. for (i = 0; i < idx_range_count; i++)
  486. {
  487. showMsg(0, "%8ld ~ %8ld\n", idx_range[i][0], idx_range[i][1]);
  488. count += idx_range[i][1] - idx_range[i][0] + 1;
  489. }
  490. showMsg(0, "Total file count: %ld, Max file size: %ld\n", count, max_file_size);
  491. exit(0);
  492. }
  493. rc = mysql_query(conn, "select idx from entries order by idx desc limit 1");
  494. res = mysql_use_result(conn);
  495. if ((row = mysql_fetch_row(res)) != NULL && row[0])
  496. {
  497. showMsg(0, "max article idx:\t\t%ld\n", (max_article_idx=atol(row[0])));
  498. mysql_free_result(res);
  499. mysql_commit(conn);
  500. rc = mysql_query(conn, "select count(*) from entries");
  501. res = mysql_use_result(conn);
  502. if ((row = mysql_fetch_row(res)) != NULL && row[0])
  503. showMsg(0, "pass1 processed entries:\t%ld\n", atol(row[0]));
  504. // mysql_free_result(res);
  505. // mysql_commit(conn);
  506. // rc = mysql_query(conn, "select count(*) from entries where entry_type=0 and pass_2_processed=1");
  507. // res = mysql_use_result(conn);
  508. // if ((row = mysql_fetch_row(res)) != NULL && row[0])
  509. // showMsg(0, "pass2 processed articles:\t%ld\n", atol(row[0]));
  510. // mysql_free_result(res);
  511. // mysql_commit(conn);
  512. // rc = mysql_query(conn, "select count(*) from entries where entry_type=0 and pass_2_processed=0");
  513. // res = mysql_use_result(conn);
  514. // if ((row = mysql_fetch_row(res)) != NULL && row[0])
  515. // showMsg(0, "pass2 to be processed articles:\t%ld\n", atol(row[0]));
  516. }
  517. else
  518. {
  519. showMsg(0, "no process status\n");
  520. file_offset_for_pass_1 = 0;
  521. max_article_idx = 0;
  522. init_bigram_table(conn);
  523. }
  524. mysql_free_result(res);
  525. if (pass == 1)
  526. {
  527. // if (nBatch <= 0)
  528. // nBatch = 8;
  529. // else if (nBatch > MAX_DAT_FILES)
  530. // nBatch = MAX_DAT_FILES;
  531. showMsg(0, "\nProcessing %s for %ld titles.\n", sFileName, titlesToProcess);
  532. }
  533. else if (pass == 2)
  534. showMsg(0, "\nProcessing idx %ld ~ %ld.\n", idxStart, idxEnd);
  535. showMsg(3, "Server-%s, DB-%s, user-%s, password-%s.\n\n", sServer, sDB, sId, sPassword);
  536. if (bNew && pass == 1)
  537. printf("\nAll previously processed records will be deleted. Continue processing? (y to continue)\n");
  538. else
  539. printf("\nStart processing? (y to continue)\n");
  540. c = getchar();
  541. if (c == 'y')
  542. {
  543. if (bNew)
  544. {
  545. if (pass == 1)
  546. {
  547. mysql_query(conn, "delete from entries");
  548. rc = mysql_commit(conn);
  549. mysql_query(conn, "alter table entries AUTO_INCREMENT=1");
  550. rc = mysql_commit(conn);
  551. showMsg(3, "commit update process_status rc=%d\n", rc);
  552. file_offset_for_pass_1 = 0;
  553. max_article_idx = 0;
  554. init_bigram_table(conn);
  555. }
  556. }
  557. time(&t);
  558. showMsg(0, "start pass %d - %s\n", pass, ctime(&t));
  559. if (pass == 1)
  560. {
  561. process_pass_1(conn, sFileName, nMsgLevel, titlesToProcess,
  562. file_offset_for_pass_1, max_article_idx);
  563. }
  564. else if (pass == 2)
  565. {
  566. conn2 = mysql_init(NULL);
  567. if (!mysql_real_connect(conn2, sServer, sId, sPassword, sDB, 0, NULL, 0))
  568. {
  569. showMsg(0, "Error connecting DB %s/%s using %s/%s\n", sServer, sDB, sId, sPassword);
  570. exit(1);
  571. }
  572. process_pass_2(conn, conn2, sFileName, nMsgLevel, titlesToProcess, batch, idxStart, idxEnd);
  573. mysql_close(conn2);
  574. }
  575. else if (pass == 3)
  576. {
  577. conn2 = mysql_init(NULL);
  578. if (!mysql_real_connect(conn2, sServer, sId, sPassword, sDB, 0, NULL, 0))
  579. {
  580. showMsg(0, "Error connecting DB %s/%s using %s/%s\n", sServer, sDB, sId, sPassword);
  581. exit(1);
  582. }
  583. unlink("pedia.idx");
  584. unlink("pedia.fnd");
  585. unlink("pedia.pfx");
  586. if (max_article_idx > 2000)
  587. process_pass_3(conn, conn2, 1);
  588. else
  589. process_pass_3(conn, conn2, 0);
  590. mysql_close(conn2);
  591. }
  592. time(&t);
  593. showMsg(0, "end pass %d - %s\n", pass, ctime(&t));
  594. }
  595. /* close connection */
  596. mysql_close(conn);
  597. mysql_close(g_conn);
  598. exit(0);
  599. }
  600. int retrieve_article(long idx_article)
  601. {
  602. // dummy function for linking lcd_buf_draw.c
  603. return 0;
  604. }