Posted to tcl by stu at Fri Jan 26 15:54:38 GMT 2018view raw

  1. /*
  2. * Copyright (c) 2015,2017 Stuart Cassoff <stwo@users.sourceforge.net>
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16.  
  17.  
  18. /*
  19. * tjpledge.c
  20. *
  21. * Tcl / Jim interface to pledge(3).
  22. *
  23. */
  24.  
  25. /*
  26. * Notes:
  27. *
  28. */
  29.  
  30. #ifdef __cplusplus
  31. extern "C" {
  32. #endif
  33.  
  34. #include <unistd.h>
  35. #include <errno.h>
  36. #include <string.h> /* strerror */
  37.  
  38. #define COMBIEN(Z) ((int) (sizeof(Z) / sizeof(Z[0])))
  39.  
  40. #ifdef FOR_JIM
  41. #include <jim-subcmd.h>
  42. # define EZT_OK JIM_OK
  43. # define EZT_ERROR JIM_ERR
  44. # define Ezt_Alloc Jim_Alloc
  45. # define Ezt_Free Jim_Free
  46. # define Ezt_PosixError() strerror(errno)
  47. # define Ezt_WrongNumArgs Jim_WrongNumArgs
  48. # define Ezt_IncrRefCount Jim_IncrRefCount
  49. # define Ezt_DecrRefCount(O) Jim_DecrRefCount(interp,(O))
  50. # define Ezt_SetResult(O) Jim_SetResult(interp,(O))
  51. # define Ezt_Obj Jim_Obj
  52. # define Ezt_Interp Jim_Interp
  53. # define Ezt_NewInt(I) Ezt_NewIntObj(interp,(I))
  54. # define Ezt_GetInt(I,P) Ezt_GetIntFromJimObj(interp,(I),(P))
  55. # define Ezt_NewWide(I) Jim_NewWideObj(interp,(I))
  56. # define Ezt_GetWide Jim_GetWide
  57. # define Ezt_NewString(S,L) Jim_NewStringObj(interp,(S),(L))
  58. # define Ezt_GetString Jim_GetString
  59. # define Ezt_GetBytes Jim_GetString
  60. # define Ezt_NewList() Jim_NewListObj(interp, NULL, 0)
  61. # define Ezt_ListAppend(L,O) Jim_ListAppendElement(interp,(L),(O))
  62. # define Ezt_NewDict() Jim_NewDictObj(interp, NULL, 0)
  63. # define Ezt_DictPut(D,KO,VO) Jim_DictAddElement(interp,(D),(KO),(VO))
  64. # define ezt_wide jim_wide
  65. # define EZT_SUBCMD(S) int (S) (Ezt_Interp *interp, int objc, Ezt_Obj *const *objv)
  66. # define EZT_CMD(S) int (S) (Ezt_Interp *interp, int objc, Ezt_Obj *const *objv)
  67. # define ezt_subcmd_type jim_subcmd_type
  68. #else
  69. # include <tcl.h>
  70. # define EZT_OK TCL_OK
  71. # define EZT_ERROR TCL_ERROR
  72. # define Ezt_Alloc ckalloc
  73. # define Ezt_Free ckfree
  74. # define Ezt_PosixError() Tcl_PosixError(interp)
  75. # define Ezt_WrongNumArgs Tcl_WrongNumArgs
  76. # define Ezt_IncrRefCount Tcl_IncrRefCount
  77. # define Ezt_DecrRefCount(O) Tcl_DecrRefCount((O))
  78. # define Ezt_SetResult(O) Tcl_SetObjResult(interp,(O))
  79. # define Ezt_Obj Tcl_Obj
  80. # define Ezt_Interp Tcl_Interp
  81. # define Ezt_NewInt Tcl_NewIntObj
  82. # define Ezt_GetInt(I,P) Tcl_GetIntFromObj(interp,(I),(P))
  83. # define Ezt_NewWide Tcl_NewWideIntObj
  84. # define Ezt_GetWide Tcl_GetWideIntFromObj
  85. # define Ezt_NewString Tcl_NewStringObj
  86. # define Ezt_GetString Tcl_GetStringFromObj
  87. # define Ezt_GetBytes Tcl_GetByteArrayFromObj
  88. # define Ezt_NewList() Tcl_NewListObj(0,NULL)
  89. # define Ezt_ListAppend(L,O) Tcl_ListObjAppendElement(interp,(L),(O))
  90. # define Ezt_NewDict() Tcl_NewDictObj()
  91. # define Ezt_DictPut(D,KO,VO) Tcl_DictObjPut(interp,(D),(KO),(VO))
  92. # define ezt_wide TclWideInt
  93. # define EZT_SUBCMD(S) int (S) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
  94. # define EZT_CMD EZT_SUBCMD
  95. typedef struct {
  96. const char *name;
  97. const char *args;
  98. Tcl_ObjCmdProc *proc;
  99. short minargs;
  100. short maxargs;
  101. unsigned short flags;
  102. } ezt_subcmd_type;
  103. #endif
  104.  
  105. #if 0 /* unused in this prog */
  106. #ifdef FOR_JIM
  107. static Jim_Obj *
  108. Ezt_NewIntObj (Jim_Interp *interp, int i) {
  109. return Jim_NewWideObj(interp, (ezt_wide) i);
  110. }
  111. static int
  112. Ezt_GetIntFromJimObj (Jim_Interp *interp, Jim_Obj *objPtr, int *intPtr) {
  113. jim_wide w;
  114. if (Jim_GetWide(interp, objPtr, &w) != JIM_OK) { return JIM_ERR; }
  115. *intPtr = (int) w;
  116. return JIM_OK;
  117. }
  118. #endif
  119. #endif
  120.  
  121.  
  122. static EZT_CMD(TJPledge_PledgeCmd);
  123.  
  124. /***/
  125.  
  126. #ifdef FOR_TCL_WENC
  127. static
  128. EZT_CMD(TJPledge_PledgeCmd) {
  129. Tcl_DString req;
  130. int ret = EZT_OK;
  131.  
  132. if (objc < 2 || objc > 3) {
  133. Ezt_WrongNumArgs(interp, 1, objv, "promises ?paths?");
  134. return EZT_ERROR;
  135. }
  136.  
  137. Tcl_DStringInit(&req);
  138. Tcl_UtfToExternalDString(NULL, Ezt_GetString(objv[1], NULL), -1, &req);
  139.  
  140. if (objc == 2) {
  141. if (pledge(Tcl_DStringValue(&req), NULL) == -1) {
  142. Ezt_SetResult(Ezt_NewString(Tcl_PosixError(interp), -1));
  143. ret = EZT_ERROR;
  144. }
  145. } else if (objc == 3) {
  146. const char **paths = NULL;
  147. Tcl_DString *dsa;
  148. int lobjc;
  149. Ezt_Obj **lobjv;
  150. int i;
  151. if (Tcl_ListObjGetElements(interp, objv[2], &lobjc, &lobjv) != EZT_OK) {
  152. ret = EZT_ERROR;
  153. goto quitting;
  154. }
  155. dsa = ckalloc(lobjc * sizeof(*dsa));
  156. paths = ckalloc((lobjc + 1) * sizeof(*paths));
  157. for (i = 0; i < lobjc; i++) {
  158. Tcl_DStringInit(&dsa[i]);
  159. paths[i] = Tcl_UtfToExternalDString(NULL, Tcl_GetString(lobjv[i]), -1, &dsa[i]);
  160. }
  161. paths[i] = NULL;
  162. if (pledge(Tcl_DStringValue(&req), paths) == -1) {
  163. Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_PosixError(interp), -1));
  164. ret = EZT_ERROR;
  165. }
  166. for (i = 0; paths[i] != NULL; i++) {
  167. Tcl_DStringFree(&dsa[i]);
  168. }
  169. ckfree(dsa);
  170. ckfree(paths);
  171. }
  172.  
  173. quitting:;
  174.  
  175. Tcl_DStringFree(&req);
  176.  
  177. return ret;
  178. }
  179.  
  180. #else /* !FOR_TCL_WENC */
  181.  
  182. static
  183. EZT_CMD(TJPledge_PledgeCmd) {
  184. const char **paths = NULL;
  185. int ret = EZT_OK;
  186.  
  187. if (objc < 2 || objc > 3) {
  188. Ezt_WrongNumArgs(interp, 1, objv, "promises ?paths?");
  189. return EZT_ERROR;
  190. }
  191.  
  192. if (objc == 3) {
  193. int llen, i;
  194. Ezt_Obj *o;
  195. #ifdef FOR_JIM
  196. llen = Jim_ListLength(interp, objv[2]);
  197. #else
  198. Ezt_Obj **lobjv;
  199. if (Tcl_ListObjGetElements(interp, objv[2], &llen, &lobjv) != EZT_OK) {
  200. return EZT_ERROR;
  201. }
  202. #endif
  203. paths = (const char **) Ezt_Alloc((llen + 1) * sizeof(*paths));
  204. for (i = 0; i < llen; i++) {
  205. #ifdef FOR_JIM
  206. o = Jim_ListGetIndex(interp, objv[2], i);
  207. #else
  208. o = lobjv[i];
  209. #endif
  210. paths[i] = Ezt_GetString(o, NULL);
  211. }
  212. paths[i] = NULL;
  213. }
  214.  
  215. if (pledge(Ezt_GetString(objv[1], NULL), paths) == -1) {
  216. Ezt_SetResult(Ezt_NewString(Ezt_PosixError(), -1));
  217. ret = EZT_ERROR;
  218. }
  219.  
  220. Ezt_Free((char *) paths);
  221.  
  222. return ret;
  223. }
  224.  
  225. #endif /* FOR_TCL_WENC */
  226.  
  227. /***/
  228.  
  229. #ifdef FOR_JIM
  230. int
  231. Jim_pledgeInit (Jim_Interp *interp) {
  232. if (Jim_CreateCommand(interp, "pledge", TJPledge_PledgeCmd, NULL, NULL) != JIM_OK) { return JIM_ERR; }
  233. if (Jim_PackageProvide(interp, PACKAGE_NAME, PACKAGE_VERSION, JIM_ERRMSG) != JIM_OK) { return JIM_ERR; }
  234. return JIM_OK;
  235. }
  236. #else
  237.  
  238. #define MIN_TCL_VERSION "8.5"
  239. #define TJPledge_NS "::pledge"
  240. #define TJPledge_CMD "pledge"
  241.  
  242. static int
  243. TJPledge_CommonInit (
  244. Tcl_Interp *interp
  245. ) {
  246. if (Tcl_InitStubs (interp, MIN_TCL_VERSION, 0) == NULL) { return TCL_ERROR; }
  247. if (Tcl_PkgRequire (interp, "Tcl", MIN_TCL_VERSION, 0) == NULL) { return TCL_ERROR; }
  248. if (Tcl_CreateNamespace (interp, TJPledge_NS, NULL, NULL) == NULL) { return TCL_ERROR; }
  249. if (Tcl_PkgProvide (interp, PACKAGE_NAME, PACKAGE_VERSION) != TCL_OK) { return TCL_ERROR; }
  250. return TCL_OK;
  251. }
  252.  
  253.  
  254. EXTERN int
  255. Pledge_Init (
  256. Tcl_Interp *interp
  257. ) {
  258. Tcl_Namespace *ns;
  259.  
  260. if (TJPledge_CommonInit(interp) != TCL_OK) { return TCL_ERROR; }
  261. if ((ns = Tcl_FindNamespace(interp, TJPledge_NS, NULL, TCL_LEAVE_ERR_MSG)) == NULL) { return TCL_ERROR; }
  262. if (Tcl_CreateObjCommand(interp, TJPledge_NS "::" TJPledge_CMD, TJPledge_PledgeCmd, NULL, NULL) == NULL) { return TCL_ERROR; }
  263. if (Tcl_Export(interp, ns, TJPledge_CMD, 0) != TCL_OK) { return TCL_ERROR; }
  264.  
  265. return TCL_OK;
  266. }
  267.  
  268. EXTERN int
  269. Pledge_SafeInit (
  270. Tcl_Interp *interp
  271. ) {
  272. return TJPledge_CommonInit(interp);
  273. }
  274. #endif
  275.  
  276.  
  277. #ifdef __cplusplus
  278. }
  279. #endif
  280.  
  281.  
  282. /* EOF */
  283.