1 /* @(#) $Id: os_xml_writer.c,v 1.5 2009/06/24 17:06:32 dcid Exp $ */
3 /* Copyright (C) 2009 Trend Micro Inc.
6 * This program is a free software; you can redistribute it
7 * and/or modify it under the terms of the GNU General Public
8 * License (version 3) as published by the FSF - Free Software
13 * Available at http://www.ossec.net/
20 #include "os_xml_writer.h"
34 /* Internal functions */
35 int _oswcomment(FILE *fp_in, FILE *fp_out);
36 int _WReadElem(FILE *fp_in, FILE *fp_out, int position, int parent,
37 char **node, char *value, int node_pos);
45 int _xml_wfgetc(FILE *fp_in, FILE *fp_out)
49 /* Putting on fp_out, whatever we read */
56 if(c == '\n') /* add new line */
62 #define FWGETC(fp_in, fp_out) _xml_wfgetc(fp_in, fp_out)
67 * Write an XML file, based on the input and values to change.
69 int OS_WriteXML(char *infile, char *outfile, char **nodes, char *attr,
70 char *oldval, char *newval, int type)
78 /* Nodes and newval must be set. */
85 fp_in = fopen(infile,"r");
92 /* Opening out file */
93 fp_out = fopen(outfile,"w");
101 if((r = _WReadElem(fp_in, fp_out, 0, 0,
102 nodes, newval, node_pos)) < 0) /* First position */
109 /* We didn't find an entry, add at the end. */
110 if(!oldval && r == 0)
115 fseek(fp_out, 0, SEEK_END);
116 fprintf(fp_out, "\n");
118 /* Printing each node. */
121 fprintf(fp_out, "%*c<%s>", rwidth, ' ', nodes[r]);
126 fprintf(fp_out, "\n");
132 fprintf(fp_out, "%s</%s>\n", newval, nodes[r]);
136 /* Closing each node. */
139 fprintf(fp_out, "%*c</%s>\n", rwidth, ' ', nodes[r]);
152 /* Getting comments */
153 int _oswcomment(FILE *fp_in, FILE *fp_out)
156 if((c = fgetc(fp_in)) == _R_COM)
159 while((c = FWGETC(fp_in, fp_out)) != EOF)
163 if((c=fgetc(fp_in)) == _R_CONFE)
170 else if(c == '-') /* W3C way of finish comments */
172 if((c = fgetc(fp_in)) == '-')
175 if((c = fgetc(fp_in)) == _R_CONFE)
204 int _WReadElem(FILE *fp_in, FILE *fp_out,
205 int position, int parent, char **nodes, char *val, int node_pos)
209 unsigned int count = 0;
210 short int location = -1;
212 char elem[XML_MAXSIZE +1];
213 char cont[XML_MAXSIZE +1];
214 char closedelem[XML_MAXSIZE +1];
216 memset(elem,'\0',XML_MAXSIZE +1);
217 memset(cont,'\0',XML_MAXSIZE +1);
218 memset(closedelem,'\0',XML_MAXSIZE +1);
221 while((c = FWGETC(fp_in, fp_out)) != EOF)
224 if(count >= XML_MAXSIZE)
229 /* Checking for comments */
233 if((r = _oswcomment(fp_in, fp_out)) < 0)
247 /* Must be the opening element */
250 if((c = fgetc(fp_in)) == '/')
267 /* Looking for the closure */
268 else if((location == 0) && ((c == _R_CONFE) || (c == ' ')))
274 /* Removing the / at the end of the element name */
275 if(elem[count -1] == '/')
278 elem[count -1] = '\0';
282 /* If we may have more attributes */
285 /* Writing the attributes */
286 while((c = FWGETC(fp_in, fp_out)) != EOF)
296 /* If the element is closed already (finished in />) */
302 memset(elem,'\0',XML_MAXSIZE);
303 memset(closedelem,'\0',XML_MAXSIZE);
304 memset(cont,'\0',XML_MAXSIZE);
311 /* Location == means we are getting the content */
319 /* Checking position of the node */
320 if(node_pos > position)
325 /* Checking if the element name matches */
326 if(node_pos == position &&
327 nodes[node_pos] && strcmp(elem, nodes[node_pos]) == 0)
331 /* Latest node, printint value */
335 fprintf(fp_out, "%s", val);
337 while((c = fgetc(fp_in)) != EOF)
349 else if((location == 2) &&(c == _R_CONFE))
351 closedelem[count]='\0';
352 if(strcmp(closedelem,elem) != 0)
357 memset(elem,'\0',XML_MAXSIZE);
358 memset(closedelem,'\0',XML_MAXSIZE);
359 memset(cont,'\0',XML_MAXSIZE);
369 /* If we are reading the element */
370 else if((location == 1) &&(c == _R_CONFS))
372 if((c=fgetc(fp_in)) == '/')
384 ungetc(_R_CONFS,fp_in);
385 fseek(fp_out, -1, SEEK_CUR);
387 if((wret_code = _WReadElem(fp_in, fp_out, position+1, parent+1,
388 nodes, val, node_pos))< 0)
393 /* Setting final return code. */
408 else if(location == 1)
412 else if(location == 2)
414 closedelem[count++] = c;