1 #include "asciidoc.h"
2 
3 #include <fstream>
4 #include <signal.h>
5 #include <stdlib.h>
6 #include <string.h>
7 
8 #include "Wt/WString.h"
9 
10 #ifndef WT_WIN32
11 #include <unistd.h>
12 #endif
13 
14 namespace {
15 
tempFileName()16 std::string tempFileName()
17 {
18 #ifndef WT_WIN32
19   char spool[20];
20   strcpy(spool, "/tmp/wtXXXXXX");
21 
22   int i = mkstemp(spool);
23   close(i);
24 #else
25   char spool[2 * L_tmpnam];
26   tmpnam(spool);
27 #endif
28   return std::string(spool);
29 }
30 
readFileToString(const std::string & fileName)31 std::string readFileToString(const std::string& fileName)
32 {
33   std::fstream file(fileName.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
34   int length = file.tellg();
35   file.seekg(0, std::ios::beg);
36 
37   std::unique_ptr<char[]> buf(new char[length]);
38   file.read(buf.get(), length);
39   file.close();
40 
41   return std::string(buf.get(), length);
42 }
43 
44 }
45 
asciidoc(const Wt::WString & src)46 Wt::WString asciidoc(const Wt::WString& src)
47 {
48   std::string srcFileName = tempFileName();
49   std::string htmlFileName = tempFileName();
50 
51   {
52     std::ofstream srcFile(srcFileName.c_str(), std::ios::out);
53     std::string ssrc = src.toUTF8();
54     srcFile.write(ssrc.c_str(), (std::streamsize)ssrc.length());
55     srcFile.close();
56   }
57 
58 #if defined(ASCIIDOC_EXECUTABLE)
59 #define xstr(s) str(s)
60 #define str(s) #s
61   std::string cmd = xstr(ASCIIDOC_EXECUTABLE);
62 #else
63   std::string cmd = "asciidoc";
64 #endif
65   std::string command = cmd + " -o " + htmlFileName + " -s " + srcFileName;
66 
67 #ifndef WT_WIN32
68   /*
69    * So, asciidoc apparently sends a SIGINT which is caught by its parent
70    * process.. So we have to temporarily ignore it.
71    */
72   struct sigaction newAction, oldAction;
73   newAction.sa_handler = SIG_IGN;
74   newAction.sa_flags = 0;
75   sigemptyset(&newAction.sa_mask);
76   sigaction(SIGINT, &newAction, &oldAction);
77 #endif
78   bool ok = system(command.c_str()) == 0;
79 #ifndef WT_WIN32
80   sigaction(SIGINT, &oldAction, 0);
81 #endif
82 
83   Wt::WString result;
84 
85   if (ok) {
86     result = Wt::WString(readFileToString(htmlFileName));
87   } else
88     result = Wt::WString("<i>Could not execute asciidoc</i>");
89 
90   unlink(srcFileName.c_str());
91   unlink(htmlFileName.c_str());
92 
93   return result;
94 }
95