write.c revision 706f2543
1/* 2 * Copyright (c) 1997 Metro Link Incorporated 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * SOFTWARE. 21 * 22 * Except as contained in this notice, the name of the Metro Link shall not be 23 * used in advertising or otherwise to promote the sale, use or other dealings 24 * in this Software without prior written authorization from Metro Link. 25 * 26 */ 27/* 28 * Copyright (c) 1997-2003 by The XFree86 Project, Inc. 29 * 30 * Permission is hereby granted, free of charge, to any person obtaining a 31 * copy of this software and associated documentation files (the "Software"), 32 * to deal in the Software without restriction, including without limitation 33 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 34 * and/or sell copies of the Software, and to permit persons to whom the 35 * Software is furnished to do so, subject to the following conditions: 36 * 37 * The above copyright notice and this permission notice shall be included in 38 * all copies or substantial portions of the Software. 39 * 40 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 41 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 42 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 43 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 44 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 45 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 46 * OTHER DEALINGS IN THE SOFTWARE. 47 * 48 * Except as contained in this notice, the name of the copyright holder(s) 49 * and author(s) shall not be used in advertising or otherwise to promote 50 * the sale, use or other dealings in this Software without prior written 51 * authorization from the copyright holder(s) and author(s). 52 */ 53 54 55/* View/edit this file with tab stops set to 4 */ 56 57#ifdef HAVE_XORG_CONFIG_H 58#include <xorg-config.h> 59#endif 60 61#include "xf86Parser.h" 62#include "xf86tokens.h" 63#include "Configint.h" 64 65#include <unistd.h> 66#include <sys/types.h> 67#include <sys/wait.h> 68#include <signal.h> 69#include <errno.h> 70 71#if defined(SVR4) || defined(__linux__) || defined(CSRG_BASED) 72#define HAS_SAVED_IDS_AND_SETEUID 73#endif 74#if defined(WIN32) 75#define HAS_NO_UIDS 76#endif 77 78#ifdef HAS_NO_UIDS 79#define doWriteConfigFile xf86writeConfigFile 80#define Local /**/ 81#else 82#define Local static 83#endif 84 85Local int 86doWriteConfigFile (const char *filename, XF86ConfigPtr cptr) 87{ 88 FILE *cf; 89 90 if ((cf = fopen (filename, "w")) == NULL) 91 { 92 return 0; 93 } 94 95 if (cptr->conf_comment) 96 fprintf (cf, "%s\n", cptr->conf_comment); 97 98 xf86printLayoutSection (cf, cptr->conf_layout_lst); 99 100 if (cptr->conf_files != NULL) 101 { 102 fprintf (cf, "Section \"Files\"\n"); 103 xf86printFileSection (cf, cptr->conf_files); 104 fprintf (cf, "EndSection\n\n"); 105 } 106 107 if (cptr->conf_modules != NULL) 108 { 109 fprintf (cf, "Section \"Module\"\n"); 110 xf86printModuleSection (cf, cptr->conf_modules); 111 fprintf (cf, "EndSection\n\n"); 112 } 113 114 xf86printVendorSection (cf, cptr->conf_vendor_lst); 115 116 xf86printServerFlagsSection (cf, cptr->conf_flags); 117 118 xf86printInputSection (cf, cptr->conf_input_lst); 119 120 xf86printInputClassSection (cf, cptr->conf_inputclass_lst); 121 122 xf86printVideoAdaptorSection (cf, cptr->conf_videoadaptor_lst); 123 124 xf86printModesSection (cf, cptr->conf_modes_lst); 125 126 xf86printMonitorSection (cf, cptr->conf_monitor_lst); 127 128 xf86printDeviceSection (cf, cptr->conf_device_lst); 129 130 xf86printScreenSection (cf, cptr->conf_screen_lst); 131 132 xf86printDRISection (cf, cptr->conf_dri); 133 134 xf86printExtensionsSection (cf, cptr->conf_extensions); 135 136 fclose(cf); 137 return 1; 138} 139 140#ifndef HAS_NO_UIDS 141 142int 143xf86writeConfigFile (const char *filename, XF86ConfigPtr cptr) 144{ 145 int ret; 146 147#if !defined(HAS_SAVED_IDS_AND_SETEUID) 148 int pid, p; 149 int status; 150 void (*csig)(int); 151#else 152 int ruid, euid; 153#endif 154 155 if (getuid() != geteuid()) 156 { 157 158#if !defined(HAS_SAVED_IDS_AND_SETEUID) 159 /* Need to fork to change ruid without loosing euid */ 160 csig = signal(SIGCHLD, SIG_DFL); 161 switch ((pid = fork())) 162 { 163 case -1: 164 ErrorF("xf86writeConfigFile(): fork failed (%s)\n", 165 strerror(errno)); 166 return 0; 167 case 0: /* child */ 168 if (setuid(getuid()) == -1) 169 FatalError("xf86writeConfigFile(): " 170 "setuid failed(%s)\n", 171 strerror(errno)); 172 ret = doWriteConfigFile(filename, cptr); 173 exit(ret); 174 break; 175 default: /* parent */ 176 do 177 { 178 p = waitpid(pid, &status, 0); 179 } while (p == -1 && errno == EINTR); 180 } 181 signal(SIGCHLD, csig); 182 if (p != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0) 183 return 1; /* success */ 184 else 185 return 0; 186 187#else /* HAS_SAVED_IDS_AND_SETEUID */ 188 189 ruid = getuid(); 190 euid = geteuid(); 191 192 if (seteuid(ruid) == -1) 193 { 194 ErrorF("xf86writeConfigFile(): seteuid(%d) failed (%s)\n", 195 ruid, strerror(errno)); 196 return 0; 197 } 198 ret = doWriteConfigFile(filename, cptr); 199 200 if (seteuid(euid) == -1) 201 { 202 ErrorF("xf86writeConfigFile(): seteuid(%d) failed (%s)\n", 203 euid, strerror(errno)); 204 } 205 return ret; 206 207#endif /* HAS_SAVED_IDS_AND_SETEUID */ 208 209 } 210 else 211 { 212 return doWriteConfigFile(filename, cptr); 213 } 214} 215 216#endif /* !HAS_NO_UIDS */ 217