@@ -4,14 +4,16 @@ # include #endif typedef struct cvfs_data *(cmd_getData_t)(const char *, unsigned long); typedef unsigned long (cmd_getChildren_t)(const char *, unsigned long *, unsigned long); +typedef void (cmd_decryptFile_t)(const char *, struct cvfs_data *); /* Your implementation must provide these */ static cmd_getData_t *getCmdData(const char *hashkey); static cmd_getChildren_t *getCmdChildren(const char *hashkey); +static cmd_decryptFile_t *getCmdDecryptFile(const char *hashkey); /* Tcl Commands */ static int getMetadata(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { cmd_getData_t *cmd_getData; cmd_getChildren_t *cmd_getChildren; @@ -18,10 +20,11 @@ struct cvfs_data *finfo = NULL; Tcl_Obj *ret_list, *ret_list_items[20]; unsigned long num_children; const char *hashkey; const char *file; + int idx; if (objc != 3) { Tcl_SetResult(interp, "wrong # args: should be \"getMetadata hashKey fileName\"", TCL_STATIC); return(TCL_ERROR); @@ -83,21 +86,34 @@ ret_list_items[16] = Tcl_NewStringObj("mtime", 5); ret_list_items[17] = Tcl_NewStringObj("0", 1); ret_list_items[18] = Tcl_NewStringObj("ctime", 5); ret_list_items[19] = Tcl_NewStringObj("0", 1); + + for (idx = 0; idx < (sizeof(ret_list_items) / sizeof(ret_list_items[0])); idx++) { + Tcl_IncrRefCount(ret_list_items[idx]); + } ret_list = Tcl_NewListObj(sizeof(ret_list_items) / sizeof(ret_list_items[0]), ret_list_items); + + Tcl_IncrRefCount(ret_list); Tcl_SetObjResult(interp, ret_list); + + Tcl_DecrRefCount(ret_list); + + for (idx = 0; idx < (sizeof(ret_list_items) / sizeof(ret_list_items[0])); idx++) { + Tcl_DecrRefCount(ret_list_items[idx]); + } return(TCL_OK); } static int getData(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { struct cvfs_data *finfo = NULL; cmd_getData_t *cmd_getData; + cmd_decryptFile_t *cmd_decryptFile; const char *hashkey; const char *file; const char *end_str; Tcl_Obj *ret_str; long start = 0; @@ -147,10 +163,18 @@ if (finfo == NULL) { Tcl_SetResult(interp, "No such file or directory", TCL_STATIC); return(TCL_ERROR); } + + if (finfo->type == CVFS_FILETYPE_ENCRYPTED_FILE) { + cmd_decryptFile = getCmdDecryptFile(hashkey); + + if (cmd_decryptFile != NULL) { + cmd_decryptFile(file, finfo); + } + } if (finfo->type != CVFS_FILETYPE_FILE) { Tcl_SetResult(interp, "Not a file", TCL_STATIC); return(TCL_ERROR); @@ -177,12 +201,16 @@ return(TCL_ERROR); } ret_str = Tcl_NewByteArrayObj(finfo->data + start, (end - start)); + + Tcl_IncrRefCount(ret_str); Tcl_SetObjResult(interp, ret_str); + + Tcl_DecrRefCount(ret_str); return(TCL_OK); } static int getChildren(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { @@ -241,10 +269,12 @@ if (ret_list == NULL) { Tcl_SetResult(interp, "Failed to allocate new object", TCL_STATIC); return(TCL_ERROR); } + + Tcl_IncrRefCount(ret_list); children = malloc(sizeof(*children) * num_children); num_children = cmd_getChildren(file, children, num_children); @@ -256,15 +286,21 @@ } child = finfo->name; ret_curr_obj = Tcl_NewStringObj(child, strlen(child)); + + Tcl_IncrRefCount(ret_curr_obj); Tcl_ListObjAppendList(interp, ret_list, ret_curr_obj); + + Tcl_DecrRefCount(ret_curr_obj); } free(children); Tcl_SetObjResult(interp, ret_list); + + Tcl_DecrRefCount(ret_list); return(TCL_OK); }