1 /* @(#) $Id: ./src/os_xml/os_xml_writer.c, 2011/09/08 dcid Exp $
4 /* Copyright (C) 2009 Trend Micro Inc.
7 * This program is a free software; you can redistribute it
8 * and/or modify it under the terms of the GNU General Public
9 * License (version 2) as published by the FSF - Free Software
14 * Available at http://www.ossec.net/
21 #include "os_xml_internal.h"
23 /* Internal functions */
24 static int _oswcomment(FILE *fp_in, FILE *fp_out) __attribute__((nonnull));
25 static int _WReadElem(FILE *fp_in, FILE *fp_out, unsigned int position, unsigned int parent,
26 const char **node, const char *value, unsigned int node_pos) __attribute__((nonnull));
27 static int _xml_wfgetc(FILE *fp_in, FILE *fp_out) __attribute__((nonnull));
30 static int _xml_wfgetc(FILE *fp_in, FILE *fp_out)
34 /* Putting on fp_out, whatever we read */
45 * Write an XML file, based on the input and values to change.
47 int OS_WriteXML(const char *infile, const char *outfile, const char **nodes,
48 const char *oldval, const char *newval)
56 fp_in = fopen(infile,"r");
63 /* Opening out file */
64 fp_out = fopen(outfile,"w");
72 if((r = _WReadElem(fp_in, fp_out, 0, 0,
73 nodes, newval, 0)) < 0) /* First position */
80 /* We didn't find an entry, add at the end. */
86 fseek(fp_out, 0, SEEK_END);
87 fprintf(fp_out, "\n");
89 /* Printing each node. */
92 fprintf(fp_out, "%*c<%s>", rwidth, ' ', nodes[s]);
97 fprintf(fp_out, "\n");
103 fprintf(fp_out, "%s</%s>\n", newval, nodes[s]);
107 /* Closing each node. */
110 fprintf(fp_out, "%*c</%s>\n", rwidth, ' ', nodes[s]);
123 /* Getting comments */
124 static int _oswcomment(FILE *fp_in, FILE *fp_out)
127 if((c = fgetc(fp_in)) == _R_COM)
130 while((c = _xml_wfgetc(fp_in, fp_out)) != EOF)
134 if((c=fgetc(fp_in)) == _R_CONFE)
141 else if(c == '-') /* W3C way of finish comments */
143 if((c = fgetc(fp_in)) == '-')
146 if((c = fgetc(fp_in)) == _R_CONFE)
175 static int _WReadElem(FILE *fp_in, FILE *fp_out,
176 unsigned int position, unsigned int parent, const char **nodes, const char *val, unsigned int node_pos)
180 unsigned int count = 0;
181 short int location = -1;
183 char elem[XML_MAXSIZE +1];
184 char cont[XML_MAXSIZE +1];
185 char closedelem[XML_MAXSIZE +1];
187 memset(elem,'\0',XML_MAXSIZE +1);
188 memset(cont,'\0',XML_MAXSIZE +1);
189 memset(closedelem,'\0',XML_MAXSIZE +1);
192 while((c = _xml_wfgetc(fp_in, fp_out)) != EOF)
195 if(count >= XML_MAXSIZE)
200 /* Checking for comments */
204 if((r = _oswcomment(fp_in, fp_out)) < 0)
218 /* Must be the opening element */
221 if((c = fgetc(fp_in)) == '/')
238 /* Looking for the closure */
239 else if((location == 0) && ((c == _R_CONFE) || (c == ' ')))
245 /* Removing the / at the end of the element name */
246 if(count > 0 && elem[count -1] == '/')
249 elem[count -1] = '\0';
253 /* If we may have more attributes */
256 /* Writing the attributes */
257 while((c = _xml_wfgetc(fp_in, fp_out)) != EOF)
267 /* If the element is closed already (finished in />) */
273 memset(elem,'\0',XML_MAXSIZE);
274 memset(closedelem,'\0',XML_MAXSIZE);
275 memset(cont,'\0',XML_MAXSIZE);
282 /* Location == means we are getting the content */
290 /* Checking position of the node */
291 if(node_pos > position)
296 /* Checking if the element name matches */
297 if(node_pos == position &&
298 nodes[node_pos] && strcmp(elem, nodes[node_pos]) == 0)
302 /* Latest node, printint value */
306 fprintf(fp_out, "%s", val);
308 while((c = fgetc(fp_in)) != EOF)
320 else if((location == 2) &&(c == _R_CONFE))
322 closedelem[count]='\0';
323 if(strcmp(closedelem,elem) != 0)
328 memset(elem,'\0',XML_MAXSIZE);
329 memset(closedelem,'\0',XML_MAXSIZE);
330 memset(cont,'\0',XML_MAXSIZE);
340 /* If we are reading the element */
341 else if((location == 1) &&(c == _R_CONFS))
343 if((c=fgetc(fp_in)) == '/')
355 ungetc(_R_CONFS,fp_in);
356 fseek(fp_out, -1, SEEK_CUR);
358 if((wret_code = _WReadElem(fp_in, fp_out, position+1, parent+1,
359 nodes, val, node_pos))< 0)
364 /* Setting final return code. */
377 elem[count++] = (char) c;
379 else if(location == 1)
381 cont[count++] = (char) c;
383 else if(location == 2)
385 closedelem[count++] = (char) c;