static int history_cmd_getline(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { Jim_Obj *objPtr; char *line = Jim_HistoryGetline(interp, Jim_String(argv[0])); /* On EOF returns -1 if varName was specified; otherwise the empty string. */ if (line == NULL) { if (argc == 2) { Jim_SetResultInt(interp, -1); } return JIM_OK; } objPtr = Jim_NewStringObjNoAlloc(interp, line, -1); /* Returns the length of the string if varName was specified */ if (argc == 2) { if (Jim_SetVariable(interp, argv[1], objPtr) != JIM_OK) { Jim_FreeNewObj(interp, objPtr); return JIM_ERR; } Jim_SetResultInt(interp, Jim_Length(objPtr)); } else { Jim_SetResult(interp, objPtr); } return JIM_OK; }
static int aio_cmd_recvfrom(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { AioFile *af = Jim_CmdPrivData(interp); char *buf; union sockaddr_any sa; long len; socklen_t salen = sizeof(sa); int rlen; if (Jim_GetLong(interp, argv[0], &len) != JIM_OK) { return JIM_ERR; } buf = Jim_Alloc(len + 1); rlen = recvfrom(fileno(af->fp), buf, len, 0, &sa.sa, &salen); if (rlen < 0) { Jim_Free(buf); JimAioSetError(interp, NULL); return JIM_ERR; } buf[rlen] = 0; Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, buf, rlen)); if (argc > 1) { /* INET6_ADDRSTRLEN is 46. Add some for [] and port */ char addrbuf[60]; #if IPV6 if (sa.sa.sa_family == PF_INET6) { addrbuf[0] = '['; /* Allow 9 for []:65535\0 */ inet_ntop(sa.sa.sa_family, &sa.sin6.sin6_addr, addrbuf + 1, sizeof(addrbuf) - 9); snprintf(addrbuf + strlen(addrbuf), 8, "]:%d", ntohs(sa.sin.sin_port)); } else #endif { /* Allow 7 for :65535\0 */ inet_ntop(sa.sa.sa_family, &sa.sin.sin_addr, addrbuf, sizeof(addrbuf) - 7); snprintf(addrbuf + strlen(addrbuf), 7, ":%d", ntohs(sa.sin.sin_port)); } if (Jim_SetVariable(interp, argv[1], Jim_NewStringObj(interp, addrbuf, -1)) != JIM_OK) { return JIM_ERR; } } return JIM_OK; }
static int Jim_PosixGethostnameCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { char *buf; int rc = JIM_OK; if (argc != 1) { Jim_WrongNumArgs(interp, 1, argv, ""); return JIM_ERR; } buf = Jim_Alloc(JIM_HOST_NAME_MAX); if (gethostname(buf, JIM_HOST_NAME_MAX) == -1) { Jim_PosixSetError(interp); rc = JIM_ERR; } else { Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, buf, -1)); } return rc; }
static int Jim_Compress(Jim_Interp *interp, const char *in, int len, long level, int wbits) { z_stream strm = {0}; Bytef *buf; if ((level != Z_DEFAULT_COMPRESSION) && ((level < Z_NO_COMPRESSION) || (level > Z_BEST_COMPRESSION))) { Jim_SetResultString(interp, "level must be 0 to 9", -1); return JIM_ERR; } if (deflateInit2(&strm, level, Z_DEFLATED, wbits, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK) { return JIM_ERR; } strm.avail_out = deflateBound(&strm, (uLong)len); if (strm.avail_out > INT_MAX) { deflateEnd(&strm); return JIM_ERR; } buf = (Bytef *)Jim_Alloc((int)strm.avail_out); strm.next_out = buf; strm.next_in = (Bytef *)in; strm.avail_in = (uInt)len; /* always compress in one pass - the return value holds the entire * decompressed data anyway, so there's no reason to do chunked * decompression */ if (deflate(&strm, Z_FINISH) != Z_STREAM_END) { Jim_Free(strm.next_out); deflateEnd(&strm); return JIM_ERR; } deflateEnd(&strm); if (strm.total_out > INT_MAX) { Jim_Free(strm.next_out); return JIM_ERR; } Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, (char *)buf, (int)strm.total_out)); 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; } else { Jim_Free(newname); Jim_SetResultFormatted(interp, "can't normalize \"%#s\": %s", argv[0], strerror(errno)); return JIM_ERR; } #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; /* Simple implementation for now */ for (i = 0; i < argc; i++) { int len; const char *part = Jim_GetString(argv[i], &len); if (*part == '/') { /* Absolute component, so go back to the start */ last = newname; } #if defined(__MINGW32__) || defined(_MSC_VER) else if (strchr(part, ':')) { /* Absolute compontent on mingw, so go back to the start */ last = newname; } #endif else if (part[0] == '.') { if (part[1] == '/') { part += 2; len -= 2; } else if (part[1] == 0 && last != newname) { /* Adding '.' to an existing path does nothing */ continue; } } /* Add a slash if needed */ if (last != newname && last[-1] != '/') { *last++ = '/'; } if (len) { if (last + len - newname >= MAXPATHLEN) { Jim_Free(newname); Jim_SetResultString(interp, "Path too long", -1); return JIM_ERR; } memcpy(last, part, len); last += len; } /* Remove a slash if needed */ if (last > newname + 1 && last[-1] == '/') { *--last = 0; } } *last = 0; /* Probably need to handle some special cases ... */ Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, last - newname)); return JIM_OK; }