main_u.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*
  2. * main_u.c
  3. *
  4. * Released under GPL
  5. *
  6. * Copyright (C) 1998-2004 A.J. van Os
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. *
  22. * Description:
  23. * The main program of 'antiword' (Unix version)
  24. */
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #if defined(__dos)
  28. #include <fcntl.h>
  29. #include <io.h>
  30. #endif /* __dos */
  31. #if defined(__CYGWIN__) || defined(__CYGMING__)
  32. # ifdef X_LOCALE
  33. # include <X11/Xlocale.h>
  34. # else
  35. # include <locale.h>
  36. # endif
  37. #else
  38. #include <locale.h>
  39. #endif /* __CYGWIN__ || __CYGMING__ */
  40. #if defined(N_PLAT_NLM)
  41. #if !defined(_VA_LIST)
  42. #include "NW-only/nw_os.h"
  43. #endif /* !_VA_LIST */
  44. #include "getopt.h"
  45. #endif /* N_PLAT_NLM */
  46. #include "version.h"
  47. #include "antiword.h"
  48. /* The name of this program */
  49. static const char *szTask = NULL;
  50. static void
  51. vUsage(void)
  52. {
  53. fprintf(stderr, "\tName: %s\n", szTask);
  54. fprintf(stderr, "\tPurpose: "PURPOSESTRING"\n");
  55. fprintf(stderr, "\tAuthor: "AUTHORSTRING"\n");
  56. fprintf(stderr, "\tVersion: "VERSIONSTRING);
  57. #if defined(__dos)
  58. fprintf(stderr, VERSIONSTRING2);
  59. #endif /* __dos */
  60. fprintf(stderr, "\n");
  61. fprintf(stderr, "\tStatus: "STATUSSTRING"\n");
  62. fprintf(stderr,
  63. "\tUsage: %s [switches] wordfile1 [wordfile2 ...]\n", szTask);
  64. fprintf(stderr,
  65. "\tSwitches: [-f|-t|-a papersize|-p papersize|-x dtd]"
  66. "[-m mapping][-w #][-i #][-Ls]\n");
  67. fprintf(stderr, "\t\t-f formatted text output\n");
  68. fprintf(stderr, "\t\t-t text output (default)\n");
  69. fprintf(stderr, "\t\t-a <paper size name> Adobe PDF output\n");
  70. fprintf(stderr, "\t\t-p <paper size name> PostScript output\n");
  71. fprintf(stderr, "\t\t paper size like: a4, letter or legal\n");
  72. fprintf(stderr, "\t\t-x <dtd> XML output\n");
  73. fprintf(stderr, "\t\t like: db (DocBook)\n");
  74. fprintf(stderr, "\t\t-m <mapping> character mapping file\n");
  75. fprintf(stderr, "\t\t-w <width> in characters of text output\n");
  76. fprintf(stderr, "\t\t-i <level> image level (PostScript only)\n");
  77. fprintf(stderr, "\t\t-L use landscape mode (PostScript only)\n");
  78. fprintf(stderr, "\t\t-r Show removed text\n");
  79. fprintf(stderr, "\t\t-s Show hidden (by Word) text\n");
  80. } /* end of vUsage */
  81. /*
  82. * pStdin2TmpFile - save stdin in a temporary file
  83. *
  84. * returns: the pointer to the temporary file or NULL
  85. */
  86. static FILE *
  87. pStdin2TmpFile(long *lFilesize)
  88. {
  89. FILE *pTmpFile;
  90. size_t tSize;
  91. BOOL bFailure;
  92. UCHAR aucBytes[BUFSIZ];
  93. DBG_MSG("pStdin2TmpFile");
  94. fail(lFilesize == NULL);
  95. /* Open the temporary file */
  96. pTmpFile = tmpfile();
  97. if (pTmpFile == NULL) {
  98. return NULL;
  99. }
  100. #if defined(__dos)
  101. /* Stdin must be read as a binary stream */
  102. setmode(fileno(stdin), O_BINARY);
  103. #endif /* __dos */
  104. /* Copy stdin to the temporary file */
  105. *lFilesize = 0;
  106. bFailure = TRUE;
  107. for (;;) {
  108. tSize = fread(aucBytes, 1, sizeof(aucBytes), stdin);
  109. if (tSize == 0) {
  110. bFailure = feof(stdin) == 0;
  111. break;
  112. }
  113. if (fwrite(aucBytes, 1, tSize, pTmpFile) != tSize) {
  114. bFailure = TRUE;
  115. break;
  116. }
  117. *lFilesize += (long)tSize;
  118. }
  119. #if defined(__dos)
  120. /* Switch stdin back to a text stream */
  121. setmode(fileno(stdin), O_TEXT);
  122. #endif /* __dos */
  123. /* Deal with the result of the copy action */
  124. if (bFailure) {
  125. *lFilesize = 0;
  126. (void)fclose(pTmpFile);
  127. return NULL;
  128. }
  129. rewind(pTmpFile);
  130. return pTmpFile;
  131. } /* end of pStdin2TmpFile */
  132. /*
  133. * bProcessFile - process a single file
  134. *
  135. * returns: TRUE when the given file is a supported Word file, otherwise FALSE
  136. */
  137. static BOOL
  138. bProcessFile(const char *szFilename)
  139. {
  140. FILE *pFile;
  141. diagram_type *pDiag;
  142. long lFilesize;
  143. int iWordVersion;
  144. BOOL bResult;
  145. fail(szFilename == NULL || szFilename[0] == '\0');
  146. DBG_MSG(szFilename);
  147. if (szFilename[0] == '-' && szFilename[1] == '\0') {
  148. pFile = pStdin2TmpFile(&lFilesize);
  149. if (pFile == NULL) {
  150. werr(0, "I can't save the standard input to a file");
  151. return FALSE;
  152. }
  153. } else {
  154. pFile = fopen(szFilename, "rb");
  155. if (pFile == NULL) {
  156. werr(0, "I can't open '%s' for reading", szFilename);
  157. return FALSE;
  158. }
  159. lFilesize = lGetFilesize(szFilename);
  160. if (lFilesize < 0) {
  161. (void)fclose(pFile);
  162. werr(0, "I can't get the size of '%s'", szFilename);
  163. return FALSE;
  164. }
  165. }
  166. iWordVersion = iGuessVersionNumber(pFile, lFilesize);
  167. if (iWordVersion < 0 || iWordVersion == 3) {
  168. if (bIsRtfFile(pFile)) {
  169. werr(0, "%s is not a Word Document."
  170. " It is probably a Rich Text Format file",
  171. szFilename);
  172. } if (bIsWordPerfectFile(pFile)) {
  173. werr(0, "%s is not a Word Document."
  174. " It is probably a Word Perfect file",
  175. szFilename);
  176. } else {
  177. #if defined(__dos)
  178. werr(0, "%s is not a Word Document or the filename"
  179. " is not in the 8+3 format.", szFilename);
  180. #else
  181. werr(0, "%s is not a Word Document.", szFilename);
  182. #endif /* __dos */
  183. }
  184. (void)fclose(pFile);
  185. return FALSE;
  186. }
  187. /* Reset any reading done during file testing */
  188. rewind(pFile);
  189. pDiag = pCreateDiagram(szTask, szFilename);
  190. if (pDiag == NULL) {
  191. (void)fclose(pFile);
  192. return FALSE;
  193. }
  194. bResult = bWordDecryptor(pFile, lFilesize, pDiag);
  195. vDestroyDiagram(pDiag);
  196. (void)fclose(pFile);
  197. return bResult;
  198. } /* end of bProcessFile */
  199. int
  200. main(int argc, char **argv)
  201. {
  202. options_type tOptions;
  203. const char *szWordfile;
  204. int iFirst, iIndex, iGoodCount;
  205. BOOL bUsage, bMultiple, bUseTXT, bUseXML;
  206. if (argc <= 0) {
  207. return EXIT_FAILURE;
  208. }
  209. szTask = szBasename(argv[0]);
  210. if (argc <= 1) {
  211. iFirst = 1;
  212. bUsage = TRUE;
  213. } else {
  214. iFirst = iReadOptions(argc, argv);
  215. bUsage = iFirst <= 0;
  216. }
  217. if (bUsage) {
  218. vUsage();
  219. return iFirst < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
  220. }
  221. #if defined(N_PLAT_NLM) && !defined(_VA_LIST)
  222. nwinit();
  223. #endif /* N_PLAT_NLM && !_VA_LIST */
  224. vGetOptions(&tOptions);
  225. #if !defined(__dos)
  226. if (is_locale_utf8()) {
  227. #if defined(__STDC_ISO_10646__)
  228. /*
  229. * If the user wants UTF-8 and the envirionment variables
  230. * support UTF-8, than set the locale accordingly
  231. */
  232. if (tOptions.eEncoding == encoding_utf_8) {
  233. if (setlocale(LC_CTYPE, "") == NULL) {
  234. werr(1, "Can't set the UTF-8 locale! "
  235. "Check LANG, LC_CTYPE, LC_ALL.");
  236. }
  237. DBG_MSG("The UTF-8 locale has been set");
  238. } else {
  239. (void)setlocale(LC_CTYPE, "C");
  240. }
  241. #endif /* __STDC_ISO_10646__ */
  242. } else {
  243. if (setlocale(LC_CTYPE, "") == NULL) {
  244. werr(0, "Can't set the locale! Will use defaults");
  245. (void)setlocale(LC_CTYPE, "C");
  246. }
  247. DBG_MSG("The locale has been set");
  248. }
  249. #endif /* !__dos */
  250. bMultiple = argc - iFirst > 1;
  251. bUseTXT = tOptions.eConversionType == conversion_text ||
  252. tOptions.eConversionType == conversion_fmt_text;
  253. bUseXML = tOptions.eConversionType == conversion_xml;
  254. iGoodCount = 0;
  255. #if defined(__dos)
  256. if (tOptions.eConversionType == conversion_pdf) {
  257. /* PDF must be written as a binary stream */
  258. setmode(fileno(stdout), O_BINARY);
  259. }
  260. #endif /* __dos */
  261. if (bUseXML) {
  262. fprintf(stdout,
  263. "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
  264. "<!DOCTYPE %s PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2//EN\"\n"
  265. "\t\"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\">\n",
  266. bMultiple ? "set" : "book");
  267. if (bMultiple) {
  268. fprintf(stdout, "<set>\n");
  269. }
  270. }
  271. for (iIndex = iFirst; iIndex < argc; iIndex++) {
  272. if (bMultiple && bUseTXT) {
  273. szWordfile = szBasename(argv[iIndex]);
  274. fprintf(stdout, "::::::::::::::\n");
  275. fprintf(stdout, "%s\n", szWordfile);
  276. fprintf(stdout, "::::::::::::::\n");
  277. }
  278. if (bProcessFile(argv[iIndex])) {
  279. iGoodCount++;
  280. }
  281. }
  282. if (bMultiple && bUseXML) {
  283. fprintf(stdout, "</set>\n");
  284. }
  285. DBG_DEC(iGoodCount);
  286. return iGoodCount <= 0 ? EXIT_FAILURE : EXIT_SUCCESS;
  287. } /* end of main */