+/*
+ *----------------------------------------------------------------------
+ *
+ * curlChunkBgnProcInvoke --
+ *
+ * This is the function that will be invoked as a callback when the user
+ * wants to invoke a Tcl procedure to process every wildcard matching file
+ * on a ftp transfer.
+ *
+ * Parameter:
+ * transfer_info: a curl_fileinfo structure about the file.
+ * curlData: A pointer to the curlData structure for the transfer.
+ * remains: number of chunks remaining.
+ *-----------------------------------------------------------------------
+ */
+long
+curlChunkBgnProcInvoke (const void *transfer_info, void *curlDataPtr, int remains) {
+ struct curlObjData *curlData=(struct curlObjData *)curlDataPtr;
+ Tcl_Obj *tclProcPtr;
+ char tclCommand[300];
+ int i;
+ const struct curl_fileinfo *fileinfoPtr=(const struct curl_fileinfo *)transfer_info;
+
+ tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
+
+ if (curlData->chunkBgnVar==NULL) {
+ curlData->chunkBgnVar=curlstrdup("fileData");
+ }
+
+ Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filename",
+ fileinfoPtr->filename,0);
+
+ switch(fileinfoPtr->filetype) {
+ case 0:
+ Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
+ "file",0);
+ break;
+ case 1:
+ Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
+ "directory",0);
+ break;
+ case 2:
+ Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
+ "symlink",0);
+ break;
+ case 3:
+ Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
+ "device block",0);
+ break;
+ case 4:
+ Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
+ "device char",0);
+ break;
+ case 5:
+ Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
+ "named pipe",0);
+ break;
+ case 6:
+ Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
+ "socket",0);
+ break;
+ case 7:
+ Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
+ "door",0);
+ break;
+ case 8:
+ Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
+ "error",0);
+ break;
+ }
+
+ Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"time",
+ Tcl_NewLongObj(fileinfoPtr->time),0);
+
+ Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"perm",
+ Tcl_NewIntObj(fileinfoPtr->perm),0);
+
+ Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"uid",
+ Tcl_NewIntObj(fileinfoPtr->uid),0);
+ Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"gid",
+ Tcl_NewIntObj(fileinfoPtr->gid),0);
+ Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"size",
+ Tcl_NewLongObj(fileinfoPtr->size),0);
+ Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"hardlinks",
+ Tcl_NewIntObj(fileinfoPtr->hardlinks),0);
+ Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"flags",
+ Tcl_NewIntObj(fileinfoPtr->flags),0);
+
+ snprintf(tclCommand,300,"%s %d",curlData->chunkBgnProc,remains);
+ tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
+
+ if (Tcl_EvalObjEx(curlData->interp,tclProcPtr,TCL_EVAL_GLOBAL)!=TCL_OK) {
+ return CURL_CHUNK_BGN_FUNC_FAIL;
+ }
+
+ if (Tcl_GetIntFromObj(curlData->interp,Tcl_GetObjResult(curlData->interp),&i)!=TCL_OK) {
+ return CURL_CHUNK_BGN_FUNC_FAIL;
+ }
+ switch(i) {
+ case 0:
+ return CURL_CHUNK_BGN_FUNC_OK;
+ case 1:
+ return CURL_CHUNK_BGN_FUNC_SKIP;
+ }
+ return CURL_CHUNK_BGN_FUNC_FAIL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * curlChunkEndProcInvoke --
+ *
+ * This is the function that will be invoked every time a file has
+ * been downloaded or skipped, it does little more than called the
+ * given proc.
+ *
+ * Parameter:
+ * curlData: A pointer to the curlData structure for the transfer.
+ *
+ * Returns
+ *-----------------------------------------------------------------------
+ */
+long
+curlChunkEndProcInvoke (void *curlDataPtr) {
+
+ struct curlObjData *curlData=(struct curlObjData *)curlDataPtr;
+ Tcl_Obj *tclProcPtr;
+ char tclCommand[300];
+ int i;
+
+ snprintf(tclCommand,300,"%s",curlData->chunkEndProc);
+ tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
+
+ if (Tcl_EvalObjEx(curlData->interp,tclProcPtr,TCL_EVAL_GLOBAL)!=TCL_OK) {
+ return CURL_CHUNK_END_FUNC_FAIL;
+ }
+
+ if (Tcl_GetIntFromObj(curlData->interp,Tcl_GetObjResult(curlData->interp),&i)!=TCL_OK) {
+ return CURL_CHUNK_END_FUNC_FAIL;
+ }
+ if (i==1) {
+ return CURL_CHUNK_BGN_FUNC_FAIL;
+ }
+ return CURL_CHUNK_END_FUNC_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * curlfnmatchProcInvoke --
+ *
+ * This is the function that will be invoked to tell whether a filename
+ * matches a pattern when doing a 'wildcard' download. It invokes a Tcl
+ * proc to do the actual work.
+ *
+ * Parameter:
+ * curlData: A pointer to the curlData structure for the transfer.
+ * pattern: The pattern to match.
+ * filename: The file name to be matched.
+ *-----------------------------------------------------------------------
+ */
+int curlfnmatchProcInvoke(void *curlDataPtr, const char *pattern, const char *filename) {
+
+ struct curlObjData *curlData=(struct curlObjData *)curlDataPtr;
+ Tcl_Obj *tclProcPtr;
+ char tclCommand[500];
+ int i;
+
+ snprintf(tclCommand,500,"%s %s %s",curlData->fnmatchProc,pattern,filename);
+ tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
+
+ if (Tcl_EvalObjEx(curlData->interp,tclProcPtr,TCL_EVAL_GLOBAL)!=TCL_OK) {
+ return CURL_FNMATCHFUNC_FAIL;
+ }
+
+ if (Tcl_GetIntFromObj(curlData->interp,Tcl_GetObjResult(curlData->interp),&i)!=TCL_OK) {
+ return CURL_FNMATCHFUNC_FAIL;
+ }
+ switch(i) {
+ case 0:
+ return CURL_FNMATCHFUNC_MATCH;
+ case 1:
+ return CURL_FNMATCHFUNC_NOMATCH;
+ }
+ return CURL_FNMATCHFUNC_FAIL;
+}
+