1 /*
2 * Motif
3 *
4 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5 *
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
22 */
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27
28 #ifdef REV_INFO
29 #ifndef lint
30 static char rcsid[] = "$XConsortium: MrmIfile.c /main/13 1996/11/13 13:56:30 drk $"
31 #endif
32 #endif
33
34
35 /*
36 *++
37 * FACILITY:
38 *
39 * UIL Resource Manager (URM)
40 *
41 * ABSTRACT:
42 *
43 * This module contains the low-level file utilities
44 *
45 *--
46 */
47
48
49 /*
50 *
51 * INCLUDE FILES
52 *
53 */
54
55 #include <Mrm/MrmAppl.h>
56 #include <Mrm/Mrm.h>
57 #include <Mrm/IDB.h>
58
59 #include <stdio.h> /* Standard IO definitions */
60 #include <errno.h>
61 #include <fcntl.h>
62
63 #ifndef X_NOT_STDC_ENV
64 #include <unistd.h>
65 #endif
66
67
68 /*
69 *
70 * DEFINE and MACRO DEFINITIONS
71 *
72 */
73
74 #define PMODE 0666 /* Default protection mode before umask */
75 #define FAILURE -1 /* creat/stat returns this */
76
77 /*
78 *++
79 *
80 * PROCEDURE DESCRIPTION:
81 *
82 * This routine will take the file name specified and
83 * open or create it depending on the access parameter.
84 * An attempt is made to save any existing file of the
85 * same name.
86 *
87 *
88 * FORMAL PARAMETERS:
89 *
90 * name the system-dependent file spec of the IDB file
91 * to be opened.
92 * accss access type desired, read or write access.
93 * os_ext an operating specific structure to take advantage
94 * of file system features (if any).
95 * file_id IDB file id used in all calls to low level routines.
96 * returned_fname The resultant file name.
97 *
98 * IMPLICIT INPUTS:
99 *
100 * NONE
101 *
102 * IMPLICIT OUTPUTS:
103 *
104 * NONE
105 *
106 * FUNCTION VALUE:
107 *
108 * Returns an integer:
109 *
110 * MrmSUCCESS - When access is read and open works
111 * MrmCREATE_NEW - When access is write and open works
112 * MrmNOT_FOUND - When access is read and the file isn't present
113 * MrmFAILURE - When the open fails for any other reason
114 *
115 * SIDE EFFECTS:
116 *
117 * Opens or creates the named file and assigns a channel to it.
118 *
119 *--
120 */
121
122 Cardinal
123 Idb__FU_OpenFile (char *name,
124 MrmCode access,
125 MrmOsOpenParamPtr os_ext,
126 IDBLowLevelFilePtr *file_id,
127 char *returned_fname)
128 {
129
130 /*
131 * Local variables
132 */
133 int file_desc; /* 'unix' file descriptor */
134 int length; /* the length of the above string */
135 IDBLowLevelFile *a_file; /* pointer to the file_id */
136
137 /* Fill in the result name with the name specified so far */
138 length = strlen (name);
139 strcpy (returned_fname, name);
140 returned_fname[length] = 0;
141
142 /* Check if this file is to be opened for read or write access */
143 if (access == URMWriteAccess)
144 {
145 file_desc = open (name, O_RDWR, PMODE);
146 if (file_desc != FAILURE) /* filename already exists. */
147 {
148 if (os_ext == 0)
149 return MrmFAILURE;
150 else if (!os_ext->nam_flg.clobber_flg)
151 return MrmEXISTS; /* no clobber. return Exists */
152 else if (os_ext->version != MrmOsOpenParamVersion)
153 return MrmFAILURE;
154 (void) close (file_desc); /* we care not what close returns*/
155 }
156
157 file_desc = creat (name,PMODE);
158 if (file_desc == FAILURE) /* verify that worked */
159 return MrmFAILURE;
160
161 close (file_desc); /* we care not what close returns */
162 file_desc = open (name, O_RDWR, PMODE);
163
164 if (file_desc == FAILURE) /* verify that worked */
165 return MrmFAILURE;
166 }
167
168
169 /* Else this file is to opened for read access */
170 else if (access == URMReadAccess)
171 {
172 file_desc = open (name, O_RDONLY, PMODE);
173
174 /* verify that worked */
175 if (file_desc == FAILURE)
176 {
177 if ( errno == EACCES )
178 return MrmFAILURE;
179 else
180 return MrmNOT_FOUND;
181 }
182 }
183
184 /* Not URMReadAccess or URMWriteAccess, so return invalid access type */
185 else
186 return MrmFAILURE;
187
188
189 /*
190 * now all we have to do is set up the IDBFile and return the
191 * proper success code.
192 */
193
194 *file_id = (IDBLowLevelFilePtr)
195 XtMalloc(sizeof (IDBLowLevelFile));
196 if (*file_id==0)
197 return MrmFAILURE;
198
199 a_file = (IDBLowLevelFile *) *file_id;
200
201 a_file->name = XtMalloc (length+1);
202 if (a_file->name==0)
203 {
204 XtFree ((char*)*file_id);
205 return (MrmFAILURE);
206 }
207
208 a_file->file_desc = file_desc;
209 strcpy (a_file->name, name);
210 a_file->name[length] = 0;
211
212 if (access == URMWriteAccess)
213 return (MrmCREATE_NEW);
214 else
215 return (MrmSUCCESS);
216
217 }
218
219
220
221 /*
222 *++
223 *
224 * PROCEDURE DESCRIPTION:
225 *
226 * This routine will close the file and free any allocated storage
227 *
228 *
229 * FORMAL PARAMETERS:
230 *
231 * file_id IDB file id
232 * delete delete the file if == true
233 *
234 * IMPLICIT INPUTS:
235 *
236 * the file name and channel from the IDBFile record
237 *
238 * IMPLICIT OUTPUTS:
239 *
240 * NONE
241 *
242 * FUNCTION VALUE:
243 *
244 * MrmSUCCESS - When the file is closed [and deleted] successfully
245 * MrmFAILURE - When the close fails
246 *
247 * SIDE EFFECTS:
248 *
249 * Closes the file, deassigns the channel and possible deletes the file.
250 *
251 *--
252 */
253
254 Cardinal
Idb__FU_CloseFile(IDBLowLevelFile * file_id,int delete)255 Idb__FU_CloseFile (IDBLowLevelFile *file_id ,
256 int delete)
257 {
258 /*
259 * Local variables
260 */
261
262 int status; /* ret status for sys services */
263
264 status = close (file_id->file_desc);
265 if (status != 0)
266 return MrmFAILURE;
267
268 if (delete) {
269 status = unlink (file_id->name);
270 }
271
272 XtFree (file_id->name);
273 XtFree ((char*)file_id);
274 return MrmSUCCESS;
275
276 }
277
278 /*
279 *++
280 *
281 * PROCEDURE DESCRIPTION:
282 *
283 * This function reads in the desired record into the given
284 * buffer.
285 *
286 * FORMAL PARAMETERS:
287 *
288 * file_id the IDB file identifier
289 * block_num the record number to retrieve
290 * buffer pointer to the buffer to fill in
291 *
292 * IMPLICIT INPUTS:
293 *
294 * NONE
295 *
296 * IMPLICIT OUTPUTS:
297 *
298 * NONE
299 *
300 * FUNCTION VALUE:
301 *
302 * MrmSUCCESS operation succeeded
303 * MrmNOT_FOUND entry not found
304 * MrmFAILURE operation failed, no further reason
305 *
306 * SIDE EFFECTS:
307 *
308 * The buffer is filled in. Should the $READ fail the buffer's
309 * content is not predictable.
310 *
311 *--
312 */
313
314 Cardinal
Idb__FU_GetBlock(IDBLowLevelFile * file_id,IDBRecordNumber block_num,char * buffer)315 Idb__FU_GetBlock (IDBLowLevelFile *file_id,
316 IDBRecordNumber block_num,
317 char *buffer)
318 {
319 /*
320 * Local variables
321 */
322 int number_read; /* the number of bytes actually read */
323 int fdesc ; /* file descriptor from lowlevel desc */
324
325
326 fdesc = file_id->file_desc ;
327 lseek (fdesc, (block_num-1)*IDBRecordSize, 0);
328 number_read = read (file_id->file_desc, buffer, IDBRecordSize);
329
330 if (number_read != IDBRecordSize)
331 return MrmFAILURE;
332 else
333 return MrmSUCCESS;
334 }
335
336
337 /*
338 *++
339 *
340 * PROCEDURE DESCRIPTION:
341 *
342 * This function writes the data in the givin buffer into
343 * the desired record in the file.
344 *
345 * FORMAL PARAMETERS:
346 *
347 * file_id the IDB file identifier
348 * block_num the record number to write
349 * buffer pointer to the buffer to read from
350 *
351 * IMPLICIT INPUTS:
352 *
353 * NONE
354 *
355 * IMPLICIT OUTPUTS:
356 *
357 * NONE
358 *
359 * FUNCTION VALUE:
360 *
361 * Returns an integer by value:
362 *
363 * MrmSUCCESS operation succeeded
364 * MrmFAILURE operation failed, no further reason
365 *
366 * SIDE EFFECTS:
367 *
368 * the file is modified.
369 *
370 *--
371 */
372
373 Cardinal
Idb__FU_PutBlock(IDBLowLevelFile * file_id,IDBRecordNumber block_num,char * buffer)374 Idb__FU_PutBlock (IDBLowLevelFile *file_id,
375 IDBRecordNumber block_num,
376 char *buffer)
377 {
378 /*
379 * Local variables
380 */
381 int number_written; /* the # of bytes acctually written */
382 int fdesc ; /* file descriptor from lowlevel desc */
383
384
385 fdesc = file_id->file_desc ;
386 lseek (fdesc, (block_num-1)*IDBRecordSize, 0);
387 number_written = write (file_id->file_desc, buffer, IDBRecordSize);
388
389 if (number_written != IDBRecordSize)
390 return MrmFAILURE;
391 else
392 return MrmSUCCESS;
393 }
394
395