/* * nvidia-xconfig: A tool for manipulating XF86Config files, * specifically for use by the NVIDIA Linux graphics driver. * * Copyright (C) 2004 NVIDIA Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program 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 General Public License for * more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * * util.c */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "nvidia-xconfig.h" #include "msg.h" Options *__op = NULL; /* * copy_file() - copy the file specified by srcfile to dstfile, using * mmap and memcpy. The destination file is created with the * permissions specified by mode. Roughly based on code presented by * Richard Stevens, in Advanced Programming in the Unix Environment, * 12.9. */ int copy_file(const char *srcfile, const char *dstfile, mode_t mode) { int src_fd = -1, dst_fd = -1; struct stat stat_buf; char *src, *dst; int ret = FALSE; if ((src_fd = open(srcfile, O_RDONLY)) == -1) { nv_error_msg("Unable to open '%s' for copying (%s)", srcfile, strerror (errno)); goto done; } if ((dst_fd = open(dstfile, O_RDWR | O_CREAT | O_TRUNC, mode)) == -1) { nv_error_msg("Unable to create '%s' for copying (%s)", dstfile, strerror (errno)); goto done; } if (fstat(src_fd, &stat_buf) == -1) { nv_error_msg("Unable to determine size of '%s' (%s)", srcfile, strerror (errno)); goto done; } if (stat_buf.st_size == 0) { /* src file is empty; silently ignore */ ret = TRUE; goto done; } if (lseek(dst_fd, stat_buf.st_size - 1, SEEK_SET) == -1) { nv_error_msg("Unable to set file size for '%s' (%s)", dstfile, strerror (errno)); goto done; } if (write(dst_fd, "", 1) != 1) { nv_error_msg("Unable to write file size for '%s' (%s)", dstfile, strerror (errno)); goto done; } if ((src = mmap(0, stat_buf.st_size, PROT_READ, MAP_SHARED, src_fd, 0)) == (void *) -1) { nv_error_msg("Unable to map source file '%s' for " "copying (%s)", srcfile, strerror (errno)); goto done; } if ((dst = mmap(0, stat_buf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, dst_fd, 0)) == (void *) -1) { nv_error_msg("Unable to map destination file '%s' for " "copying (%s)", dstfile, strerror (errno)); goto done; } memcpy(dst, src, stat_buf.st_size); if (munmap (src, stat_buf.st_size) == -1) { nv_error_msg("Unable to unmap source file '%s' after " "copying (%s)", srcfile, strerror (errno)); goto done; } if (munmap (dst, stat_buf.st_size) == -1) { nv_error_msg("Unable to unmap destination file '%s' after " "copying (%s)", dstfile, strerror (errno)); goto done; } ret = TRUE; done: if (src_fd != -1) close(src_fd); if (dst_fd != -1) close(dst_fd); return ret; } /* copy_file() */ /* * xconfigPrint() - this is the one entry point that a user of the * XF86Config-Parser library must provide. */ void xconfigPrint(MsgType t, const char *msg) { typedef struct { MsgType msg_type; char *prefix; FILE *stream; int newline; } MessageTypeAttributes; char *prefix = NULL; int i, newline = FALSE; FILE *stream = stdout; const MessageTypeAttributes msg_types[] = { { ParseErrorMsg, "PARSE ERROR: ", stderr, TRUE }, { ParseWarningMsg, "PARSE WARNING: ", stderr, TRUE }, { ValidationErrorMsg, "VALIDATION ERROR: ", stderr, TRUE }, { InternalErrorMsg, "INTERNAL ERROR: ", stderr, TRUE }, { WriteErrorMsg, "ERROR: ", stderr, TRUE }, { WarnMsg, "WARNING: ", stderr, TRUE }, { ErrorMsg, "ERROR: ", stderr, TRUE }, { DebugMsg, "DEBUG: ", stdout, FALSE }, { UnknownMsg, NULL, stdout, FALSE }, }; for (i = 0; msg_types[i].msg_type != UnknownMsg; i++) { if (msg_types[i].msg_type == t) { prefix = msg_types[i].prefix; newline = msg_types[i].newline; stream = msg_types[i].stream; break; } } if (newline) nv_info_msg_to_file(stream, NULL, ""); nv_info_msg_to_file(stream, prefix, "%s", msg); if (newline) nv_info_msg_to_file(stream, NULL, ""); } /* xconfigPrint */