2 * Copyright (C) 2003 Timothy Bauscher <timothy@linuxfromscratch.org>
17 int lfscmd (int argc
, char **argv
) {
31 while ((c
= getopt (argc
, argv
, "fxteq:")) != -1)
54 /* Get xml file path */
55 lfs
.xmlfile
= argv
[optind
];
57 /* Validate arguments */
58 if (NULL
== lfs
.xmlfile
59 && NULL
== (lfs
.xmlfile
=locate_book("LFSCMD_BOOK")))
62 /* Setup the xml parser */
63 xmlSubstituteEntitiesDefault(1);
64 doc
= xmlParseFile(lfs
.xmlfile
);
65 node
= xmlDocGetRootElement(doc
);
67 /* Check that the document is well-formed */
68 if (NULL
== doc
) error("Document not well-formed");
69 /* Check for an empty root element */
70 if (NULL
== node
) error("Empty root element");
72 return(lfscmd_parsexml(doc
, node
->children
));
75 int lfscmd_parsexml (xmlDocPtr doc
, xmlNodePtr node
) {
78 /* Compile regex query */
79 if (NULL
!= lfs
.query
) {
80 if (regcomp(®
, lfs
.query
, REG_NOSUB
))
81 error("Regex is ill-formed: %s", lfs
.query
);
86 /* Record page title */
87 if (string_comp("title", node
->name
)) {
88 lfs
.sect
= xmlNodeListGetString(doc
, node
->children
, 1);
91 /* Determine filename by section id */
92 else if (string_comp("part", node
->name
)
93 || (string_len(node
->name
) >= 4
94 && string_comp("sect", string_snip(node
->name
, 0, 4)))) {
96 if (NULL
!= xmlGetProp(node
, "id"))
97 lfs
.fname
= xmlGetProp(node
, "id");
99 /* Display screen commands */
100 else if (string_comp("screen", node
->name
)
101 && string_comp("userinput", node
->children
->name
)) {
103 /* Match title or section with query */
104 if (NULL
!= lfs
.query
) {
105 if (!regexec(®
, lfs
.sect
, 0, NULL
, 0)
106 || !regexec(®
, lfs
.fname
, 0, NULL
, 0))
107 lfscmd_parse_screen(doc
, node
->children
);
109 else lfscmd_parse_screen(doc
, node
->children
);
112 /* Recursively traverse the tree */
113 if (NULL
!= node
->children
)
114 lfscmd_parsexml(doc
, node
->children
);
121 int lfscmd_parse_screen (xmlDocPtr doc
, xmlNodePtr node
) {
122 FILE *output
= stdout
;
124 if (NULL
== lfs
.fname
) lfs
.fname
= "unknown";
125 if (NULL
== lfs
.sect
) lfs
.sect
= "unknown";
127 /* Append output to file */
128 if (1 == lfs
.file
) output
=write_file(lfs
.fname
, "a");
130 /* Output new page title */
131 if (1 == lfs
.status
&& 1 == lfs
.title
) {
132 fprintf(output
, "\n\n### %s: %s ###\n", lfs
.fname
, lfs
.sect
);
136 /* Output screen commands and content */
139 /* Output content outside of "userinput" */
140 if (string_comp("text", node
->name
)) {
141 if (NULL
!= (lfs
.cmd
= node
->content
)) {
142 if (1 == lfs
.execute
) system(lfs
.cmd
);
143 else fprintf(output
, "%s", lfs
.cmd
);
147 /* Output commands */
148 else if (string_comp("userinput", node
->name
))
150 /* Strip double ampersands */
151 if (NULL
!= (lfs
.cmd
= xmlNodeListGetString(doc
, node
->children
, 1))) {
153 if (1 == lfs
.execute
)
154 system(string_strip(lfs
.cmd
, "&&"));
156 fprintf(output
, "%s", string_strip(lfs
.cmd
, "&&"));
159 /* Properly deal with BLFS commands of the form <screen><userinput><command> */
160 if (string_comp("command", node
->children
->name
))
162 xmlNodePtr command_node
= node
->children
;
164 while (NULL
!= command_node
)
166 if (NULL
!= (lfs
.cmd
= xmlNodeListGetString(doc
, command_node
->children
, 1)))
168 if (1 == lfs
.execute
)
170 system(string_strip(lfs
.cmd
, "&&"));
174 fprintf(output
, "%s", string_strip(lfs
.cmd
, "&&"));
177 command_node
= command_node
->next
;
186 /* Output trailing space */
187 fprintf(output
, "\n");
193 /* Make file executable */
194 if (1 == lfs
.exe
) chmod(lfs
.fname
, 00755);