1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
109
112
113
117
118
122
123
127
128
132
133
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
222
234
235
239
240
241
242
243
244
247
248
249
250
251
252
253
254
255
256
257
260
264
267
271
276
277
278
279
280
281
282
283
284
285
288
289
305
306
307
308
309
310
311
312
313
314
315
318
321
322
323
324
325
326
327
328
329
330
331
334
335
336
337
338
339
340
341
342
343
344
345
348
351
352
353
354
355
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
393
397
407
408
409
412
413
422
423
424
430
431
432
433
434
435
436
437
438
439
440
441
447
448
452
453
457
458
459
460
461
462
463
466
467
468
469
473
474
475
476
477
478
482
483
498
499
500
501
502
503
504
505
506
507
514
515
516
517
518
519
520
521
522
523
524
525
526
533
534
535
538
542
543
552
553
554
555
556
557
558
559
560
561
562
563
564
565
570
571
572
573
574
575
576
577
578
579
582
583
584
585
586
587
588
589
590
591
592
593
601
602
603
604
605
610
611
616
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
642
643
644
645
646
649
652
653
658
659
660
661
662
663
673
674
675
676
677
678
679
683
684
685
686
687
688
689
690
691
692
693
696
697
698
699
700
703
704
705
706
716
717
719
720
721
722
723
724
725
726
733
736
737
738
739
740
741
742
743
744
745
752
755
756
757
758
759
760
764
765
766
767
768
769
772
773
774
775
776
777
778
779
780
781
784
785
786
787
788
789
790
791
792
793
796
797
798
799
800
801
802
803
804
805
806
809
810
811
812
813
814
815
816
817
818
819
820
821
822
827
828
829
830
831
832
833
834
835
836
837
840
841
842
843
844
845
846
847
848
849
852
853
854
855
856
857
858
867
868
869
876
883
884
891
892
899
906
913
920
927
934
941
948
955
962
969
976
983
990
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1076
1077
1078
1079
1080
1081
1082
1086
1087
1088
1089
1094
1095
1096
1097
1098
1099
1100
1101
1106
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
/* ... */
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <jimautoconf.h>
#include <jim-subcmd.h>
#include <jimiocompat.h>
8 includes
#ifdef HAVE_UTIMES
#include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#elif defined(_MSC_VER)
#include <direct.h>
#define F_OK 0
#define W_OK 2
#define R_OK 4
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
5 defines#endif/* ... */
# ifndef MAXPATHLEN
# define MAXPATHLEN JIM_PATH_LEN
# endif
#if defined(__MINGW32__) || defined(__MSYS__) || defined(_MSC_VER)
#define ISWINDOWS 1
#else
#define ISWINDOWS 0
#endif
#if defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
#define STAT_MTIME_US(STAT) ((STAT).st_mtimespec.tv_sec * 1000000ll + (STAT).st_mtimespec.tv_nsec / 1000)
#elif defined(HAVE_STRUCT_STAT_ST_MTIM)
#define STAT_MTIME_US(STAT) ((STAT).st_mtim.tv_sec * 1000000ll + (STAT).st_mtim.tv_nsec / 1000)
#endif
/* ... */
static const char *JimGetFileType(int mode)
{
if (S_ISREG(mode)) {
return "file";
}if (S_ISREG(mode)) { ... }
else if (S_ISDIR(mode)) {
return "directory";
}else if (S_ISDIR(mode)) { ... }
#ifdef S_ISCHR
else if (S_ISCHR(mode)) {
return "characterSpecial";
}else if (S_ISCHR(mode)) { ... }
/* ... */#endif
#ifdef S_ISBLK
else if (S_ISBLK(mode)) {
return "blockSpecial";
}else if (S_ISBLK(mode)) { ... }
/* ... */#endif
#ifdef S_ISFIFO
else if (S_ISFIFO(mode)) {
return "fifo";
}else if (S_ISFIFO(mode)) { ... }
/* ... */#endif
#ifdef S_ISLNK
else if (S_ISLNK(mode)) {
return "link";
}else if (S_ISLNK(mode)) { ... }
/* ... */#endif
#ifdef S_ISSOCK
else if (S_ISSOCK(mode)) {
return "socket";
}else if (S_ISSOCK(mode)) { ... }
/* ... */#endif
return "unknown";
}{ ... }
/* ... */
static void AppendStatElement(Jim_Interp *interp, Jim_Obj *listObj, const char *key, jim_wide value)
{
Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, key, -1));
Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, value));
}{ ... }
static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const jim_stat_t *sb)
{
Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
AppendStatElement(interp, listObj, "dev", sb->st_dev);
AppendStatElement(interp, listObj, "ino", sb->st_ino);
AppendStatElement(interp, listObj, "mode", sb->st_mode);
AppendStatElement(interp, listObj, "nlink", sb->st_nlink);
AppendStatElement(interp, listObj, "uid", sb->st_uid);
AppendStatElement(interp, listObj, "gid", sb->st_gid);
AppendStatElement(interp, listObj, "size", sb->st_size);
AppendStatElement(interp, listObj, "atime", sb->st_atime);
AppendStatElement(interp, listObj, "mtime", sb->st_mtime);
AppendStatElement(interp, listObj, "ctime", sb->st_ctime);
#ifdef STAT_MTIME_US
AppendStatElement(interp, listObj, "mtimeus", STAT_MTIME_US(*sb));
#endif
Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "type", -1));
Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, JimGetFileType((int)sb->st_mode), -1));
if (varName) {
Jim_Obj *objPtr;
objPtr = Jim_GetVariable(interp, varName, JIM_NONE);
if (objPtr) {
Jim_Obj *objv[2];
objv[0] = objPtr;
objv[1] = listObj;
objPtr = Jim_DictMerge(interp, 2, objv);
if (objPtr == NULL) {
Jim_SetResultFormatted(interp, "can't set \"%#s(dev)\": variable isn't array", varName);
Jim_FreeNewObj(interp, listObj);
return JIM_ERR;
}if (objPtr == NULL) { ... }
Jim_InvalidateStringRep(objPtr);
Jim_FreeNewObj(interp, listObj);
listObj = objPtr;
}if (objPtr) { ... }
Jim_SetVariable(interp, varName, listObj);
}if (varName) { ... }
Jim_SetResult(interp, listObj);
return JIM_OK;
}{ ... }
/* ... */
static int JimPathLenNoTrailingSlashes(const char *path, int len)
{
int i;
for (i = len; i > 1 && path[i - 1] == '/'; i--) {
if (ISWINDOWS && path[i - 2] == ':') {
break;
}if (ISWINDOWS && path[i - 2] == ':') { ... }
}for (i = len; i > 1 && path[i - 1] == '/'; i--) { ... }
return i;
}{ ... }
/* ... */
static Jim_Obj *JimStripTrailingSlashes(Jim_Interp *interp, Jim_Obj *objPtr)
{
int len = Jim_Length(objPtr);
const char *path = Jim_String(objPtr);
int i = JimPathLenNoTrailingSlashes(path, len);
if (i != len) {
objPtr = Jim_NewStringObj(interp, path, i);
}if (i != len) { ... }
Jim_IncrRefCount(objPtr);
return objPtr;
}{ ... }
static int file_cmd_dirname(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_Obj *objPtr = JimStripTrailingSlashes(interp, argv[0]);
const char *path = Jim_String(objPtr);
const char *p = strrchr(path, '/');
if (!p) {
Jim_SetResultString(interp, ".", -1);
}if (!p) { ... }
else if (p[1] == 0) {
Jim_SetResult(interp, objPtr);
}else if (p[1] == 0) { ... }
else if (p == path) {
Jim_SetResultString(interp, "/", -1);
}else if (p == path) { ... }
else if (ISWINDOWS && p[-1] == ':') {
Jim_SetResultString(interp, path, p - path + 1);
}else if (ISWINDOWS && p[-1] == ':') { ... }
else {
int len = JimPathLenNoTrailingSlashes(path, p - path);
Jim_SetResultString(interp, path, len);
}else { ... }
Jim_DecrRefCount(interp, objPtr);
return JIM_OK;
}{ ... }
static int file_cmd_split(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
const char *path = Jim_String(argv[0]);
if (*path == '/') {
Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "/", 1));
}if (*path == '/') { ... }
while (1) {
while (*path == '/') {
path++;
}while (*path == '/') { ... }
if (*path) {
const char *pt = strchr(path, '/');
if (pt) {
Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, path, pt - path));
path = pt;
continue;
}if (pt) { ... }
Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, path, -1));
}if (*path) { ... }
break;
}while (1) { ... }
Jim_SetResult(interp, listObj);
return JIM_OK;
}{ ... }
static int file_cmd_rootname(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
const char *path = Jim_String(argv[0]);
const char *lastSlash = strrchr(path, '/');
const char *p = strrchr(path, '.');
if (p == NULL || (lastSlash != NULL && lastSlash > p)) {
Jim_SetResult(interp, argv[0]);
}if (p == NULL || (lastSlash != NULL && lastSlash > p)) { ... }
else {
Jim_SetResultString(interp, path, p - path);
}else { ... }
return JIM_OK;
}{ ... }
static int file_cmd_extension(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_Obj *objPtr = JimStripTrailingSlashes(interp, argv[0]);
const char *path = Jim_String(objPtr);
const char *lastSlash = strrchr(path, '/');
const char *p = strrchr(path, '.');
if (p == NULL || (lastSlash != NULL && lastSlash >= p)) {
p = "";
}if (p == NULL || (lastSlash != NULL && lastSlash >= p)) { ... }
Jim_SetResultString(interp, p, -1);
Jim_DecrRefCount(interp, objPtr);
return JIM_OK;
}{ ... }
static int file_cmd_tail(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_Obj *objPtr = JimStripTrailingSlashes(interp, argv[0]);
const char *path = Jim_String(objPtr);
const char *lastSlash = strrchr(path, '/');
if (lastSlash) {
Jim_SetResultString(interp, lastSlash + 1, -1);
}if (lastSlash) { ... }
else {
Jim_SetResult(interp, objPtr);
}else { ... }
Jim_DecrRefCount(interp, objPtr);
return JIM_OK;
}{ ... }
static int file_cmd_normalize(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
#ifdef HAVE_REALPATH
const char *path = Jim_String(argv[0]);
char *newname = Jim_Alloc(MAXPATHLEN + 1);
if (realpath(path, newname)) {
Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, -1));
return JIM_OK;
}if (realpath(path, newname)) { ... }
else {
Jim_Free(newname);
Jim_SetResultFormatted(interp, "can't normalize \"%#s\": %s", argv[0], strerror(errno));
return JIM_ERR;
}else { ... }
/* ... */#else
Jim_SetResultString(interp, "Not implemented", -1);
return JIM_ERR;/* ... */
#endif
}{ ... }
static int file_cmd_join(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
int i;
char *newname = Jim_Alloc(MAXPATHLEN + 1);
char *last = newname;
*newname = 0;
for (i = 0; i < argc; i++) {
int len;
const char *part = Jim_GetString(argv[i], &len);
if (*part == '/') {
last = newname;
}if (*part == '/') { ... }
else if (ISWINDOWS && strchr(part, ':')) {
last = newname;
}else if (ISWINDOWS && strchr(part, ':')) { ... }
else if (part[0] == '.') {
if (part[1] == '/') {
part += 2;
len -= 2;
}if (part[1] == '/') { ... }
else if (part[1] == 0 && last != newname) {
continue;
}else if (part[1] == 0 && last != newname) { ... }
}else if (part[0] == '.') { ... }
if (last != newname && last[-1] != '/') {
*last++ = '/';
}if (last != newname && last[-1] != '/') { ... }
if (len) {
if (last + len - newname >= MAXPATHLEN) {
Jim_Free(newname);
Jim_SetResultString(interp, "Path too long", -1);
return JIM_ERR;
}if (last + len - newname >= MAXPATHLEN) { ... }
memcpy(last, part, len);
last += len;
}if (len) { ... }
if (last > newname + 1 && last[-1] == '/') {
if (!ISWINDOWS || !(last > newname + 2 && last[-2] == ':')) {
*--last = 0;
}if (!ISWINDOWS || !(last > newname + 2 && last[-2] == ':')) { ... }
}if (last > newname + 1 && last[-1] == '/') { ... }
}for (i = 0; i < argc; i++) { ... }
*last = 0;
Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, last - newname));
return JIM_OK;
}{ ... }
static int file_access(Jim_Interp *interp, Jim_Obj *filename, int mode)
{
Jim_SetResultBool(interp, access(Jim_String(filename), mode) != -1);
return JIM_OK;
}{ ... }
static int file_cmd_readable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
return file_access(interp, argv[0], R_OK);
}{ ... }
static int file_cmd_writable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
return file_access(interp, argv[0], W_OK);
}{ ... }
static int file_cmd_executable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
#ifdef X_OK
return file_access(interp, argv[0], X_OK);
#else
Jim_SetResultBool(interp, 1);
return JIM_OK;/* ... */
#endif
}{ ... }
static int file_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
return file_access(interp, argv[0], F_OK);
}{ ... }
static int file_cmd_delete(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
int force = Jim_CompareStringImmediate(interp, argv[0], "-force");
if (force || Jim_CompareStringImmediate(interp, argv[0], "--")) {
argc++;
argv--;
}if (force || Jim_CompareStringImmediate(interp, argv[0], "--")) { ... }
while (argc--) {
const char *path = Jim_String(argv[0]);
if (unlink(path) == -1 && errno != ENOENT) {
if (rmdir(path) == -1) {
if (!force || Jim_EvalPrefix(interp, "file delete force", 1, argv) != JIM_OK) {
Jim_SetResultFormatted(interp, "couldn't delete file \"%s\": %s", path,
strerror(errno));
return JIM_ERR;
}if (!force || Jim_EvalPrefix(interp, "file delete force", 1, argv) != JIM_OK) { ... }
}if (rmdir(path) == -1) { ... }
}if (unlink(path) == -1 && errno != ENOENT) { ... }
argv++;
}while (argc--) { ... }
return JIM_OK;
}{ ... }
#ifdef HAVE_MKDIR_ONE_ARG
#define MKDIR_DEFAULT(PATHNAME) mkdir(PATHNAME)
#else
#define MKDIR_DEFAULT(PATHNAME) mkdir(PATHNAME, 0755)
#endif
/* ... */
static int mkdir_all(char *path)
{
int ok = 1;
goto first;
while (ok--) {
{
char *slash = strrchr(path, '/');
if (slash && slash != path) {
*slash = 0;
if (mkdir_all(path) != 0) {
return -1;
}if (mkdir_all(path) != 0) { ... }
*slash = '/';
}if (slash && slash != path) { ... }
}while (ok--) { ... }
first:
if (MKDIR_DEFAULT(path) == 0) {
return 0;
}if (MKDIR_DEFAULT(path) == 0) { ... }
if (errno == ENOENT) {
continue;
}if (errno == ENOENT) { ... }
if (errno == EEXIST) {
jim_stat_t sb;
if (Jim_Stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
return 0;
}if (Jim_Stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { ... }
errno = EEXIST;
}if (errno == EEXIST) { ... }
break;
}while (ok--) { ... }
return -1;
}{ ... }
static int file_cmd_mkdir(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
while (argc--) {
char *path = Jim_StrDup(Jim_String(argv[0]));
int rc = mkdir_all(path);
Jim_Free(path);
if (rc != 0) {
Jim_SetResultFormatted(interp, "can't create directory \"%#s\": %s", argv[0],
strerror(errno));
return JIM_ERR;
}if (rc != 0) { ... }
argv++;
}while (argc--) { ... }
return JIM_OK;
}{ ... }
static int file_cmd_tempfile(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
int fd = Jim_MakeTempFile(interp, (argc >= 1) ? Jim_String(argv[0]) : NULL, 0);
if (fd < 0) {
return JIM_ERR;
}if (fd < 0) { ... }
close(fd);
return JIM_OK;
}{ ... }
static int file_cmd_rename(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
const char *source;
const char *dest;
int force = 0;
if (argc == 3) {
if (!Jim_CompareStringImmediate(interp, argv[0], "-force")) {
return -1;
}if (!Jim_CompareStringImmediate(interp, argv[0], "-force")) { ... }
force++;
argv++;
argc--;
}if (argc == 3) { ... }
source = Jim_String(argv[0]);
dest = Jim_String(argv[1]);
if (!force && access(dest, F_OK) == 0) {
Jim_SetResultFormatted(interp, "error renaming \"%#s\" to \"%#s\": target exists", argv[0],
argv[1]);
return JIM_ERR;
}if (!force && access(dest, F_OK) == 0) { ... }
#if ISWINDOWS
if (access(dest, F_OK) == 0) {
remove(dest);
}if (access(dest, F_OK) == 0) { ... }
/* ... */#endif
if (rename(source, dest) != 0) {
Jim_SetResultFormatted(interp, "error renaming \"%#s\" to \"%#s\": %s", argv[0], argv[1],
strerror(errno));
return JIM_ERR;
}if (rename(source, dest) != 0) { ... }
return JIM_OK;
}{ ... }
#if defined(HAVE_LINK) && defined(HAVE_SYMLINK)
static int file_cmd_link(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
int ret;
const char *source;
const char *dest;
static const char * const options[] = { "-hard", "-symbolic", NULL };
enum { OPT_HARD, OPT_SYMBOLIC, };
int option = OPT_HARD;
if (argc == 3) {
if (Jim_GetEnum(interp, argv[0], options, &option, NULL, JIM_ENUM_ABBREV | JIM_ERRMSG) != JIM_OK) {
return JIM_ERR;
}if (Jim_GetEnum(interp, argv[0], options, &option, NULL, JIM_ENUM_ABBREV | JIM_ERRMSG) != JIM_OK) { ... }
argv++;
argc--;
}if (argc == 3) { ... }
dest = Jim_String(argv[0]);
source = Jim_String(argv[1]);
if (option == OPT_HARD) {
ret = link(source, dest);
}if (option == OPT_HARD) { ... }
else {
ret = symlink(source, dest);
}else { ... }
if (ret != 0) {
Jim_SetResultFormatted(interp, "error linking \"%#s\" to \"%#s\": %s", argv[0], argv[1],
strerror(errno));
return JIM_ERR;
}if (ret != 0) { ... }
return JIM_OK;
}file_cmd_link (Jim_Interp *interp, int argc, Jim_Obj *const *argv) { ... }
/* ... */#endif
static int file_stat(Jim_Interp *interp, Jim_Obj *filename, jim_stat_t *sb)
{
const char *path = Jim_String(filename);
if (Jim_Stat(path, sb) == -1) {
Jim_SetResultFormatted(interp, "could not read \"%#s\": %s", filename, strerror(errno));
return JIM_ERR;
}if (Jim_Stat(path, sb) == -1) { ... }
return JIM_OK;
}{ ... }
#ifdef HAVE_LSTAT
static int file_lstat(Jim_Interp *interp, Jim_Obj *filename, jim_stat_t *sb)
{
const char *path = Jim_String(filename);
if (lstat(path, sb) == -1) {
Jim_SetResultFormatted(interp, "could not read \"%#s\": %s", filename, strerror(errno));
return JIM_ERR;
}if (lstat(path, sb) == -1) { ... }
return JIM_OK;
}file_lstat (Jim_Interp *interp, Jim_Obj *filename, jim_stat_t *sb) { ... }
/* ... */#else
#define file_lstat file_stat
#endif
static int file_cmd_atime(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
jim_stat_t sb;
if (file_stat(interp, argv[0], &sb) != JIM_OK) {
return JIM_ERR;
}if (file_stat(interp, argv[0], &sb) != JIM_OK) { ... }
Jim_SetResultInt(interp, sb.st_atime);
return JIM_OK;
}{ ... }
/* ... */
static int JimSetFileTimes(Jim_Interp *interp, const char *filename, jim_wide us)
{
#ifdef HAVE_UTIMES
struct timeval times[2];
times[1].tv_sec = times[0].tv_sec = us / 1000000;
times[1].tv_usec = times[0].tv_usec = us % 1000000;
if (utimes(filename, times) != 0) {
Jim_SetResultFormatted(interp, "can't set time on \"%s\": %s", filename, strerror(errno));
return JIM_ERR;
}if (utimes(filename, times) != 0) { ... }
return JIM_OK;/* ... */
#else
Jim_SetResultString(interp, "Not implemented", -1);
return JIM_ERR;/* ... */
#endif
}{ ... }
static int file_cmd_mtime(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
jim_stat_t sb;
if (argc == 2) {
jim_wide secs;
if (Jim_GetWide(interp, argv[1], &secs) != JIM_OK) {
return JIM_ERR;
}if (Jim_GetWide(interp, argv[1], &secs) != JIM_OK) { ... }
return JimSetFileTimes(interp, Jim_String(argv[0]), secs * 1000000);
}if (argc == 2) { ... }
if (file_stat(interp, argv[0], &sb) != JIM_OK) {
return JIM_ERR;
}if (file_stat(interp, argv[0], &sb) != JIM_OK) { ... }
Jim_SetResultInt(interp, sb.st_mtime);
return JIM_OK;
}{ ... }
#ifdef STAT_MTIME_US
static int file_cmd_mtimeus(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
jim_stat_t sb;
if (argc == 2) {
jim_wide us;
if (Jim_GetWide(interp, argv[1], &us) != JIM_OK) {
return JIM_ERR;
}if (Jim_GetWide(interp, argv[1], &us) != JIM_OK) { ... }
return JimSetFileTimes(interp, Jim_String(argv[0]), us);
}if (argc == 2) { ... }
if (file_stat(interp, argv[0], &sb) != JIM_OK) {
return JIM_ERR;
}if (file_stat(interp, argv[0], &sb) != JIM_OK) { ... }
Jim_SetResultInt(interp, STAT_MTIME_US(sb));
return JIM_OK;
}file_cmd_mtimeus (Jim_Interp *interp, int argc, Jim_Obj *const *argv) { ... }
/* ... */#endif
static int file_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
return Jim_EvalPrefix(interp, "file copy", argc, argv);
}{ ... }
static int file_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
jim_stat_t sb;
if (file_stat(interp, argv[0], &sb) != JIM_OK) {
return JIM_ERR;
}if (file_stat(interp, argv[0], &sb) != JIM_OK) { ... }
Jim_SetResultInt(interp, sb.st_size);
return JIM_OK;
}{ ... }
static int file_cmd_isdirectory(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
jim_stat_t sb;
int ret = 0;
if (file_stat(interp, argv[0], &sb) == JIM_OK) {
ret = S_ISDIR(sb.st_mode);
}if (file_stat(interp, argv[0], &sb) == JIM_OK) { ... }
Jim_SetResultInt(interp, ret);
return JIM_OK;
}{ ... }
static int file_cmd_isfile(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
jim_stat_t sb;
int ret = 0;
if (file_stat(interp, argv[0], &sb) == JIM_OK) {
ret = S_ISREG(sb.st_mode);
}if (file_stat(interp, argv[0], &sb) == JIM_OK) { ... }
Jim_SetResultInt(interp, ret);
return JIM_OK;
}{ ... }
#ifdef HAVE_GETEUID
static int file_cmd_owned(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
jim_stat_t sb;
int ret = 0;
if (file_stat(interp, argv[0], &sb) == JIM_OK) {
ret = (geteuid() == sb.st_uid);
}if (file_stat(interp, argv[0], &sb) == JIM_OK) { ... }
Jim_SetResultInt(interp, ret);
return JIM_OK;
}file_cmd_owned (Jim_Interp *interp, int argc, Jim_Obj *const *argv) { ... }
/* ... */#endif
#if defined(HAVE_READLINK)
static int file_cmd_readlink(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
const char *path = Jim_String(argv[0]);
char *linkValue = Jim_Alloc(MAXPATHLEN + 1);
int linkLength = readlink(path, linkValue, MAXPATHLEN);
if (linkLength == -1) {
Jim_Free(linkValue);
Jim_SetResultFormatted(interp, "could not read link \"%#s\": %s", argv[0], strerror(errno));
return JIM_ERR;
}if (linkLength == -1) { ... }
linkValue[linkLength] = 0;
Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, linkValue, linkLength));
return JIM_OK;
}file_cmd_readlink (Jim_Interp *interp, int argc, Jim_Obj *const *argv) { ... }
/* ... */#endif
static int file_cmd_type(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
jim_stat_t sb;
if (file_lstat(interp, argv[0], &sb) != JIM_OK) {
return JIM_ERR;
}if (file_lstat(interp, argv[0], &sb) != JIM_OK) { ... }
Jim_SetResultString(interp, JimGetFileType((int)sb.st_mode), -1);
return JIM_OK;
}{ ... }
#ifdef HAVE_LSTAT
static int file_cmd_lstat(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
jim_stat_t sb;
if (file_lstat(interp, argv[0], &sb) != JIM_OK) {
return JIM_ERR;
}if (file_lstat(interp, argv[0], &sb) != JIM_OK) { ... }
return StoreStatData(interp, argc == 2 ? argv[1] : NULL, &sb);
}file_cmd_lstat (Jim_Interp *interp, int argc, Jim_Obj *const *argv) { ... }
/* ... */#else
#define file_cmd_lstat file_cmd_stat
#endif
static int file_cmd_stat(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
jim_stat_t sb;
if (file_stat(interp, argv[0], &sb) != JIM_OK) {
return JIM_ERR;
}if (file_stat(interp, argv[0], &sb) != JIM_OK) { ... }
return StoreStatData(interp, argc == 2 ? argv[1] : NULL, &sb);
}{ ... }
static const jim_subcmd_type file_command_table[] = {
{ "atime",
"name",
file_cmd_atime,
1,
1,
...},
{ "mtime",
"name ?time?",
file_cmd_mtime,
1,
2,
...},
#ifdef STAT_MTIME_US
{ "mtimeus",
"name ?time?",
file_cmd_mtimeus,
1,
2,
...},/* ... */
#endif
{ "copy",
"?-force? source dest",
file_cmd_copy,
2,
3,
...},
{ "dirname",
"name",
file_cmd_dirname,
1,
1,
...},
{ "rootname",
"name",
file_cmd_rootname,
1,
1,
...},
{ "extension",
"name",
file_cmd_extension,
1,
1,
...},
{ "tail",
"name",
file_cmd_tail,
1,
1,
...},
{ "split",
"name",
file_cmd_split,
1,
1,
...},
{ "normalize",
"name",
file_cmd_normalize,
1,
1,
...},
{ "join",
"name ?name ...?",
file_cmd_join,
1,
-1,
...},
{ "readable",
"name",
file_cmd_readable,
1,
1,
...},
{ "writable",
"name",
file_cmd_writable,
1,
1,
...},
{ "executable",
"name",
file_cmd_executable,
1,
1,
...},
{ "exists",
"name",
file_cmd_exists,
1,
1,
...},
{ "delete",
"?-force|--? name ...",
file_cmd_delete,
1,
-1,
...},
{ "mkdir",
"dir ...",
file_cmd_mkdir,
1,
-1,
...},
{ "tempfile",
"?template?",
file_cmd_tempfile,
0,
1,
...},
{ "rename",
"?-force? source dest",
file_cmd_rename,
2,
3,
...},
#if defined(HAVE_LINK) && defined(HAVE_SYMLINK)
{ "link",
"?-symbolic|-hard? newname target",
file_cmd_link,
2,
3,
}defined (HAVE_SYMLINK) { ... },
#endif
#if defined(HAVE_READLINK)
{ "readlink",
"name",
file_cmd_readlink,
1,
1,
}defined (HAVE_READLINK) { ... },
#endif
{ "size",
"name",
file_cmd_size,
1,
1,
...},
{ "stat",
"name ?var?",
file_cmd_stat,
1,
2,
...},
{ "lstat",
"name ?var?",
file_cmd_lstat,
1,
2,
...},
{ "type",
"name",
file_cmd_type,
1,
1,
...},
#ifdef HAVE_GETEUID
{ "owned",
"name",
file_cmd_owned,
1,
1,
...},/* ... */
#endif
{ "isdirectory",
"name",
file_cmd_isdirectory,
1,
1,
...},
{ "isfile",
"name",
file_cmd_isfile,
1,
1,
...},
{
NULL
...}
...};
static int Jim_CdCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
const char *path;
if (argc != 2) {
Jim_WrongNumArgs(interp, 1, argv, "dirname");
return JIM_ERR;
}if (argc != 2) { ... }
path = Jim_String(argv[1]);
if (chdir(path) != 0) {
Jim_SetResultFormatted(interp, "couldn't change working directory to \"%s\": %s", path,
strerror(errno));
return JIM_ERR;
}if (chdir(path) != 0) { ... }
return JIM_OK;
}{ ... }
static int Jim_PwdCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
char *cwd = Jim_Alloc(MAXPATHLEN);
if (getcwd(cwd, MAXPATHLEN) == NULL) {
Jim_SetResultString(interp, "Failed to get pwd", -1);
Jim_Free(cwd);
return JIM_ERR;
}if (getcwd(cwd, MAXPATHLEN) == NULL) { ... }
else if (ISWINDOWS) {
char *p = cwd;
while ((p = strchr(p, '\\')) != NULL) {
*p++ = '/';
}while ((p = strchr(p, '\\')) != NULL) { ... }
}else if (ISWINDOWS) { ... }
Jim_SetResultString(interp, cwd, -1);
Jim_Free(cwd);
return JIM_OK;
}{ ... }
int Jim_fileInit(Jim_Interp *interp)
{
Jim_PackageProvideCheck(interp, "file");
Jim_CreateCommand(interp, "file", Jim_SubCmdProc, (void *)file_command_table, NULL);
Jim_CreateCommand(interp, "pwd", Jim_PwdCmd, NULL, NULL);
Jim_CreateCommand(interp, "cd", Jim_CdCmd, NULL, NULL);
return JIM_OK;
}{ ... }