/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * * This library is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . * */ #include #include #include #include #ifndef O_BINARY #define O_BINARY 0 #endif #include #include #include #include "e-xml-utils.h" #ifdef G_OS_WIN32 #define fsync(fd) 0 #endif /** * e_xml_parse_file: * @filename: path to an XML file * * Reads a local XML file and parses the contents into an XML document * structure. If the XML file cannot be read or its contents are malformed, * the function returns %NULL. * * Returns: an XML document structure, or %NULL **/ xmlDocPtr e_xml_parse_file (const gchar *filename) { xmlDocPtr result = NULL; GMappedFile *mapped_file; mapped_file = g_mapped_file_new (filename, FALSE, NULL); if (mapped_file) { result = xmlParseMemory ( g_mapped_file_get_contents (mapped_file), g_mapped_file_get_length (mapped_file)); g_mapped_file_unref (mapped_file); } return result; } /** * e_xml_save_file: * @filename: path to a file to save to * @doc: an XML document structure * * Writes the given XML document structure to the file given by @filename. * If an error occurs while saving, the function returns -1 and sets errno. * * Returns: 0 on success, -1 on failure **/ gint e_xml_save_file (const gchar *filename, xmlDocPtr doc) { gchar *filesave; xmlChar *xmlbuf; gsize n, written = 0; gint ret, fd, size; gint errnosave; gssize w; gchar *dirname = g_path_get_dirname (filename); gchar *basename = g_path_get_basename (filename); gchar *savebasename = g_strconcat (".#", basename, NULL); g_free (basename); filesave = g_build_filename (dirname, savebasename, NULL); g_free (savebasename); g_free (dirname); fd = g_open (filesave, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600); if (fd == -1) { g_free (filesave); return -1; } xmlDocDumpFormatMemory (doc, &xmlbuf, &size, TRUE); if (size <= 0) { close (fd); g_unlink (filesave); g_free (filesave); errno = ENOMEM; return -1; } n = (gsize) size; do { do { w = write (fd, xmlbuf + written, n - written); } while (w == -1 && errno == EINTR); if (w > 0) written += w; } while (w != -1 && written < n); xmlFree (xmlbuf); if (written < n || fsync (fd) == -1) { errnosave = errno; close (fd); g_unlink (filesave); g_free (filesave); errno = errnosave; return -1; } while ((ret = close (fd)) == -1 && errno == EINTR) ; if (ret == -1) { g_free (filesave); return -1; } if (g_rename (filesave, filename) == -1) { errnosave = errno; g_unlink (filesave); g_free (filesave); errno = errnosave; return -1; } g_free (filesave); return 0; } /** * e_xml_get_child_by_name: * @parent: an XML node structure * @child_name: element name of a child node * * Attempts to find a child element of @parent named @child_name. * If no such child exists, the function returns %NULL. * * Returns: a child XML node structure, or %NULL **/ xmlNode * e_xml_get_child_by_name (const xmlNode *parent, const xmlChar *child_name) { xmlNode *child; g_return_val_if_fail (parent != NULL, NULL); g_return_val_if_fail (child_name != NULL, NULL); for (child = parent->xmlChildrenNode; child != NULL; child = child->next) { if (xmlStrcmp (child->name, child_name) == 0) { return child; } } return NULL; }