/[baselayout]/trunk/src/filefuncs/filefuncs.c
Gentoo

Contents of /trunk/src/filefuncs/filefuncs.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 345 - (show annotations) (download) (as text)
Sun Apr 6 16:28:27 2003 UTC (16 years ago) by azarah
File MIME type: text/x-csrc
File size: 10922 byte(s)
various fixes; moved .c files to src

1 /*
2 * filefuncs.c - Builtin functions that provide initial minimal iterface
3 * to the file system.
4 *
5 * Arnold Robbins, update for 3.1, Mon Nov 23 12:53:39 EST 1998
6 */
7
8 /*
9 * Copyright (C) 2001 the Free Software Foundation, Inc.
10 *
11 * This file is part of GAWK, the GNU implementation of the
12 * AWK Programming Language.
13 *
14 * GAWK is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * GAWK is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
27 */
28
29 /*
30 * Copyright 1999-2003 Gentoo Technologies, Inc.
31 * Distributed under the terms of the GNU General Public License v2
32 * Author: Martin Schlemmer <azarah@gentoo.org>, Nov 2002
33 * $Header$
34 *
35 * Extended with: do_symlink()
36 * do_unlink()
37 * do_mkdir()
38 * do_rmdir()
39 *
40 * for use in the Gentoo rcscripts
41 *
42 */
43
44 #include "awk.h"
45
46 #include <unistd.h>
47 #include <sys/sysmacros.h>
48
49 /* do_chdir --- provide dynamically loaded chdir() builtin for gawk */
50
51 static NODE *
52 do_chdir(tree)
53 NODE *tree;
54 {
55 NODE *newdir;
56 int ret = -1;
57
58 if (do_lint && tree->param_cnt > 1)
59 lintwarn("chdir: called with too many arguments");
60
61 newdir = get_argument(tree, 0);
62 if (newdir != NULL) {
63 (void) force_string(newdir);
64 ret = chdir(newdir->stptr);
65 if (ret < 0)
66 update_ERRNO();
67
68 free_temp(newdir);
69 } else if (do_lint)
70 lintwarn("chdir: called with no arguments");
71
72
73 /* Set the return value */
74 set_value(tmp_number((AWKNUM) ret));
75
76 /* Just to make the interpreter happy */
77 return tmp_number((AWKNUM) 0);
78 }
79
80 /* do_symlink --- provide dynamically loaded symlink() builtin for gawk */
81
82 static NODE *
83 do_symlink(tree)
84 NODE *tree;
85 {
86 NODE *oldpath, *newpath;
87 int ret = -1;
88
89 if (do_lint && tree->param_cnt > 2)
90 lintwarn("symlink: called with too many arguments");
91
92 oldpath = get_argument(tree, 0);
93 newpath = get_argument(tree, 1);
94 if ((oldpath != NULL) && (newpath)) {
95 (void) force_string(oldpath);
96 (void) force_string(newpath);
97 ret = symlink(oldpath->stptr, newpath->stptr);
98 if (ret < 0)
99 update_ERRNO();
100
101 free_temp(oldpath);
102 free_temp(newpath);
103 } else if (do_lint)
104 lintwarn("symlink: called with not enough arguments");
105
106 /* Set the return value */
107 set_value(tmp_number((AWKNUM) ret));
108
109 /* Just to make the interpreter happy */
110 return tmp_number((AWKNUM) 0);
111 }
112
113 /* do_unlink --- provide dynamically loaded unlink() builtin for gawk */
114
115 static NODE *
116 do_unlink(tree)
117 NODE *tree;
118 {
119 NODE *pathname;
120 int ret = -1;
121
122 if (do_lint && tree->param_cnt > 1)
123 lintwarn("unlink: called with too many arguments");
124
125 pathname = get_argument(tree, 0);
126 if (pathname != NULL) {
127 (void) force_string(pathname);
128 ret = unlink(pathname->stptr);
129 if (ret < 0)
130 update_ERRNO();
131
132 free_temp(pathname);
133 } else if (do_lint)
134 lintwarn("unlink: called with no arguments");
135
136 /* Set the return value */
137 set_value(tmp_number((AWKNUM) ret));
138
139 /* Just to make the interpreter happy */
140 return tmp_number((AWKNUM) 0);
141 }
142
143 /* do_mkdir --- provide dynamically loaded mkdir() builtin for gawk */
144
145 static NODE *
146 do_mkdir(tree)
147 NODE *tree;
148 {
149 NODE *pathname, *mode;
150 int ret = -1;
151
152 if (do_lint && tree->param_cnt > 2)
153 lintwarn("mkdir: called with too many arguments");
154
155 pathname = get_argument(tree, 0);
156 mode = get_argument(tree, 1);
157 if ((pathname != NULL) && (mode != NULL)) {
158 (void) force_string(pathname);
159 (void) force_number(mode);
160 ret = mkdir(pathname->stptr, mode->numbr);
161 if (ret < 0)
162 update_ERRNO();
163
164 free_temp(pathname);
165 free_temp(mode);
166 } else if (do_lint)
167 lintwarn("mkdir: called with not enough arguments");
168
169 /* Set the return value */
170 set_value(tmp_number((AWKNUM) ret));
171
172 /* Just to make the interpreter happy */
173 return tmp_number((AWKNUM) 0);
174 }
175
176 /* do_rmdir --- provide dynamically loaded rmdir() builtin for gawk */
177
178 static NODE *
179 do_rmdir(tree)
180 NODE *tree;
181 {
182 NODE *pathname;
183 int ret = -1;
184
185 if (do_lint && tree->param_cnt > 1)
186 lintwarn("rmdir: called with too many arguments");
187
188 pathname = get_argument(tree, 0);
189 if (pathname != NULL) {
190 (void) force_string(pathname);
191 ret = rmdir(pathname->stptr);
192 if (ret < 0)
193 update_ERRNO();
194
195 free_temp(pathname);
196 } else if (do_lint)
197 lintwarn("rmdir: called with no arguments");
198
199 /* Set the return value */
200 set_value(tmp_number((AWKNUM) ret));
201
202 /* Just to make the interpreter happy */
203 return tmp_number((AWKNUM) 0);
204 }
205
206 /* format_mode --- turn a stat mode field into something readable */
207
208 static char *
209 format_mode(fmode)
210 unsigned long fmode;
211 {
212 static char outbuf[12];
213 int i;
214
215 strcpy(outbuf, "----------");
216 /* first, get the file type */
217 i = 0;
218 switch (fmode & S_IFMT) {
219 #ifdef S_IFSOCK
220 case S_IFSOCK:
221 outbuf[i] = 's';
222 break;
223 #endif
224 #ifdef S_IFLNK
225 case S_IFLNK:
226 outbuf[i] = 'l';
227 break;
228 #endif
229 case S_IFREG:
230 outbuf[i] = '-'; /* redundant */
231 break;
232 case S_IFBLK:
233 outbuf[i] = 'b';
234 break;
235 case S_IFDIR:
236 outbuf[i] = 'd';
237 break;
238 #ifdef S_IFDOOR /* Solaris weirdness */
239 case S_IFDOOR:
240 outbuf[i] = 'D';
241 break;
242 #endif /* S_IFDOOR */
243 case S_IFCHR:
244 outbuf[i] = 'c';
245 break;
246 #ifdef S_IFIFO
247 case S_IFIFO:
248 outbuf[i] = 'p';
249 break;
250 #endif
251 }
252
253 i++;
254 if ((fmode & S_IRUSR) != 0)
255 outbuf[i] = 'r';
256 i++;
257 if ((fmode & S_IWUSR) != 0)
258 outbuf[i] = 'w';
259 i++;
260 if ((fmode & S_IXUSR) != 0)
261 outbuf[i] = 'x';
262 i++;
263
264 if ((fmode & S_IRGRP) != 0)
265 outbuf[i] = 'r';
266 i++;
267 if ((fmode & S_IWGRP) != 0)
268 outbuf[i] = 'w';
269 i++;
270 if ((fmode & S_IXGRP) != 0)
271 outbuf[i] = 'x';
272 i++;
273
274 if ((fmode & S_IROTH) != 0)
275 outbuf[i] = 'r';
276 i++;
277 if ((fmode & S_IWOTH) != 0)
278 outbuf[i] = 'w';
279 i++;
280 if ((fmode & S_IXOTH) != 0)
281 outbuf[i] = 'x';
282 i++;
283
284 outbuf[i] = '\0';
285
286 if ((fmode & S_ISUID) != 0) {
287 if (outbuf[3] == 'x')
288 outbuf[3] = 's';
289 else
290 outbuf[3] = 'S';
291 }
292
293 /* setgid without execute == locking */
294 if ((fmode & S_ISGID) != 0) {
295 if (outbuf[6] == 'x')
296 outbuf[6] = 's';
297 else
298 outbuf[6] = 'l';
299 }
300
301 if ((fmode & S_ISVTX) != 0) {
302 if (outbuf[9] == 'x')
303 outbuf[9] = 't';
304 else
305 outbuf[9] = 'T';
306 }
307
308 return outbuf;
309 }
310
311 /* do_stat --- provide a stat() function for gawk */
312
313 static NODE *
314 do_stat(tree)
315 NODE *tree;
316 {
317 NODE *file, *array;
318 struct stat sbuf;
319 int ret;
320 NODE **aptr;
321 char *pmode; /* printable mode */
322 char *type = "unknown";
323
324 /* check arg count */
325 if (tree->param_cnt != 2)
326 fatal(
327 "stat: called with incorrect number of arguments (%d), should be 2",
328 tree->param_cnt);
329
330 /* directory is first arg, array to hold results is second */
331 file = get_argument(tree, 0);
332 array = get_argument(tree, 1);
333
334 /* empty out the array */
335 assoc_clear(array);
336
337 /* lstat the file, if error, set ERRNO and return */
338 (void) force_string(file);
339 ret = lstat(file->stptr, & sbuf);
340 if (ret < 0) {
341 update_ERRNO();
342
343 set_value(tmp_number((AWKNUM) ret));
344
345 free_temp(file);
346 return tmp_number((AWKNUM) 0);
347 }
348
349 /* fill in the array */
350 aptr = assoc_lookup(array, tmp_string("name", 4), FALSE);
351 *aptr = dupnode(file);
352
353 aptr = assoc_lookup(array, tmp_string("dev", 3), FALSE);
354 *aptr = make_number((AWKNUM) sbuf.st_dev);
355
356 aptr = assoc_lookup(array, tmp_string("ino", 3), FALSE);
357 *aptr = make_number((AWKNUM) sbuf.st_ino);
358
359 aptr = assoc_lookup(array, tmp_string("mode", 4), FALSE);
360 *aptr = make_number((AWKNUM) sbuf.st_mode);
361
362 aptr = assoc_lookup(array, tmp_string("nlink", 5), FALSE);
363 *aptr = make_number((AWKNUM) sbuf.st_nlink);
364
365 aptr = assoc_lookup(array, tmp_string("uid", 3), FALSE);
366 *aptr = make_number((AWKNUM) sbuf.st_uid);
367
368 aptr = assoc_lookup(array, tmp_string("gid", 3), FALSE);
369 *aptr = make_number((AWKNUM) sbuf.st_gid);
370
371 aptr = assoc_lookup(array, tmp_string("size", 4), FALSE);
372 *aptr = make_number((AWKNUM) sbuf.st_size);
373
374 aptr = assoc_lookup(array, tmp_string("blocks", 6), FALSE);
375 *aptr = make_number((AWKNUM) sbuf.st_blocks);
376
377 aptr = assoc_lookup(array, tmp_string("atime", 5), FALSE);
378 *aptr = make_number((AWKNUM) sbuf.st_atime);
379
380 aptr = assoc_lookup(array, tmp_string("mtime", 5), FALSE);
381 *aptr = make_number((AWKNUM) sbuf.st_mtime);
382
383 aptr = assoc_lookup(array, tmp_string("ctime", 5), FALSE);
384 *aptr = make_number((AWKNUM) sbuf.st_ctime);
385
386 /* for block and character devices, add rdev, major and minor numbers */
387 if (S_ISBLK(sbuf.st_mode) || S_ISCHR(sbuf.st_mode)) {
388 aptr = assoc_lookup(array, tmp_string("rdev", 4), FALSE);
389 *aptr = make_number((AWKNUM) sbuf.st_rdev);
390
391 aptr = assoc_lookup(array, tmp_string("major", 5), FALSE);
392 *aptr = make_number((AWKNUM) major(sbuf.st_rdev));
393
394 aptr = assoc_lookup(array, tmp_string("minor", 5), FALSE);
395 *aptr = make_number((AWKNUM) minor(sbuf.st_rdev));
396 }
397
398 #ifdef HAVE_ST_BLKSIZE
399 aptr = assoc_lookup(array, tmp_string("blksize", 7), FALSE);
400 *aptr = make_number((AWKNUM) sbuf.st_blksize);
401 #endif /* HAVE_ST_BLKSIZE */
402
403 aptr = assoc_lookup(array, tmp_string("pmode", 5), FALSE);
404 pmode = format_mode(sbuf.st_mode);
405 *aptr = make_string(pmode, strlen(pmode));
406
407 /* for symbolic links, add a linkval field */
408 if (S_ISLNK(sbuf.st_mode)) {
409 char buf[BUFSIZ*2];
410 int linksize;
411
412 linksize = readlink(file->stptr, buf, sizeof buf);
413 /* should make this smarter */
414 if (linksize == sizeof(buf))
415 fatal("size of symbolic link too big");
416 buf[linksize] = '\0';
417
418 aptr = assoc_lookup(array, tmp_string("linkval", 7), FALSE);
419 *aptr = make_string(buf, linksize);
420 }
421
422 /* add a type field */
423 switch (sbuf.st_mode & S_IFMT) {
424 #ifdef S_IFSOCK
425 case S_IFSOCK:
426 type = "socket";
427 break;
428 #endif
429 #ifdef S_IFLNK
430 case S_IFLNK:
431 type = "symlink";
432 break;
433 #endif
434 case S_IFREG:
435 type = "file";
436 break;
437 case S_IFBLK:
438 type = "blockdev";
439 break;
440 case S_IFDIR:
441 type = "directory";
442 break;
443 #ifdef S_IFDOOR
444 case S_IFDOOR:
445 type = "door";
446 break;
447 #endif
448 case S_IFCHR:
449 type = "chardev";
450 break;
451 #ifdef S_IFIFO
452 case S_IFIFO:
453 type = "fifo";
454 break;
455 #endif
456 }
457
458 aptr = assoc_lookup(array, tmp_string("type", 4), FALSE);
459 *aptr = make_string(type, strlen(type));
460
461 free_temp(file);
462
463 /* Set the return value */
464 set_value(tmp_number((AWKNUM) ret));
465
466 /* Just to make the interpreter happy */
467 return tmp_number((AWKNUM) 0);
468 }
469
470 /* dlload --- load new builtins in this library */
471
472 NODE *
473 dlload(tree, dl)
474 NODE *tree;
475 void *dl;
476 {
477 make_builtin("chdir", do_chdir, 1);
478 make_builtin("symlink", do_symlink, 2);
479 make_builtin("unlink", do_unlink, 1);
480 make_builtin("mkdir", do_mkdir, 2);
481 make_builtin("rmdir", do_rmdir, 1);
482 make_builtin("stat", do_stat, 2);
483
484 return tmp_number((AWKNUM) 0);
485 }
486

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.20