static FskErr KprWebSocketEndpointUpgradeConnection(KprWebSocketEndpoint self) { FskErr err = kFskErrNone; FskHeaders *request; char buffer[1024], tmp[1024], portStr[10]; int len, port; bailIfError(FskHeaderStructNew(&request)); port = (self->parts->port ? port = self->parts->port : 80); if (port == 80) { FskHeaderAddString("Host", self->parts->host, request); } else { FskStrCopy(tmp, self->parts->host); FskStrCat(tmp, ":"); FskStrNumToStr(port, portStr, 10); FskStrCat(tmp, portStr); FskHeaderAddString("Host", tmp, request); } if (self->origin) { FskHeaderAddString("Origin", self->origin, request); } else { FskStrCopy(tmp, "http://"); FskStrCat(tmp, self->parts->host); FskHeaderAddString("Origin", tmp, request); } FskHeaderAddString("Upgrade", "websocket", request); FskHeaderAddString("Connection", "Upgrade", request); KprWebSocketCreateKey(&self->key); FskHeaderAddString("Sec-WebSocket-Key", self->key, request); FskHeaderAddInteger("Sec-WebSocket-Version", 13, request); FskStrCopy(buffer, "GET "); if (self->parts->path[0] != '/') FskStrCat(buffer, "/"); FskStrCat(buffer, self->parts->path); FskStrCat(buffer, " HTTP/1.1\r\n"); len = FskStrLen(buffer); FskHeaderGenerateOutputBlob(&buffer[len], 1024 - len, true, request); KprSocketWriterSendBytes(self->writer, buffer, FskStrLen(buffer)); bail: return err; }
FskErr FskFSFileRenameDirectory(const char *fullPath, const char *newName) { int err, len; char *p, newPath[PATH_MAX]; FskFileInfo itemInfo; err = sCheckFullPath(fullPath, kFskPathIsDirectory); BAIL_IF_ERR(err); len = FskStrLen(fullPath); if (len < 2) BAIL(kFskErrOperationFailed); // can't rename root err = FskFSFileGetFileInfo(fullPath, &itemInfo); BAIL_IF_ERR(err); if (itemInfo.filetype != kFskDirectoryItemIsDirectory) BAIL(kFskErrNotDirectory); p = FskStrRChr((char *)newName, '/'); if (p) BAIL(kFskErrOperationFailed); // newName contains path elements FskStrCopy(newPath, fullPath); if (newPath[len - 1] == '/') newPath[len - 1] = '\0'; // remove trailing slash p = FskStrRChr(newPath, '/'); if (p) *++p = '\0'; FskStrCat(newPath, newName); err = rename(fullPath, newPath); if (err == -1) BAIL(errnoToFskErr(errno)); err = kFskErrNone; bail: return err; }
void fxReadAddressAutomatic(txMachine* the) { /* read debugAddress and debugAutomatic from a file... */ #if TARGET_OS_ANDROID char *folder = NULL; char *file = FskStrDoCat(folder, "/sdcard/debug.txt"); { #else char *folder; if (kFskErrNone == FskDirectoryGetSpecialPath(kFskDirectorySpecialTypeApplicationPreference, true, NULL, &folder)) { char *file = FskStrDoCat(folder, "debug.txt"); #endif char *data; if (kFskErrNone == FskFileLoad(file, (FskMemPtr *)&data, NULL)) { char *lf = FskStrChr(data, 10); if ((NULL != lf) && (FskStrLen(data) < sizeof(debugAddress))) { *lf = 0; FskStrCopy(debugAddress, data); debugAutomatic = '1' == lf[1]; } FskMemPtrDispose(data); } else { FskECMAScriptGetDebug(&data, NULL, NULL); if (data) { FskStrCopy(debugAddress, data); FskStrCat(debugAddress, ":5002"); debugAutomatic = 1; } } FskMemPtrDispose(file); FskMemPtrDispose(folder); } } void fxSetAddress(txMachine* the, char* theAddress) { c_strcpy(debugAddress, theAddress); fxWriteAddressAutomatic(the); }
FskErr KplFileRenameDirectory(const char *fullPath, const char *newName) { int err, len; char *p, newPath[PATH_MAX]; KplFileInfo itemInfo; err = sCheckFullPath(fullPath, kKplPathIsDirectory); if (err) return err; len = FskStrLen(fullPath); if (len < 2) return kFskErrOperationFailed; // can't rename root err = KplFileGetFileInfo(fullPath, &itemInfo); if (err) return err; if (itemInfo.filetype != kKplDirectoryItemIsDirectory) return kFskErrNotDirectory; p = FskStrRChr((char *)newName, '/'); if (p) return kFskErrOperationFailed; // newName contains path elements FskStrCopy(newPath, fullPath); if (newPath[len - 1] == '/') newPath[len - 1] = '\0'; // remove trailing slash p = FskStrRChr(newPath, '/'); if (p) *++p = '\0'; FskStrCat(newPath, newName); err = rename(fullPath, newPath); if (err == -1) return errnoToFskErr(errno); else return kFskErrNone; }
// text void KPR_canvasRenderingContext2D_get_font(xsMachine *the) { FskCanvas2dContext ctx = xsGetHostData(xsThis); const struct FskFontAttributes* font = FskCanvas2dGetFont(ctx); char buffer[1024] = ""; if (font->style == kFskFontStyleItalic) FskStrCat(buffer, "italic "); else if (font->style == kFskFontStyleOblique) FskStrCat(buffer, "oblique "); if (font->weight == kFskFontWeightBold) FskStrCat(buffer, "bold "); else if (font->weight != kFskFontWeightNormal) { FskStrNumToStr(font->weight, buffer + FskStrLen(buffer), sizeof(buffer) - FskStrLen(buffer)); FskStrCat(buffer, " "); } if (font->variant == kFskFontVariantSmallCaps) FskStrCat(buffer, "small-caps "); FskStrNumToStr((SInt32)(font->size), buffer + FskStrLen(buffer), sizeof(buffer) - FskStrLen(buffer)); FskStrCat(buffer, "px "); FskStrCat(buffer, font->family); xsResult = xsString(buffer); }
void KprFILEServiceInvoke(KprService service UNUSED, KprMessage message) { FskErr err = kFskErrNone; char* path = NULL; FskFileInfo info; FskDirectoryIterator iterator = NULL; char* pathName = NULL; char* sniff = NULL; FskFile fref = NULL; char *name = NULL; if (KprMessageContinue(message)) { if (!message->method || FskStrCompare(message->method, "GET")) { bailIfError(KprURLToPath(message->url, &path)); bailIfError(FskFileGetFileInfo(path, &info)); if (kFskDirectoryItemIsDirectory == info.filetype) { unsigned char buffer[4096]; UInt32 itemType; double date; UInt32 size; xsBeginHostSandboxCode(gFILEService.machine, NULL); { xsVars(3); { xsTry { xsVar(0) = xsGet(xsGlobal, xsID("Files")); xsResult = xsNewInstanceOf(xsArrayPrototype); bailIfError(FskDirectoryIteratorNew(path, &iterator, 0)); while (kFskErrNone == FskDirectoryIteratorGetNext(iterator, &name, &itemType)) { if (name[0] == '.') { FskMemPtrDisposeAt(&name); continue; } if (kFskDirectoryItemIsFile == itemType) { pathName = FskStrDoCat(path, name); bailIfError(FskFileGetFileInfo(pathName, &info)); bailIfError(FskFileOpen(pathName, kFskFilePermissionReadOnly, &fref)); bailIfError(FskFileRead(fref, sizeof(buffer), buffer, &size)); FskFileClose(fref); fref = NULL; if (kFskErrNone == FskMediaPlayerSniffForMIME(buffer, size, NULL, pathName, &sniff)) { } else if (kFskErrNone == FskImageDecompressSniffForMIME(buffer, size, NULL, pathName, &sniff)) { } FskMemPtrDispose(pathName); pathName = NULL; } xsVar(1) = xsNewInstanceOf(xsObjectPrototype); xsNewHostProperty(xsVar(1), xsID("name"), xsString(name), xsDefault, xsDontScript); xsNewHostProperty(xsVar(1), xsID("path"), xsString(name), xsDefault, xsDontScript); FskStrCopy((char*)buffer, message->url); FskStrCat((char*)buffer, name); if (kFskDirectoryItemIsDirectory == itemType) { xsVar(2) = xsGet(xsVar(0), xsID("directoryType")); FskStrCat((char*)buffer, "/"); } else if (kFskDirectoryItemIsFile == itemType) { xsVar(2) = xsGet(xsVar(0), xsID("fileType")); if (info.fileModificationDate > info.fileCreationDate) date = info.fileModificationDate * 1000.0; else date = info.fileCreationDate * 1000.0; xsNewHostProperty(xsVar(1), xsID("date"), xsNumber(date), xsDefault, xsDontScript); xsNewHostProperty(xsVar(1), xsID("size"), xsNumber(info.filesize), xsDefault, xsDontScript); if (sniff) { xsNewHostProperty(xsVar(1), xsID("mime"), xsString(sniff), xsDefault, xsDontScript); FskMemPtrDispose(sniff); sniff = NULL; } } else xsVar(2) = xsGet(xsVar(0), xsID("linkType")); xsNewHostProperty(xsVar(1), xsID("type"), xsVar(2), xsDefault, xsDontScript); xsNewHostProperty(xsVar(1), xsID("url"), xsString((char*)buffer), xsDefault, xsDontScript); (void)xsCall1(xsResult, xsID("push"), xsVar(1)); FskMemPtrDisposeAt(&name); } xsResult = xsCall1(xsGet(xsGlobal, xsID("JSON")), xsID("stringify"), xsResult); message->response.body = FskStrDoCopy(xsToString(xsResult)); message->response.size = FskStrLen(message->response.body); KprMessageTransform(message, gFILEService.machine); } xsCatch { } } } xsEndHostSandboxCode(); } else if (kFskDirectoryItemIsFile == info.filetype) {
static void httpProcessRequestHeaders(FskHTTPServerRequest request) { char *str; FskHeaders* headers = request->requestHeaders; UInt32 version = FskHeaderHTTPVersion(headers); char* host = FskHeaderFind(kFskStrHost, headers); char* uri = FskHeaderURI(headers); char* filename = FskHeaderFilename(headers); request->state = kHTTPReadRequestBody; if (FskStrCompareWithLength(uri, "http://", 7) == 0) { // remove host from filename char* p = FskStrStr(filename, "://") + 3; p = FskStrChr(p, '/') + 1; FskMemMove(filename, p, FskStrLen(p) + 1); } else { if (host) { if (FskMemPtrNewClear(FskStrLen(host) + FskStrLen(uri) + 9, &str) != kFskErrNone) headers->responseCode = 500; else { FskStrCat(str, "http://"); FskStrCat(str, host); FskStrCat(str, "/"); FskStrCat(str, headers->URI); FskMemPtrDispose(headers->URI); headers->URI = str; } } else if (version >= kFskHTTPVersion1dot1) headers->responseCode = 400; else if (version == kFskHTTPVersion1dot0) { if (FskMemPtrNewClear(FskStrLen(uri) + 9, &str) != kFskErrNone) headers->responseCode = 500; else { FskStrCat(str, "http:///"); FskStrCat(str, headers->URI); FskMemPtrDispose(headers->URI); headers->URI = str; } } } str = FskHeaderFind(kFskStrConnection, request->requestHeaders); if (str && FskStrCompareCaseInsensitiveWithLength(str, kFskStrClose, 5) == 0) request->keepAlive = false; else request->keepAlive = true; str = FskHeaderFind(kFskStrContentLength, request->requestHeaders); if (str) { request->requestBodyContentLength = FskStrToNum(str); request->stats.expectedBytesToReceive = FskStrToNum(str); } else request->stats.expectedBytesToReceive = 0; str = FskHeaderFind(kFskStrTransferEncoding, request->requestHeaders); if (str && (FskStrCompareCaseInsensitiveWithLength(str, kFskStrChunked, FskStrLen(kFskStrChunked)) == 0)) request->requestBodyChunked = true; else request->requestBodyChunked = false; doCallCondition(request->http->callbacks->requestCondition, request, kFskHTTPConditionRequestReceivedRequestHeaders, request->refCon); if (NULL != (str = FskHeaderFind(kFskStrExpect, request->requestHeaders))) { if (0 == FskStrCompareCaseInsensitive(kFskStr100Continue, str)) request->state = kHTTPFulfillExpectation; else request->state = kHTTPDenyExpectation; } }
// ------------------------------------------------------------------------ static int sParseStartLine(char *startLine, UInt16 headerType, FskHeaders *headers) { FskErr err; int l; const char *p; char *c = startLine; char *firstPart; // Get method or protocol p = c; c = FskStrChr(c, ' '); if (!c) return -1; l = (c++) - p; err = FskMemPtrNew(l+1, &firstPart); if (err != kFskErrNone) return -1; FskStrNCopy(firstPart, p, l); firstPart[l] = '\0'; if (kFskHeaderTypeResponse == headerType) headers->protocol = firstPart; else headers->method = firstPart; c = FskStrStripHeadSpace(c); // skip over space headers->headerType = headerType; if (kFskHeaderTypeResponse == headerType) { // Get response code and message (if message not in HTTP_Responses) headers->responseCode = FskStrToNum(c); if (headers->flags & kFskHeadersNonStandardResponseReasonPhrase) { c = FskStrChr(c, ' '); if (c) { char *r, *s; s = FskStrStripHeadSpace(c); r = FskFindResponse(headers->responseCode); if (!r || (0 != FskStrCompareCaseInsensitiveWithLength(s, r, FskStrLen(r)))) { headers->responseReasonPhrase = FskStrDoCopy(s); if (NULL != headers->responseReasonPhrase) FskStrStripTailSpace(headers->responseReasonPhrase); } } } } else { char *s, *t = NULL; char *uri = NULL; // Get URI if ((*c == '/') && !(headers->flags & kFskHeadersDoNotStripURILeadingSlash)) c++; s = FskStrChr(c, ' '); if (!s) { headers->responseCode = 400; return -1; } headers->protocol = FskStrDoCopy(s + 1); if (NULL != headers->protocol) FskStrStripTailSpace(headers->protocol); BAIL_IF_ERR(FskMemPtrNew((s-c)+1, &uri)); BAIL_IF_ERR(FskMemPtrNew((s-c)+1, &t)); FskMemCopy(uri, c, s-c); uri[s-c] = '\0'; s = FskStrChr(uri, '?'); if (s) *s = 0; FskStrDecodeEscapedChars(uri, t); if (s) { *s = '?'; FskStrCat(t, s); } headers->URI = FskStrDoCopy(t); // Break URI into filename and parameters s = FskStrChr(t, '?'); if (!s) { headers->filename = FskStrDoCopy(t); } else { // URI has parameters *s++ = '\0'; // cap off the filename headers->filename = FskStrDoCopy(t); headers->parameters = FskAssociativeArrayNew(); while (s) { char *name = s; char *value = FskStrChr(name, '='); if (!value) break; s = FskStrChr(value, '&'); *value++ = '\0'; // cap off the name if (s) *s++ = '\0'; // cap off the value FskAssociativeArrayElementSetString(headers->parameters, name, value); } } bail: FskMemPtrDispose(uri); FskMemPtrDispose(t); } return headers->headerType; }
FskErr FskEnvironmentInitialize(void) { char *appPath; gEnvironment = FskAssociativeArrayNew(); appPath = FskGetApplicationPath(); FskEnvironmentSet("applicationPath", appPath); FskMemPtrDispose(appPath); #if TARGET_OS_KPL KplEnvironmentInitialize(gEnvironment); #elif TARGET_OS_ANDROID FskEnvironmentSet("application", "PLAY"); #elif TARGET_OS_WIN32 || TARGET_OS_MAC || TARGET_OS_LINUX FskEnvironmentSet("application", FSK_APPLICATION); #else FskEnvironmentSet("application", "PLAY"); #endif #if TARGET_OS_WIN32 { char name[256], *nameTemp = NULL; UInt16 nameW[256]; char num[32]; DWORD nameSize = sizeof(nameW) / sizeof(UInt16); EXTENDED_NAME_FORMAT exNameFormat = NameSamCompatible; if (GetUserNameExW(exNameFormat, (LPWSTR)nameW, &nameSize)) { FskTextUnicode16LEToUTF8(nameW, nameSize * 2, &nameTemp, NULL); FskStrCopy(name, nameTemp); FskEnvironmentSet("loginName", name); FskMemPtrDispose(nameTemp); } FskEnvironmentSet("OS", "Windows"); FskStrNumToStr(gWindowsVersionInfo.dwMajorVersion, name, sizeof(name)); FskStrCat(name, "."); FskStrNumToStr(gWindowsVersionInfo.dwMinorVersion, num, sizeof(num)); FskStrCat(name, num); FskEnvironmentSet("OSVersion", name); } #elif TARGET_OS_MAC { struct utsname un; char name[256], *model; SInt32 gen; #if TARGET_OS_IPHONE FskEnvironmentSet("OS", "iPhone"); #else FskEnvironmentSet("OS", "Mac"); #endif FskCocoaSystemGetVersion(name); FskEnvironmentSet("OSVersion", name); if (uname(&un) == 0) { model = un.machine; if (FskStrCompareWithLength(model, "iPhone", 6) == 0) gen = FskStrToNum(model + 6); else if (FskStrCompareWithLength(model, "iPad", 4) == 0) { gen = FskStrToNum(model + 4); if (gen == 3) { SInt32 minor = FskStrToNum(model + 6); if (minor == 4) /* 4th gen */ gen = 5; else gen = 4; /* Only the 3rd gen iPad doesn't follow the numbering system */ } else gen += 2; } else if (FskStrCompareWithLength(model, "iPod", 4) == 0) { gen = FskStrToNum(model + 4); if (gen > 1) --gen; } else gen = 99; } else { model = "unknown"; gen = 99; } FskEnvironmentSet("Model", model); FskStrNumToStr(gen, name, sizeof(name)); FskEnvironmentSet("Generation", name); } #elif TARGET_OS_LINUX { struct utsname name; uname(&name); if (getlogin()) FskEnvironmentSet("loginName", getlogin()); else FskEnvironmentSet("loginName", "User"); FskEnvironmentSet("OS", name.sysname); FskEnvironmentSet("OSVersion", name.release); //@@ } #endif return kFskErrNone; }
char *FskEnvironmentApply(char *input) { FskErr err; char *p; char *out = NULL; char *start, *end; UInt32 outCount = 0; char tempName[256]; UInt32 nameLen; char *value; Boolean doApply = false; if (NULL == input) goto bail; if ('"' == *input) { // special case for string literal - useful when there is leading or trailing white space or [ or ] in the string UInt32 len = FskStrLen(input); if ('"' == input[len - 1]) { err = FskMemPtrNew(len - 1, &out); BAIL_IF_ERR(err); out[len - 2] = 0; FskMemMove(out, input + 1, len - 2); goto bail; } } // scan p = input; while (true) { start = FskStrChr(p, '['); if (NULL == start) { outCount += FskStrLen(p); break; } outCount += start - p; end = FskStrChr(start + 1, ']'); if (NULL == end) { outCount += FskStrLen(start); break; } nameLen = end - start - 1; if (nameLen > (sizeof(tempName) - 1)) goto bail; FskMemMove(tempName, start + 1, nameLen); tempName[nameLen] = 0; value = FskEnvironmentGet(tempName); outCount += FskStrLen(value); doApply = true; p = end + 1; } if (!doApply) goto bail; // replace err = FskMemPtrNew(outCount + 1, &out); BAIL_IF_ERR(err); out[0] = 0; p = input; while (true) { start = FskStrChr(p, '['); if (NULL == start) { FskStrCat(out, p); break; } outCount += start - p; end = FskStrChr(start + 1, ']'); if (NULL == end) { FskStrCat(out, start); break; } FskStrNCat(out, p, start - p); nameLen = end - start - 1; FskMemMove(tempName, start + 1, nameLen); tempName[nameLen] = 0; FskStrCat(out, FskEnvironmentGet(tempName)); p = end + 1; } bail: return out; }
FskErr FskFSDirectoryGetSpecialPath(UInt32 type, const Boolean create, const char *volumeName, char **fullPath) { FskErr err = kFskErrFileNotFound; FskFileInfo finfo; char *tmp = NULL, *specialDir = NULL; char *dataDir = gAndroidCallbacks->getStaticDataDirCB(); char *externalDir = gAndroidCallbacks->getStaticExternalDirCB(); Boolean doCreate = create; *fullPath = NULL; FskAndroidFilesPrintfDebug("for SpecialPath - type %d, use dataDir as %s (volumeName %s)\n", type, dataDir, volumeName); switch (type & ~kFskDirectorySpecialTypeSharedFlag) { case kFskDirectorySpecialTypeDownload: if (androidSystemDownloadsDir) tmp = FskStrDoCat(androidSystemDownloadsDir, "/"); else if (externalDir) tmp = FskStrDoCat(externalDir, "/Kinoma/Downloads/"); else BAIL(kFskErrNotDirectory); break; case kFskDirectorySpecialTypeDocument: doCreate = true; if (externalDir) tmp = FskStrDoCat(externalDir, "/"); else if (androidSystemDownloadsDir) tmp = FskStrDoCat(androidSystemDownloadsDir, "/"); else specialDir = "Download"; break; case kFskDirectorySpecialTypePhoto: if (androidSystemPicturesDir) tmp = FskStrDoCat(androidSystemPicturesDir, "/"); else specialDir = "Pictures"; break; case kFskDirectorySpecialTypeMusic: if (androidSystemMusicDir) tmp = FskStrDoCat(androidSystemMusicDir, "/"); else specialDir = "Music"; break; case kFskDirectorySpecialTypeVideo: if (androidSystemMoviesDir) tmp = FskStrDoCat(androidSystemMoviesDir, "/"); else specialDir = "Movies"; break; case kFskDirectorySpecialTypeTV: specialDir = "TV"; break; case kFskDirectorySpecialTypeApplicationPreference: *fullPath = FskStrDoCat(dataDir, "kinoma/"); err = FskFSFileCreateDirectory(*fullPath); err = kFskErrNone; goto makeit; case kFskDirectorySpecialTypeTemporary: *fullPath = FskStrDoCat(dataDir, "tmp/"); err = FskFSFileCreateDirectory(*fullPath); err = kFskErrNone; goto makeit; case kFskDirectorySpecialTypeCache: *fullPath = FskStrDoCat(dataDir, "tmp/"); err = FskFSFileCreateDirectory(*fullPath); err = kFskErrNone; goto makeit; default: FskAndroidFilesPrintfDebug("SpecialDirectory - bad special directory\n"); BAIL(kFskErrInvalidParameter); } if (specialDir) tmp = FskStrDoCopy(FskEnvironmentGet(specialDir)); if (!tmp) { char *home; home = dataDir; err = FskMemPtrNewClear(FskStrLen(home) + FskStrLen(specialDir) + 3, (FskMemPtr*)(void*)&tmp); BAIL_IF_ERR(err); FskStrCopy(tmp, home); if (tmp[FskStrLen(tmp)-1] != '/') FskStrCat(tmp, "/"); if (specialDir) { FskStrCat(tmp, specialDir); FskStrCat(tmp, "/"); } } FskAndroidFilesPrintfDebug("looking for %s - got %s", specialDir, tmp); *fullPath = tmp; makeit: if (doCreate) { err = FskFSFileCreateDirectory(*fullPath); } else { err = FskFSFileGetFileInfo(*fullPath, &finfo); if (kFskErrNone == err) { if (kFskDirectoryItemIsDirectory != finfo.filetype) BAIL(kFskErrNotDirectory); } } bail: if (kFskErrFileExists == err) { err = kFskErrNone; FskAndroidFilesPrintfDebug("DIRECTORY EXISTS specialDirectory - looking for type %d - got [%s]", type, *fullPath); } else if (kFskErrNone != err) { FskAndroidFilesPrintfDebug("DIRECGOTRY DIDN'T EXIST - specialDirectory - looking for type %d - got [%s] err: %d", type, *fullPath, err); } return err; }