︙ | | |
66
67
68
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
66
67
68
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
return(syscall(SYS_pivot_root, new_root, put_old));
}
#endif
/*
* Simple hash routine to enable switching on a string to be implemented
*/
static unsigned long tclsystem_internal_simplehash(const void *databuf, int datalen) {
static unsigned long tuapi_internal_simplehash(const void *databuf, int datalen) {
unsigned long retval = 0;
const unsigned char *data;
data = databuf;
for (; datalen > 0; datalen--,data++) {
retval ^= (retval >> 25) & 0x7F;
retval <<= 7;
retval &= (0xFFFFFFFFUL);
retval ^= *data;
}
return(retval);
}
static unsigned long tclsystem_internal_simplehash_obj(Tcl_Obj *tcl_data) {
static unsigned long tuapi_internal_simplehash_obj(Tcl_Obj *tcl_data) {
unsigned long retval;
char *data;
int datalen = -1;
data = Tcl_GetStringFromObj(tcl_data, &datalen);
retval = tclsystem_internal_simplehash(data, datalen);
retval = tuapi_internal_simplehash(data, datalen);
return(retval);
}
#if 0
/* NOTUSED: Uncomment when needed: */
static unsigned long tclsystem_internal_simplehash_str(const char *data) {
static unsigned long tuapi_internal_simplehash_str(const char *data) {
unsigned long retval;
int datalen;
datalen = strlen(data);
retval = tclsystem_internal_simplehash(data, datalen);
retval = tuapi_internal_simplehash(data, datalen);
return(retval);
}
#endif
static int tclsystem_internalproc_simplehash(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_internalproc_simplehash(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
unsigned long hashval;
Tcl_Obj *hashval_obj;
if (objc != 2) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::internal::hash value\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::tuapi::internal::hash value\"", -1));
return(TCL_ERROR);
}
hashval = tclsystem_internal_simplehash_obj(objv[1]);
hashval = tuapi_internal_simplehash_obj(objv[1]);
hashval_obj = Tcl_NewObj();
Tcl_SetWideIntObj(hashval_obj, hashval);
Tcl_SetObjResult(interp, hashval_obj);
return(TCL_OK);
}
static int tclsystem_internal_getsock(int *sock_v4_out, int *sock_v6_out) {
static int tuapi_internal_getsock(int *sock_v4_out, int *sock_v6_out) {
int sock_v4 = -1, sock_v6 = -1;
int sock;
if (sock_v4_out == NULL && sock_v6_out == NULL) {
return(-1);
}
|
︙ | | |
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
-
+
-
+
|
/*
* Low-level System Call Wrapper Procedures
*
* These procedures should minimally wrap Linux or UNIX system calls to
* expose to the Tcl-level. Where possible accept symbolic names rather
* than numeric values (.e.g, list of values to OR together to get flags).
*/
static int tclsystem_mount(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_mount(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
Tcl_Obj *mountflags_obj, **mountflags_list, *mountflag;
int mountflags_list_len;
char *source, *target, *fstype;
unsigned long mountflags = 0;
void *data = NULL;
int mount_ret, tcl_ret;
if (objc < 5 || objc > 6) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::mount source target fstype mountflags ?data?\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::tuapi::syscall::mount source target fstype mountflags ?data?\"", -1));
return(TCL_ERROR);
}
source = Tcl_GetString(objv[1]);
target = Tcl_GetString(objv[2]);
fstype = Tcl_GetString(objv[3]);
|
︙ | | |
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
|
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
|
-
+
|
if (tcl_ret != TCL_OK) {
return(tcl_ret);
}
for (; mountflags_list_len > 0; mountflags_list_len--,mountflags_list++) {
mountflag = mountflags_list[0];
switch (tclsystem_internal_simplehash_obj(mountflag)) {
switch (tuapi_internal_simplehash_obj(mountflag)) {
#ifdef MS_BIND
case 0x8526744: /* BIND */
mountflags |= MS_BIND;
break;
#endif
#ifdef MS_DIRSYNC
case 0x2aff41c3: /* DIRSYNC */
|
︙ | | |
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
|
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
|
-
+
-
+
-
+
|
}
Tcl_SetObjResult(interp, Tcl_NewStringObj(target, -1));
return(TCL_OK);
}
static int tclsystem_umount(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_umount(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
Tcl_Obj **flags, *flag;
Tcl_Obj *pathname_obj;
char *pathname;
int umount2_flags = 0;
int flags_cnt;
int chk_ret, tcl_ret;
if (objc < 2 || objc > 3) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"system::syscall::umount dir ?flags?\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"tuapi::syscall::umount dir ?flags?\"", -1));
return(TCL_ERROR);
}
pathname_obj = objv[1];
pathname = Tcl_GetString(pathname_obj);
/* Set a default return value */
Tcl_SetObjResult(interp, pathname_obj);
if (objc == 3) {
tcl_ret = Tcl_ListObjGetElements(interp, objv[2], &flags_cnt, &flags);
if (tcl_ret != TCL_OK) {
return(tcl_ret);
}
for (; flags_cnt > 0; flags_cnt--,flags++) {
flag = flags[0];
switch (tclsystem_internal_simplehash_obj(flag)) {
switch (tuapi_internal_simplehash_obj(flag)) {
case 0x69f4a3c5: /* FORCE */
umount2_flags |= MNT_FORCE;
break;
case 0x5a9173c8: /* DETACH */
umount2_flags |= MNT_DETACH;
|
︙ | | |
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
|
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
|
-
+
-
+
-
+
-
+
-
+
-
+
|
return(TCL_ERROR);
}
return(TCL_OK);
}
static int tclsystem_swapon(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_swapon(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
char *pathname;
int chk_ret;
if (objc != 2) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"system::syscall::swapon pathname\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"tuapi::syscall::swapon pathname\"", -1));
return(TCL_ERROR);
}
pathname = Tcl_GetString(objv[1]);
chk_ret = swapon(pathname, 0);
if (chk_ret != 0) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(strerror(errno), -1));
return(TCL_ERROR);
}
return(TCL_OK);
}
static int tclsystem_swapoff(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_swapoff(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
char *pathname;
int chk_ret;
if (objc != 2) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"system::syscall::swapoff pathname\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"tuapi::syscall::swapoff pathname\"", -1));
return(TCL_ERROR);
}
pathname = Tcl_GetString(objv[1]);
chk_ret = swapoff(pathname);
if (chk_ret != 0) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(strerror(errno), -1));
return(TCL_ERROR);
}
return(TCL_OK);
}
static int tclsystem_insmod(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_insmod(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
Tcl_Channel fd;
Tcl_Obj *module_filename, *module_data;
void *module_data_val;
int module_data_len;
int read_ret, chk_ret;
if (objc < 2) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"system::syscall::insmod filename ?args ...?\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"tuapi::syscall::insmod filename ?args ...?\"", -1));
return(TCL_ERROR);
}
module_filename = objv[1];
fd = Tcl_FSOpenFileChannel(interp, module_filename, "r", 0600);
|
︙ | | |
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
|
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
|
-
+
-
+
-
+
|
return(TCL_ERROR);
}
return(TCL_OK);
}
static int tclsystem_rmmod(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_rmmod(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("not implemented", -1));
return(TCL_ERROR);
}
static int tclsystem_lsmod(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_lsmod(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("not implemented", -1));
return(TCL_ERROR);
}
static int tclsystem_hostname(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_hostname(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
char hostname[HOST_NAME_MAX + 1];
int chk_ret;
if (objc == 1) {
/* No arguments given, just return the hostname */
chk_ret = gethostname(hostname, sizeof(hostname));
if (chk_ret != 0) {
|
︙ | | |
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
|
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
|
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
}
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"hostname ?hostname?\"", -1));
return(TCL_ERROR);
}
static int tclsystem_domainname(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_domainname(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("not implemented", -1));
return(TCL_ERROR);
}
static int tclsystem_chroot(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_chroot(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
char *pathname;
int chk_ret;
if (objc != 2) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall:chroot pathname\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::tuapi::syscall:chroot pathname\"", -1));
return(TCL_ERROR);
}
pathname = Tcl_GetString(objv[1]);
chk_ret = chroot(pathname);
if (chk_ret != 0) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(strerror(errno), -1));
return(TCL_ERROR);
}
return(TCL_OK);
}
static int tclsystem_pivot_root(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_pivot_root(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
char *new_root, *put_old;
int chk_ret;
if (objc != 3) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::pivot_root new_root put_old\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::tuapi::syscall::pivot_root new_root put_old\"", -1));
return(TCL_ERROR);
}
new_root = Tcl_GetString(objv[1]);
put_old = Tcl_GetString(objv[2]);
chk_ret = pivot_root(new_root, put_old);
if (chk_ret != 0) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(strerror(errno), -1));
return(TCL_ERROR);
}
return(TCL_OK);
}
static int tclsystem_mknod(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_mknod(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("not implemented", -1));
return(TCL_ERROR);
}
static int tclsystem_getuid(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_getuid(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("not implemented", -1));
return(TCL_ERROR);
}
static int tclsystem_kill(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_kill(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
Tcl_Obj *signal_obj;
Tcl_WideInt pid_wide, sig_wide;
pid_t pid;
int sig;
int kill_ret, tcl_ret;
if (objc != 3) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::kill pid sig\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::tuapi::syscall::kill pid sig\"", -1));
return(TCL_ERROR);
}
tcl_ret = Tcl_GetWideIntFromObj(interp, objv[1], &pid_wide);
if (tcl_ret != TCL_OK) {
return(tcl_ret);
}
pid = pid_wide;
signal_obj = objv[2];
tcl_ret = Tcl_GetWideIntFromObj(interp, signal_obj, &sig_wide);
if (tcl_ret != TCL_OK) {
switch (tclsystem_internal_simplehash_obj(signal_obj)) {
switch (tuapi_internal_simplehash_obj(signal_obj)) {
case 0x122ad0: /* HUP */
case 0x98f364d0: /* SIGHUP */
sig = SIGHUP;
break;
case 0x126754: /* INT */
case 0x98f32954: /* SIGINT */
sig = SIGINT;
|
︙ | | |
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
|
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
|
-
+
-
+
-
+
|
return(TCL_ERROR);
}
return(TCL_OK);
}
static int tclsystem_ps(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_ps(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("not implemented", -1));
return(TCL_ERROR);
}
static int tclsystem_execve(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_execve(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
char **argv = NULL;
char *file;
int idx;
if (objc < 2) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::execve file ?args ...?\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::tuapi::syscall::execve file ?args ...?\"", -1));
return(TCL_ERROR);
}
/* Find executable */
file = Tcl_GetString(objv[1]);
|
︙ | | |
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
|
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
|
-
+
-
+
|
/* If the new image could not take over, something went wrong -- report error */
Tcl_SetObjResult(interp, Tcl_NewStringObj(strerror(errno), -1));
return(TCL_ERROR);
}
static int tclsystem_losetup(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_losetup(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
char *file, *loopdev;
int chk_ret;
int loopfd, filefd;
if (objc != 3) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::losetup loopdev file\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::tuapi::syscall::losetup loopdev file\"", -1));
return(TCL_ERROR);
}
loopdev = Tcl_GetString(objv[1]);
file = Tcl_GetString(objv[2]);
|
︙ | | |
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
|
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
|
-
+
|
return(TCL_ERROR);
}
return(TCL_OK);
}
static void tclsystem_private_append_sockaddr_to_tclobj(Tcl_Interp *interp, Tcl_Obj *list, char *header, struct sockaddr *addr) {
static void tuapi_private_append_sockaddr_to_tclobj(Tcl_Interp *interp, Tcl_Obj *list, char *header, struct sockaddr *addr) {
char addr_buf[INET6_ADDRSTRLEN + INET_ADDRSTRLEN + 1], *chk_inp;
switch (addr->sa_family) {
case AF_INET: /* IPv4 */
case AF_INET6: /* IPv6 */
switch (addr->sa_family) {
case AF_INET: /* IPv4 */
|
︙ | | |
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
|
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
|
-
+
|
break;
}
return;
}
static int tclsystem_private_get_sockaddr_from_obj(Tcl_Obj *value, void *target) {
static int tuapi_private_get_sockaddr_from_obj(Tcl_Obj *value, void *target) {
struct sockaddr_in local_v4;
struct sockaddr_in6 local_v6;
const char *addr_str;
int inetpton_ret;
addr_str = Tcl_GetString(value);
|
︙ | | |
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
|
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
|
-
+
|
return(0);
}
return(-1);
}
static int tclsystem_ifconfig_list(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int sock) {
static int tuapi_ifconfig_list(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int sock) {
Tcl_Obj *tcl_iface_list;
struct ifconf ifaces_cfg;
struct ifreq *iface_req = NULL;
int iface_req_cnt = 224, iface_req_len;
int idx, iface_cnt;
int ioctl_ret, tcl_ret;
|
︙ | | |
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
|
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
|
-
+
|
free(iface_req);
Tcl_SetObjResult(interp, tcl_iface_list);
return(TCL_OK);
}
static int tclsystem_ifconfig_info(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int sock, int sock_v4, int sock_v6) {
static int tuapi_ifconfig_info(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int sock, int sock_v4, int sock_v6) {
Tcl_Obj *retlist, *flags;
struct ifreq iface_req;
unsigned char *addr_data;
const char *link_encap;
const char *iface;
int flags_bitmask, flag_broadcast = 0, flag_pointopoint = 0;
int ioctl_ret;
|
︙ | | |
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
|
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
|
-
+
-
+
-
+
-
+
-
+
|
Tcl_ListObjAppendElement(interp, retlist, Tcl_NewStringObj("index", -1));
Tcl_ListObjAppendElement(interp, retlist, Tcl_NewWideIntObj(iface_req.ifr_ifindex));
}
if (sock_v4 != -1) {
ioctl_ret = ioctl(sock_v4, SIOCGIFADDR, &iface_req);
if (ioctl_ret == 0) {
tclsystem_private_append_sockaddr_to_tclobj(interp, retlist, "address", &iface_req.ifr_addr);
tuapi_private_append_sockaddr_to_tclobj(interp, retlist, "address", &iface_req.ifr_addr);
}
if (flag_pointopoint) {
/* Point-to-Point interfaces */
ioctl_ret = ioctl(sock_v4, SIOCGIFDSTADDR, &iface_req);
if (ioctl_ret == 0) {
tclsystem_private_append_sockaddr_to_tclobj(interp, retlist, "destination", &iface_req.ifr_addr);
tuapi_private_append_sockaddr_to_tclobj(interp, retlist, "destination", &iface_req.ifr_addr);
}
}
if (flag_broadcast) {
/* Broadcast interfaces */
ioctl_ret = ioctl(sock_v4, SIOCGIFBRDADDR, &iface_req);
if (ioctl_ret == 0) {
tclsystem_private_append_sockaddr_to_tclobj(interp, retlist, "broadcast", &iface_req.ifr_addr);
tuapi_private_append_sockaddr_to_tclobj(interp, retlist, "broadcast", &iface_req.ifr_addr);
}
}
ioctl_ret = ioctl(sock_v4, SIOCGIFNETMASK, &iface_req);
if (ioctl_ret == 0) {
tclsystem_private_append_sockaddr_to_tclobj(interp, retlist, "netmask", &iface_req.ifr_addr);
tuapi_private_append_sockaddr_to_tclobj(interp, retlist, "netmask", &iface_req.ifr_addr);
}
}
Tcl_SetObjResult(interp, retlist);
return(TCL_OK);
}
static int tclsystem_ifconfig_conf(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int sock, int sock_v4, int sock_v6) {
static int tuapi_ifconfig_conf(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int sock, int sock_v4, int sock_v6) {
Tcl_Obj *option_name_obj, *option_val_obj;
Tcl_Obj **flags_objv;
struct ifreq iface_req;
struct sockaddr *tmp_ioctl_addr;
const char *iface;
short flags;
int flags_objc;
|
︙ | | |
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
|
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
|
-
+
-
+
|
}
objc--;
objv++;
option_val_obj = objv[0];
switch (tclsystem_internal_simplehash_obj(option_name_obj)) {
switch (tuapi_internal_simplehash_obj(option_name_obj)) {
case 0x6d9870f3: /* flags */
flags = 0;
tcl_ret = Tcl_ListObjGetElements(interp, option_val_obj, &flags_objc, &flags_objv);
if (tcl_ret != TCL_OK) {
return(tcl_ret);
}
for (; flags_objc > 0; flags_objc--,flags_objv++) {
switch (tclsystem_internal_simplehash_obj(flags_objv[0])) {
switch (tuapi_internal_simplehash_obj(flags_objv[0])) {
case 0x2ad0: /* UP */
flags |= IFF_UP;
break;
case 0x1aef7f54: /* BROADCAST */
flags |= IFF_BROADCAST;
break;
case 0xc252abd4: /* POINTOPOINT */
|
︙ | | |
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
|
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
|
-
+
|
case 0x4d65ee6b: /* netmask */
if (tmp_ioctl == -1) {
tmp_ioctl = SIOCSIFNETMASK;
tmp_ioctl_addr = &iface_req.ifr_netmask;
}
parse_ret = tclsystem_private_get_sockaddr_from_obj(option_val_obj, tmp_ioctl_addr);
parse_ret = tuapi_private_get_sockaddr_from_obj(option_val_obj, tmp_ioctl_addr);
if (parse_ret != 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf("unable to parse \"%s\" as an address", Tcl_GetString(option_val_obj)));
return(TCL_ERROR);
}
switch (tmp_ioctl_addr->sa_family) {
|
︙ | | |
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
|
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
|
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
return(TCL_ERROR);
}
}
return(TCL_OK);
}
static int tclsystem_ifconfig(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_ifconfig(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
int sock_v4, sock_v6, sock;
int retval = TCL_ERROR;
sock = tclsystem_internal_getsock(&sock_v4, &sock_v6);
sock = tuapi_internal_getsock(&sock_v4, &sock_v6);
if (sock == -1) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to create socket", -1));
return(TCL_ERROR);
}
switch (objc) {
case 0:
case 1: /* No arguments, list all interfaces */
retval = tclsystem_ifconfig_list(cd, interp, objc, objv, sock);
retval = tuapi_ifconfig_list(cd, interp, objc, objv, sock);
break;
case 2: /* One argument, give information about the interface */
retval = tclsystem_ifconfig_info(cd, interp, objc, objv, sock, sock_v4, sock_v6);
retval = tuapi_ifconfig_info(cd, interp, objc, objv, sock, sock_v4, sock_v6);
break;
default:
/* Otherwise, configure the interace */
retval = tclsystem_ifconfig_conf(cd, interp, objc, objv, sock, sock_v4, sock_v6);
retval = tuapi_ifconfig_conf(cd, interp, objc, objv, sock, sock_v4, sock_v6);
break;
}
/* Cleanup */
if (sock_v4 != -1) {
close(sock_v4);
}
if (sock_v6 != -1) {
close(sock_v6);
}
return(retval);
}
static int tclsystem_route_list(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int sock_v4, int sock_v6) {
static int tuapi_route_list(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int sock_v4, int sock_v6) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("not implemented", -1));
return(TCL_ERROR);
}
static int tclsystem_route_conf(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int sock_v4, int sock_v6) {
static int tuapi_route_conf(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int sock_v4, int sock_v6) {
Tcl_WideInt option_val_wide;
Tcl_Obj *operation_obj, *dest_obj, *destmask_obj;
Tcl_Obj *option_name_obj, *option_val_obj;
struct rtentry route;
int sock;
int ioctl_id;
int tcl_ret, ioctl_ret, parse_ret;
if (objc < 4) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::route operation destination destination_mask ?options?\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::tuapi::syscall::route operation destination destination_mask ?options?\"", -1));
return(TCL_ERROR);
}
/* Clear object values */
memset(&route, 0, sizeof(route));
/* Determine operation */
operation_obj = objv[1];
switch (tclsystem_internal_simplehash_obj(operation_obj)) {
switch (tuapi_internal_simplehash_obj(operation_obj)) {
case 0x187264: /* add */
ioctl_id = SIOCADDRT;
break;
case 0x1932ec: /* del */
case 0x5d98e965: /* delete */
ioctl_id = SIOCDELRT;
break;
default:
Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad option \"%s\": must be add, or delete", Tcl_GetString(operation_obj)));
return(TCL_ERROR);
}
/* Set default flags */
route.rt_flags = RTF_UP;
/* Parse destination address */
dest_obj = objv[2];
parse_ret = tclsystem_private_get_sockaddr_from_obj(dest_obj, &route.rt_dst);
parse_ret = tuapi_private_get_sockaddr_from_obj(dest_obj, &route.rt_dst);
if (parse_ret != 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf("unable to parse \"%s\" as an address", Tcl_GetString(dest_obj)));
return(TCL_ERROR);
}
/* Parse destination netmask */
destmask_obj = objv[3];
parse_ret = tclsystem_private_get_sockaddr_from_obj(destmask_obj, &route.rt_genmask);
parse_ret = tuapi_private_get_sockaddr_from_obj(destmask_obj, &route.rt_genmask);
if (parse_ret != 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf("unable to parse \"%s\" as an address", Tcl_GetString(destmask_obj)));
return(TCL_ERROR);
}
if (route.rt_dst.sa_family != route.rt_genmask.sa_family) {
|
︙ | | |
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
|
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
|
-
+
-
+
|
}
objc--;
objv++;
option_val_obj = objv[0];
switch (tclsystem_internal_simplehash_obj(option_name_obj)) {
switch (tuapi_internal_simplehash_obj(option_name_obj)) {
case 0x4c727779: /* gateway */
parse_ret = tclsystem_private_get_sockaddr_from_obj(option_val_obj, &route.rt_gateway);
parse_ret = tuapi_private_get_sockaddr_from_obj(option_val_obj, &route.rt_gateway);
if (parse_ret != 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf("unable to parse \"%s\" as an address", Tcl_GetString(option_val_obj)));
return(TCL_ERROR);
}
route.rt_flags &= (~RTF_HOST);
|
︙ | | |
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
|
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
|
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
return(TCL_ERROR);
}
return(TCL_OK);
}
static int tclsystem_route(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_route(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
int sock_v4, sock_v6, sock;
int retval = TCL_ERROR;
sock = tclsystem_internal_getsock(&sock_v4, &sock_v6);
sock = tuapi_internal_getsock(&sock_v4, &sock_v6);
if (sock == -1) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to create socket", -1));
return(TCL_ERROR);
}
switch (objc) {
case 0:
case 1: /* No arguments, list all interfaces */
retval = tclsystem_route_list(cd, interp, objc, objv, sock_v4, sock_v6);
retval = tuapi_route_list(cd, interp, objc, objv, sock_v4, sock_v6);
break;
default:
/* Otherwise, modify routes */
retval = tclsystem_route_conf(cd, interp, objc, objv, sock_v4, sock_v6);
retval = tuapi_route_conf(cd, interp, objc, objv, sock_v4, sock_v6);
break;
}
/* Cleanup */
if (sock_v4 != -1) {
close(sock_v4);
}
if (sock_v6 != -1) {
close(sock_v6);
}
return(retval);
}
static int tclsystem_brctl_list(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int sock) {
static int tuapi_brctl_list(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int sock) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("not implemented", -1));
return(TCL_ERROR);
}
static int tclsystem_brctl_conf(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int sock) {
static int tuapi_brctl_conf(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int sock) {
Tcl_Obj *operation_obj, *bridge_name_obj, *interface_name_obj;
unsigned long arg[4];
struct ifreq ifr;
int ioctl_ret, ioctl_id;
int add = 0;
/* Determine operation */
operation_obj = objv[1];
switch (tclsystem_internal_simplehash_obj(operation_obj)) {
switch (tuapi_internal_simplehash_obj(operation_obj)) {
case 0x1c993272: /* addbr */
add = 1;
case 0x4cbb3272: /* delbr */
if (objc != 3) {
if (add) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::brctl addbr bridge\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::tuapi::syscall::brctl addbr bridge\"", -1));
} else {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::brctl delbr bridge\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::tuapi::syscall::brctl delbr bridge\"", -1));
}
return(TCL_ERROR);
}
bridge_name_obj = objv[2];
|
︙ | | |
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
|
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
|
-
+
-
+
|
break;
case 0x1C9937E6: /* addif */
add = 1;
case 0x4cbb37e6: /* delif */
if (objc != 4) {
if (add) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::brctl addif bridge interface\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::tuapi::syscall::brctl addif bridge interface\"", -1));
} else {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::brctl delif bridge interface\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::tuapi::syscall::brctl delif bridge interface\"", -1));
}
return(TCL_ERROR);
}
if (add) {
ioctl_id = SIOCBRADDIF;
|
︙ | | |
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
|
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
|
-
+
-
+
-
+
-
+
-
+
-
+
|
return(TCL_ERROR);
}
return(TCL_OK);
}
static int tclsystem_brctl(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_brctl(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
int sock_v4, sock_v6, sock;
int retval = TCL_ERROR;
sock = tclsystem_internal_getsock(&sock_v4, &sock_v6);
sock = tuapi_internal_getsock(&sock_v4, &sock_v6);
if (sock == -1) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to create socket", -1));
return(TCL_ERROR);
}
switch (objc) {
case 0:
case 1: /* No arguments, list all bridges */
retval = tclsystem_brctl_list(cd, interp, objc, objv, sock);
retval = tuapi_brctl_list(cd, interp, objc, objv, sock);
break;
default:
/* Otherwise, modify routes */
retval = tclsystem_brctl_conf(cd, interp, objc, objv, sock);
retval = tuapi_brctl_conf(cd, interp, objc, objv, sock);
break;
}
/* Cleanup */
if (sock_v4 != -1) {
close(sock_v4);
}
if (sock_v6 != -1) {
close(sock_v6);
}
return(retval);
}
static int tclsystem_vconfig(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_vconfig(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
int sock_v4, sock_v6, sock;
int retval = TCL_ERROR;
sock = tclsystem_internal_getsock(&sock_v4, &sock_v6);
sock = tuapi_internal_getsock(&sock_v4, &sock_v6);
if (sock == -1) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to create socket", -1));
return(TCL_ERROR);
}
Tcl_SetObjResult(interp, Tcl_NewStringObj("not implemented", -1));
|
︙ | | |
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
|
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
|
-
+
-
-
+
+
-
-
+
+
-
-
+
+
|
close(sock_v6);
}
return(retval);
}
#ifndef DISABLE_UNIX_SOCKETS
struct tclsystem_socket_unix__chan_id {
struct tuapi_socket_unix__chan_id {
int fd;
Tcl_Channel chan;
};
static int tclsystem_socket_unix__chan_close(ClientData id_p, Tcl_Interp *interp) {
struct tclsystem_socket_unix__chan_id *id;
static int tuapi_socket_unix__chan_close(ClientData id_p, Tcl_Interp *interp) {
struct tuapi_socket_unix__chan_id *id;
int fd;
id = id_p;
fd = id->fd;
close(fd);
free(id);
return(0);
}
static int tclsystem_socket_unix__chan_read(ClientData id_p, char *buf, int bufsize, int *errorCodePtr) {
struct tclsystem_socket_unix__chan_id *id;
static int tuapi_socket_unix__chan_read(ClientData id_p, char *buf, int bufsize, int *errorCodePtr) {
struct tuapi_socket_unix__chan_id *id;
ssize_t read_ret;
int fd;
int retval;
id = id_p;
fd = id->fd;
read_ret = read(fd, buf, bufsize);
if (read_ret < 0) {
*errorCodePtr = errno;
return(-1);
}
retval = read_ret;
return(retval);
}
static int tclsystem_socket_unix__chan_write(ClientData id_p, const char *buf, int toWrite, int *errorCodePtr) {
struct tclsystem_socket_unix__chan_id *id;
static int tuapi_socket_unix__chan_write(ClientData id_p, const char *buf, int toWrite, int *errorCodePtr) {
struct tuapi_socket_unix__chan_id *id;
ssize_t write_ret;
int fd;
int bytesWritten;
id = id_p;
fd = id->fd;
|
︙ | | |
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
|
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
|
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
|
return(-1);
}
return(bytesWritten);
}
static void tclsystem_socket_unix__chan_eventhandler(ClientData id_p, int mask) {
struct tclsystem_socket_unix__chan_id *id;
static void tuapi_socket_unix__chan_eventhandler(ClientData id_p, int mask) {
struct tuapi_socket_unix__chan_id *id;
Tcl_Channel chan;
id = id_p;
chan = id->chan;
if (!chan) {
return;
}
Tcl_NotifyChannel(chan, mask);
}
static void tclsystem_socket_unix__chan_watch(ClientData id_p, int mask) {
struct tclsystem_socket_unix__chan_id *id;
static void tuapi_socket_unix__chan_watch(ClientData id_p, int mask) {
struct tuapi_socket_unix__chan_id *id;
int fd;
id = id_p;
fd = id->fd;
Tcl_CreateFileHandler(fd, mask, tclsystem_socket_unix__chan_eventhandler, id);
Tcl_CreateFileHandler(fd, mask, tuapi_socket_unix__chan_eventhandler, id);
return;
}
static int tclsystem_socket_unix__chan_gethandle(ClientData id_p, int direction, ClientData *handlePtr) {
struct tclsystem_socket_unix__chan_id *id;
static int tuapi_socket_unix__chan_gethandle(ClientData id_p, int direction, ClientData *handlePtr) {
struct tuapi_socket_unix__chan_id *id;
int fd;
ClientData fd_cd;
id = id_p;
fd = id->fd;
memcpy(&fd_cd, &fd, sizeof(fd));
*handlePtr = fd_cd;
return(TCL_OK);
}
static Tcl_Channel tclsystem_socket_unix_sock2tclchan(int sock) {
struct tclsystem_socket_unix__chan_id *id;
static Tcl_Channel tuapi_socket_unix_sock2tclchan(int sock) {
struct tuapi_socket_unix__chan_id *id;
static Tcl_ChannelType tcl_chan_type;
static int tcl_chan_type_init = 0;
Tcl_Channel tcl_chan;
char chan_name[32];
int sock_flags;
if (!tcl_chan_type_init) {
tcl_chan_type.typeName = "socket";
tcl_chan_type.version = TCL_CHANNEL_VERSION_2;
tcl_chan_type.closeProc = tclsystem_socket_unix__chan_close;
tcl_chan_type.inputProc = tclsystem_socket_unix__chan_read;
tcl_chan_type.outputProc = tclsystem_socket_unix__chan_write;
tcl_chan_type.watchProc = tclsystem_socket_unix__chan_watch;
tcl_chan_type.getHandleProc = tclsystem_socket_unix__chan_gethandle;
tcl_chan_type.closeProc = tuapi_socket_unix__chan_close;
tcl_chan_type.inputProc = tuapi_socket_unix__chan_read;
tcl_chan_type.outputProc = tuapi_socket_unix__chan_write;
tcl_chan_type.watchProc = tuapi_socket_unix__chan_watch;
tcl_chan_type.getHandleProc = tuapi_socket_unix__chan_gethandle;
tcl_chan_type.seekProc = NULL;
tcl_chan_type.setOptionProc = NULL;
tcl_chan_type.getOptionProc = NULL;
tcl_chan_type.close2Proc = NULL;
tcl_chan_type.blockModeProc = NULL;
tcl_chan_type.flushProc = NULL;
tcl_chan_type.handlerProc = NULL;
|
︙ | | |
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
|
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
|
-
+
-
-
+
+
|
/* Update the structure passed to each function to include the channel name */
id->chan = tcl_chan;
return(tcl_chan);
}
struct tclsystem_socket_unix__chan_accept_cd {
struct tuapi_socket_unix__chan_accept_cd {
int fd;
Tcl_Interp *interp;
Tcl_Obj *command;
};
static void tclsystem_socket_unix__chan_accept(ClientData cd_p, int mask) {
struct tclsystem_socket_unix__chan_accept_cd *cd;
static void tuapi_socket_unix__chan_accept(ClientData cd_p, int mask) {
struct tuapi_socket_unix__chan_accept_cd *cd;
Tcl_Interp *interp;
Tcl_Channel chan;
Tcl_Obj *command, *command_to_run_objs[5], *command_to_run;
int setsockopt_ret;
int pass_creds_true = 1;
int fd;
int sock;
|
︙ | | |
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
|
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
|
-
+
|
command = cd->command;
sock = accept(fd, NULL, NULL);
if (sock < 0) {
return;
}
chan = tclsystem_socket_unix_sock2tclchan(sock);
chan = tuapi_socket_unix_sock2tclchan(sock);
if (chan == NULL) {
close(sock);
return;
}
setsockopt_ret = setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &pass_creds_true, sizeof(pass_creds_true));
|
︙ | | |
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
|
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
|
-
-
+
+
|
command_to_run = Tcl_ConcatObj(sizeof(command_to_run_objs) / sizeof(command_to_run_objs[0]), command_to_run_objs);
Tcl_EvalObjEx(interp, command_to_run, TCL_EVAL_GLOBAL);
return;
}
static int tclsystem_socket_unix_server(ClientData cd, Tcl_Interp *interp, int sock, const char *path, Tcl_Obj *command) {
struct tclsystem_socket_unix__chan_accept_cd *accept_cd;
static int tuapi_socket_unix_server(ClientData cd, Tcl_Interp *interp, int sock, const char *path, Tcl_Obj *command) {
struct tuapi_socket_unix__chan_accept_cd *accept_cd;
struct sockaddr_un dest;
ssize_t pathlen;
int bind_ret, listen_ret;
pathlen = strlen(path) + 1;
if (pathlen <= 0) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("path too short", -1));
|
︙ | | |
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
|
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
|
-
+
-
+
|
accept_cd->fd = sock;
accept_cd->interp = interp;
accept_cd->command = command;
Tcl_IncrRefCount(command);
Tcl_CreateFileHandler(sock, TCL_READABLE, tclsystem_socket_unix__chan_accept, accept_cd);
Tcl_CreateFileHandler(sock, TCL_READABLE, tuapi_socket_unix__chan_accept, accept_cd);
return(TCL_OK);
}
static int tclsystem_socket_unix_client(ClientData cd, Tcl_Interp *interp, int sock, const char *path) {
static int tuapi_socket_unix_client(ClientData cd, Tcl_Interp *interp, int sock, const char *path) {
Tcl_Channel chan;
struct sockaddr_un dest;
ssize_t pathlen;
int connect_ret, setsockopt_ret;
int pass_creds_true = 1;
pathlen = strlen(path) + 1;
|
︙ | | |
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
|
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
|
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
setsockopt_ret = setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &pass_creds_true, sizeof(pass_creds_true));
if (setsockopt_ret != 0) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(strerror(errno), -1));
return(TCL_ERROR);
}
chan = tclsystem_socket_unix_sock2tclchan(sock);
chan = tuapi_socket_unix_sock2tclchan(sock);
if (chan == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to create Tcl channel", -1));
return(TCL_ERROR);
}
Tcl_RegisterChannel(interp, chan);
Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetChannelName(chan), -1));
return(TCL_OK);
}
static int tclsystem_socket_unix(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_socket_unix(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
Tcl_Obj *path_obj, *command_obj;
char *path;
int retval;
int sock;
if (objc < 2) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::socket_unix path\" or \"::system::syscall::socket_unix -server command path\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::tuapi::syscall::socket_unix path\" or \"::tuapi::syscall::socket_unix -server command path\"", -1));
return(TCL_ERROR);
}
path_obj = objv[1];
path = Tcl_GetString(path_obj);
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock == -1) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(strerror(errno), -1));
return(TCL_ERROR);
}
if (strcmp(path, "-server") == 0) {
if (objc != 4) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::socket_unix -server command path\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::tuapi::syscall::socket_unix -server command path\"", -1));
close(sock);
return(TCL_ERROR);
}
command_obj = objv[2];
path_obj = objv[3];
path = Tcl_GetString(path_obj);
retval = tclsystem_socket_unix_server(cd, interp, sock, path, command_obj);
retval = tuapi_socket_unix_server(cd, interp, sock, path, command_obj);
} else {
if (objc != 2) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::socket_unix path\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::tuapi::syscall::socket_unix path\"", -1));
close(sock);
return(TCL_ERROR);
}
retval = tclsystem_socket_unix_client(cd, interp, sock, path);
retval = tuapi_socket_unix_client(cd, interp, sock, path);
}
if (retval != TCL_OK) {
close(sock);
}
return(retval);
}
#else
static int tclsystem_socket_unix(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_socket_unix(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("not implemented", -1));
return(TCL_ERROR)
}
#endif
static int tclsystem_tsmf_start_svc(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
static int tuapi_tsmf_start_svc(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
struct timeval select_timeout;
Tcl_WideInt umask_val, timeout_val, uid_val, gid_val;
Tcl_Obj *filename_obj, *env_obj, *logfile_obj, **env_entry_objv, *cwd_obj, *umask_obj, *uid_obj, *gid_obj;
Tcl_Obj *sri_obj, *timeout_obj;
pid_t child, child_pgid = -1, waitpid_ret;
ssize_t read_ret;
time_t currtime;
|
︙ | | |
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
|
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
|
-
+
|
int fds[2], fd;
int status;
int idx;
/* 1. Parse arguments */
/* 1.a. Ensure the correct number of arguments were passed */
if (objc != 10) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::tsmf_start_svc sri filename logfile env cwd umask uid gid timeout\"", -1));
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::tuapi::syscall::tsmf_start_svc sri filename logfile env cwd umask uid gid timeout\"", -1));
return(TCL_ERROR);
}
/* 1.b. Identify Tcl_Objs to use for each argument */
sri_obj = objv[1];
filename_obj = objv[2];
|
︙ | | |
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
|
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
|
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
argv[0] = filename;
argv[1] = "start";
argv[2] = NULL;
execve_ret = execve(filename, argv, envv);
/* 10. Abort if something has gone wrong */
_exit(execve_ret);
}
int System_Init(Tcl_Interp *interp) {
/* Handle lint-ness */
return(TCL_ERROR);
sri_obj = sri_obj;
}
int Tuapi_Init(Tcl_Interp *interp) {
#ifdef USE_TCL_STUBS
const char *tclInitStubs_ret;
/* Initialize Stubs */
tclInitStubs_ret = Tcl_InitStubs(interp, "8.4", 0);
if (!tclInitStubs_ret) {
return(TCL_ERROR);
}
#endif
/* Kernel maintenance related commands */
Tcl_CreateObjCommand(interp, "::system::syscall::insmod", tclsystem_insmod, NULL, NULL);
Tcl_CreateObjCommand(interp, "::system::syscall::rmmod", tclsystem_rmmod, NULL, NULL);
Tcl_CreateObjCommand(interp, "::system::syscall::lsmod", tclsystem_lsmod, NULL, NULL);
Tcl_CreateObjCommand(interp, "::system::syscall::hostname", tclsystem_hostname, NULL, NULL);
Tcl_CreateObjCommand(interp, "::system::syscall::domainname", tclsystem_domainname, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::insmod", tuapi_insmod, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::rmmod", tuapi_rmmod, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::lsmod", tuapi_lsmod, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::hostname", tuapi_hostname, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::domainname", tuapi_domainname, NULL, NULL);
/* Block or char device related commands */
Tcl_CreateObjCommand(interp, "::system::syscall::losetup", tclsystem_losetup, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::losetup", tuapi_losetup, NULL, NULL);
/* Filesystem related commands */
Tcl_CreateObjCommand(interp, "::system::syscall::mount", tclsystem_mount, NULL, NULL);
Tcl_CreateObjCommand(interp, "::system::syscall::umount", tclsystem_umount, NULL, NULL);
Tcl_CreateObjCommand(interp, "::system::syscall::swapon", tclsystem_swapon, NULL, NULL);
Tcl_CreateObjCommand(interp, "::system::syscall::swapoff", tclsystem_swapoff, NULL, NULL);
Tcl_CreateObjCommand(interp, "::system::syscall::mknod", tclsystem_mknod, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::mount", tuapi_mount, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::umount", tuapi_umount, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::swapon", tuapi_swapon, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::swapoff", tuapi_swapoff, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::mknod", tuapi_mknod, NULL, NULL);
/* Process related commands */
Tcl_CreateObjCommand(interp, "::system::syscall::getuid", tclsystem_getuid, NULL, NULL);
Tcl_CreateObjCommand(interp, "::system::syscall::chroot", tclsystem_chroot, NULL, NULL);
Tcl_CreateObjCommand(interp, "::system::syscall::pivot_root", tclsystem_pivot_root, NULL, NULL);
Tcl_CreateObjCommand(interp, "::system::syscall::kill", tclsystem_kill, NULL, NULL);
Tcl_CreateObjCommand(interp, "::system::syscall::ps", tclsystem_ps, NULL, NULL);
Tcl_CreateObjCommand(interp, "::system::syscall::execve", tclsystem_execve, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::getuid", tuapi_getuid, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::chroot", tuapi_chroot, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::pivot_root", tuapi_pivot_root, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::kill", tuapi_kill, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::ps", tuapi_ps, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::execve", tuapi_execve, NULL, NULL);
/* Network related commands */
Tcl_CreateObjCommand(interp, "::system::syscall::ifconfig", tclsystem_ifconfig, NULL, NULL);
Tcl_CreateObjCommand(interp, "::system::syscall::route", tclsystem_route, NULL, NULL);
Tcl_CreateObjCommand(interp, "::system::syscall::brctl", tclsystem_brctl, NULL, NULL);
Tcl_CreateObjCommand(interp, "::system::syscall::vconfig", tclsystem_vconfig, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::ifconfig", tuapi_ifconfig, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::route", tuapi_route, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::brctl", tuapi_brctl, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::vconfig", tuapi_vconfig, NULL, NULL);
/* Needed commands for basic services Tcl lacks */
Tcl_CreateObjCommand(interp, "::system::syscall::socket_unix", tclsystem_socket_unix, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::socket_unix", tuapi_socket_unix, NULL, NULL);
/* Service (TSMF) related commands */
Tcl_CreateObjCommand(interp, "::system::syscall::tsmf_start_svc", tclsystem_tsmf_start_svc, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::syscall::tsmf_start_svc", tuapi_tsmf_start_svc, NULL, NULL);
/* Internal functions */
Tcl_CreateObjCommand(interp, "::system::internal::hash", tclsystem_internalproc_simplehash, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tuapi::internal::hash", tuapi_internalproc_simplehash, NULL, NULL);
/* Define constants */
/** Create parent namespace **/
Tcl_CreateNamespace(interp, "::system::const", NULL, NULL);
Tcl_CreateNamespace(interp, "::tuapi::const", NULL, NULL);
/** Define constants, for real **/
Tcl_ObjSetVar2(interp, Tcl_NewStringObj("::system::const::HOST_NAME_MAX", -1), NULL, Tcl_NewWideIntObj(HOST_NAME_MAX), TCL_GLOBAL_ONLY);
Tcl_ObjSetVar2(interp, Tcl_NewStringObj("::tuapi::const::HOST_NAME_MAX", -1), NULL, Tcl_NewWideIntObj(HOST_NAME_MAX), TCL_GLOBAL_ONLY);
/* Create high-level user functions */
Tcl_Eval(interp,
#include "system.tcl.h"
#include "tuapi.tcl.h"
);
Tcl_PkgProvide(interp, "system", "0.1");
Tcl_PkgProvide(interp, "tuapi", "0.1");
return(TCL_OK);
}
|