00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "awk.h"
00030
00031 #include <sys/sysmacros.h>
00032
00033
00034
00035 static NODE *
00036 do_chdir(tree)
00037 NODE *tree;
00038 {
00039 NODE *newdir;
00040 int ret = -1;
00041
00042 if (do_lint && tree->param_cnt > 1)
00043 lintwarn("chdir: called with too many arguments");
00044
00045 newdir = get_argument(tree, 0);
00046 if (newdir != NULL) {
00047 (void) force_string(newdir);
00048 ret = chdir(newdir->stptr);
00049 if (ret < 0)
00050 update_ERRNO();
00051
00052 free_temp(newdir);
00053 } else if (do_lint)
00054 lintwarn("chdir: called with no arguments");
00055
00056
00057
00058 set_value(tmp_number((AWKNUM) ret));
00059
00060
00061 return tmp_number((AWKNUM) 0);
00062 }
00063
00064
00065
00066 static char *
00067 format_mode(fmode)
00068 unsigned long fmode;
00069 {
00070 static char outbuf[12];
00071 int i;
00072
00073 strcpy(outbuf, "----------");
00074
00075 i = 0;
00076 switch (fmode & S_IFMT) {
00077 #ifdef S_IFSOCK
00078 case S_IFSOCK:
00079 outbuf[i] = 's';
00080 break;
00081 #endif
00082 #ifdef S_IFLNK
00083 case S_IFLNK:
00084 outbuf[i] = 'l';
00085 break;
00086 #endif
00087 case S_IFREG:
00088 outbuf[i] = '-';
00089 break;
00090 case S_IFBLK:
00091 outbuf[i] = 'b';
00092 break;
00093 case S_IFDIR:
00094 outbuf[i] = 'd';
00095 break;
00096 #ifdef S_IFDOOR
00097 case S_IFDOOR:
00098 outbuf[i] = 'D';
00099 break;
00100 #endif
00101 case S_IFCHR:
00102 outbuf[i] = 'c';
00103 break;
00104 #ifdef S_IFIFO
00105 case S_IFIFO:
00106 outbuf[i] = 'p';
00107 break;
00108 #endif
00109 }
00110
00111 i++;
00112 if ((fmode & S_IRUSR) != 0)
00113 outbuf[i] = 'r';
00114 i++;
00115 if ((fmode & S_IWUSR) != 0)
00116 outbuf[i] = 'w';
00117 i++;
00118 if ((fmode & S_IXUSR) != 0)
00119 outbuf[i] = 'x';
00120 i++;
00121
00122 if ((fmode & S_IRGRP) != 0)
00123 outbuf[i] = 'r';
00124 i++;
00125 if ((fmode & S_IWGRP) != 0)
00126 outbuf[i] = 'w';
00127 i++;
00128 if ((fmode & S_IXGRP) != 0)
00129 outbuf[i] = 'x';
00130 i++;
00131
00132 if ((fmode & S_IROTH) != 0)
00133 outbuf[i] = 'r';
00134 i++;
00135 if ((fmode & S_IWOTH) != 0)
00136 outbuf[i] = 'w';
00137 i++;
00138 if ((fmode & S_IXOTH) != 0)
00139 outbuf[i] = 'x';
00140 i++;
00141
00142 outbuf[i] = '\0';
00143
00144 if ((fmode & S_ISUID) != 0) {
00145 if (outbuf[3] == 'x')
00146 outbuf[3] = 's';
00147 else
00148 outbuf[3] = 'S';
00149 }
00150
00151
00152 if ((fmode & S_ISGID) != 0) {
00153 if (outbuf[6] == 'x')
00154 outbuf[6] = 's';
00155 else
00156 outbuf[6] = 'l';
00157 }
00158
00159 if ((fmode & S_ISVTX) != 0) {
00160 if (outbuf[9] == 'x')
00161 outbuf[9] = 't';
00162 else
00163 outbuf[9] = 'T';
00164 }
00165
00166 return outbuf;
00167 }
00168
00169
00170
00171 static NODE *
00172 do_stat(tree)
00173 NODE *tree;
00174 {
00175 NODE *file, *array;
00176 struct stat sbuf;
00177 int ret;
00178 NODE **aptr;
00179 char *pmode;
00180 char *type = "unknown";
00181
00182
00183 if (tree->param_cnt != 2)
00184 fatal(
00185 "stat: called with incorrect number of arguments (%d), should be 2",
00186 tree->param_cnt);
00187
00188
00189 file = get_argument(tree, 0);
00190 array = get_argument(tree, 1);
00191
00192 array = get_array(array);
00193
00194
00195 assoc_clear(array);
00196
00197
00198 (void) force_string(file);
00199 ret = lstat(file->stptr, & sbuf);
00200 if (ret < 0) {
00201 update_ERRNO();
00202
00203 set_value(tmp_number((AWKNUM) ret));
00204
00205 free_temp(file);
00206 return tmp_number((AWKNUM) 0);
00207 }
00208
00209
00210 aptr = assoc_lookup(array, tmp_string("name", 4), FALSE);
00211 *aptr = dupnode(file);
00212
00213 aptr = assoc_lookup(array, tmp_string("dev", 3), FALSE);
00214 *aptr = make_number((AWKNUM) sbuf.st_dev);
00215
00216 aptr = assoc_lookup(array, tmp_string("ino", 3), FALSE);
00217 *aptr = make_number((AWKNUM) sbuf.st_ino);
00218
00219 aptr = assoc_lookup(array, tmp_string("mode", 4), FALSE);
00220 *aptr = make_number((AWKNUM) sbuf.st_mode);
00221
00222 aptr = assoc_lookup(array, tmp_string("nlink", 5), FALSE);
00223 *aptr = make_number((AWKNUM) sbuf.st_nlink);
00224
00225 aptr = assoc_lookup(array, tmp_string("uid", 3), FALSE);
00226 *aptr = make_number((AWKNUM) sbuf.st_uid);
00227
00228 aptr = assoc_lookup(array, tmp_string("gid", 3), FALSE);
00229 *aptr = make_number((AWKNUM) sbuf.st_gid);
00230
00231 aptr = assoc_lookup(array, tmp_string("size", 4), FALSE);
00232 *aptr = make_number((AWKNUM) sbuf.st_size);
00233
00234 aptr = assoc_lookup(array, tmp_string("blocks", 6), FALSE);
00235 *aptr = make_number((AWKNUM) sbuf.st_blocks);
00236
00237 aptr = assoc_lookup(array, tmp_string("atime", 5), FALSE);
00238 *aptr = make_number((AWKNUM) sbuf.st_atime);
00239
00240 aptr = assoc_lookup(array, tmp_string("mtime", 5), FALSE);
00241 *aptr = make_number((AWKNUM) sbuf.st_mtime);
00242
00243 aptr = assoc_lookup(array, tmp_string("ctime", 5), FALSE);
00244 *aptr = make_number((AWKNUM) sbuf.st_ctime);
00245
00246
00247 if (S_ISBLK(sbuf.st_mode) || S_ISCHR(sbuf.st_mode)) {
00248 aptr = assoc_lookup(array, tmp_string("rdev", 4), FALSE);
00249 *aptr = make_number((AWKNUM) sbuf.st_rdev);
00250
00251 aptr = assoc_lookup(array, tmp_string("major", 5), FALSE);
00252 *aptr = make_number((AWKNUM) major(sbuf.st_rdev));
00253
00254 aptr = assoc_lookup(array, tmp_string("minor", 5), FALSE);
00255 *aptr = make_number((AWKNUM) minor(sbuf.st_rdev));
00256 }
00257
00258 #ifdef HAVE_ST_BLKSIZE
00259 aptr = assoc_lookup(array, tmp_string("blksize", 7), FALSE);
00260 *aptr = make_number((AWKNUM) sbuf.st_blksize);
00261 #endif
00262
00263 aptr = assoc_lookup(array, tmp_string("pmode", 5), FALSE);
00264 pmode = format_mode(sbuf.st_mode);
00265 *aptr = make_string(pmode, strlen(pmode));
00266
00267
00268 if (S_ISLNK(sbuf.st_mode)) {
00269 char buf[BUFSIZ*2];
00270 int linksize;
00271
00272 linksize = readlink(file->stptr, buf, sizeof buf);
00273
00274 if (linksize == sizeof(buf))
00275 fatal("size of symbolic link too big");
00276 buf[linksize] = '\0';
00277
00278 aptr = assoc_lookup(array, tmp_string("linkval", 7), FALSE);
00279 *aptr = make_string(buf, linksize);
00280 }
00281
00282
00283 switch (sbuf.st_mode & S_IFMT) {
00284 #ifdef S_IFSOCK
00285 case S_IFSOCK:
00286 type = "socket";
00287 break;
00288 #endif
00289 #ifdef S_IFLNK
00290 case S_IFLNK:
00291 type = "symlink";
00292 break;
00293 #endif
00294 case S_IFREG:
00295 type = "file";
00296 break;
00297 case S_IFBLK:
00298 type = "blockdev";
00299 break;
00300 case S_IFDIR:
00301 type = "directory";
00302 break;
00303 #ifdef S_IFDOOR
00304 case S_IFDOOR:
00305 type = "door";
00306 break;
00307 #endif
00308 case S_IFCHR:
00309 type = "chardev";
00310 break;
00311 #ifdef S_IFIFO
00312 case S_IFIFO:
00313 type = "fifo";
00314 break;
00315 #endif
00316 }
00317
00318 aptr = assoc_lookup(array, tmp_string("type", 4), FALSE);
00319 *aptr = make_string(type, strlen(type));
00320
00321 free_temp(file);
00322
00323
00324 set_value(tmp_number((AWKNUM) ret));
00325
00326
00327 return tmp_number((AWKNUM) 0);
00328 }
00329
00330
00331
00332 NODE *
00333 dlload(tree, dl)
00334 NODE *tree;
00335 void *dl;
00336 {
00337 make_builtin("chdir", do_chdir, 1);
00338 make_builtin("stat", do_stat, 2);
00339
00340 return tmp_number((AWKNUM) 0);
00341 }