FskErr KplDirectoryIteratorGetNext(KplDirectoryIterator dirIt, char **name, UInt32 *itemType) { struct dirent *ent; FskErr err; KplFileInfo finfo; if (!dirIt || !dirIt->theDir) return kFskErrInvalidParameter; ent = readdir(dirIt->theDir); if (!ent) { return kFskErrIteratorComplete; } err = KplFileGetPathInfo((char *)dirIt->root, ent->d_name, &finfo); if (err != kFskErrNone) return err; if (itemType) *itemType = finfo.filetype; if ('.' == ent->d_name[0]) { if ((0 == (dirIt->flags & 1)) || (0 == FskStrCompare(ent->d_name, ".")) || (0 == FskStrCompare(ent->d_name, ".."))) return KplDirectoryIteratorGetNext(dirIt, name, itemType); // skip hidden files } if (name) *name = FskStrDoCopy(ent->d_name); return kFskErrNone; }
void KPR_canvasPattern_setStyle(xsMachine *the) { FskCanvas2dContext ctx = xsGetHostData(xsArg(0)); UInt32 repetition = kFskCanvas2dPatternRepeat; FskConstBitmap bitmap = NULL; Boolean owned = false; xsVars(1); xsVar(0) = xsGet(xsThis, xsID("repetition")); if (xsTest(xsVar(0))) { xsStringValue it = xsToString(xsVar(0)); if (!FskStrCompare(it, "no-repeat")) repetition = kFskCanvas2dPatternRepeatNone; else if (!FskStrCompare(it, "repeat-x")) repetition = kFskCanvas2dPatternRepeatX; else if (!FskStrCompare(it, "repeat-y")) repetition = kFskCanvas2dPatternRepeatY; else if (!FskStrCompare(it, "repeat")) repetition = kFskCanvas2dPatternRepeat; else xsError(kFskErrInvalidParameter); } xsVar(0) = xsGet(xsThis, xsID("image")); if (xsIsInstanceOf(xsVar(0), xsGet(xsGet(xsGlobal, xsID_KPR), xsID_texture))) { KprTexture texture = xsGetHostData(xsVar(0)); bitmap = KprTextureGetBitmap(texture, NULL, &owned); } else { KprContent content = xsGetHostData(xsVar(0)); bitmap = (*content->dispatch->getBitmap)(content, NULL, &owned); } if (!bitmap) xsError(kFskErrInvalidParameter); if (xsTest(xsArg(1))) FskCanvas2dSetStrokeStylePattern(ctx, repetition, bitmap); else FskCanvas2dSetFillStylePattern(ctx, repetition, bitmap); if (!owned) FskBitmapDispose((FskBitmap)bitmap); }
static SInt32 GetFillRule(xsStringValue fillStr) { SInt32 fillRule = kFskCanvas2dFillRuleNonZero; /* Default */ if (fillStr) { if (!FskStrCompare(fillStr, kFskCanvas2dFillRuleStrings[0])) fillRule = kFskCanvas2dFillRuleNonZero; else if (!FskStrCompare(fillStr, kFskCanvas2dFillRuleStrings[1])) fillRule = kFskCanvas2dFillRuleEvenOdd; } return fillRule; }
void xs_i2c_readBlock(xsMachine *the) { FskErr err; xsI2C i2c = xsGetHostData(xsThis); int argc = xsToInteger(xsArgc), i; int format = 2; SInt32 dataSize = xsToInteger(xsArg(0)), readCount; UInt8 data[32]; xsThrowIfNULL(i2c); DBG_I2C("xs_i2c_readBlock\n"); if ((dataSize > 32) || (dataSize <= 0)) xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C readBlock invalid size %d. %s", (int)dataSize, i2c->diagnosticID); FskPinI2CSetAddress(i2c->pin, i2c->address); err = FskPinI2CReadBytes(i2c->pin, dataSize, &readCount, data); if (err) { xsTraceDiagnostic("I2C readBlock failed with error %s %s.", FskInstrumentationGetErrorString(err), i2c->diagnosticID); goto bail; } if (argc > 1) { int t = xsTypeOf(xsArg(1)); if ((xsNumberType == t) || (t == xsIntegerType)) format = xsToInteger(xsArg(1)); else { char *formatString = xsToString(xsArg(1)); if (0 == FskStrCompare(formatString, "Buffer")) format = 2; else if (0 == FskStrCompare(formatString, "Chunk")) format = 0; else if (0 == FskStrCompare(formatString, "Array")) format = 1; } } if (2 == format) { xsResult = xsArrayBuffer(data, readCount); } else if (0 == format) { xsResult = xsNew1(xsGlobal, xsID("Chunk"), xsInteger(readCount)); FskMemMove(xsGetHostData(xsResult), data, readCount); } else if (1 == format) { xsResult = xsNew1(xsGlobal, xsID("Array"), xsInteger(readCount)); for (i = 0; i < readCount; i++) xsSet(xsResult, i, xsInteger(data[i])); } bail: if (err) xsError(err); }
GPIOdirection stringToDirection(xsMachine *the, const char *direction, FskGPIO gpio) { if (0 == FskStrCompare(direction, "input")) return in; else if (0 == FskStrCompare(direction, "output")) return out; else if (0 == FskStrCompare(direction, "undefined")) return undefined; xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "Digital pin %d must specify direction", (int)gpio->pinNum); }
void KPR_system_alert(xsMachine* the) { int argc = xsToInteger(xsArgc); MSGBOXPARAMSW params; xsStringValue string; xsIntegerValue result; xsVars(1); params.cbSize = sizeof(params); params.hwndOwner = NULL; params.hInstance = FskMainGetHInstance(); params.lpszText = NULL; params.lpszCaption = xsStringToWideString("Kinoma Code"); params.dwStyle = MB_ICONSTOP; params.dwContextHelpId = 0; params.lpfnMsgBoxCallback = NULL; params.dwLanguageId = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT); if ((argc > 0) && xsTest(xsArg(0))) { if (xsFindString(xsArg(0), xsID_type, &string)) { if (!FskStrCompare(string, "about")) params.dwStyle = MB_ICONINFORMATION; else if (!FskStrCompare(string, "stop")) params.dwStyle = MB_ICONSTOP; else if (!FskStrCompare(string, "note")) params.dwStyle = MB_ICONEXCLAMATION; } if (xsFindResult(xsArg(0), xsID_prompt)) { xsVar(0) = xsResult; } if (xsFindResult(xsArg(0), xsID_info)) { xsVar(0) = xsCall1(xsVar(0), xsID("concat"), xsString("\n\n")); xsVar(0) = xsCall1(xsVar(0), xsID("concat"), xsResult); } params.lpszText = xsStringToWideString(xsToString(xsVar(0))); if (xsFindResult(xsArg(0), xsID_buttons)) { if (xsIsInstanceOf(xsResult, xsArrayPrototype)) { xsIntegerValue c = xsToInteger(xsGet(xsResult, xsID_length)); if (c == 3) params.dwStyle |= MB_YESNOCANCEL; else if (c == 2) params.dwStyle |= MB_OKCANCEL; else params.dwStyle |= MB_OK; } } } result = MessageBoxIndirectW(¶ms); if (params.lpszText) CoTaskMemFree((LPVOID *)params.lpszText); if (params.lpszCaption) CoTaskMemFree((LPVOID *)params.lpszCaption); if ((argc > 1) && xsTest(xsArg(1))) (void)xsCallFunction1(xsArg(1), xsNull, ((result == IDYES) || (result == IDOK)) ? xsTrue : (result == IDNO) ? xsFalse : xsUndefined); }
FskErr FskFSVolumeGetInfo(UInt32 volumeID, char **pathOut, char **nameOut, UInt32 *volumeType, Boolean *isRemovable, FskInt64 *capacity, FskInt64 *freeSpace) { FskErr err = kFskErrNone; struct statfs *fs; if (volumeID >= (UInt32)gNumStatFS) return kFskErrInvalidParameter; fs = &gStatFS[volumeID]; if (pathOut) *pathOut = FskStrDoCopy(fs->f_mntonname); if (nameOut) *nameOut = FskStrDoCopy(FskCocoaDisplayNameAtPath(fs->f_mntonname)); if (capacity) *capacity = fs->f_blocks * fs->f_bsize; if (freeSpace) *freeSpace = fs->f_bavail * fs->f_bsize; if (isRemovable) *isRemovable = FskCocoaIsRemovable(fs->f_mntonname); if (volumeType) { *volumeType = kFskVolumeTypeUnknown; if (!(fs->f_flags & MNT_LOCAL)) *volumeType = kFskVolumeTypeNetwork; else if (FskStrCompare(fs->f_fstypename, "hfs") == 0 || FskStrCompare(fs->f_fstypename, "ufs") == 0) *volumeType = kFskVolumeTypeFixed; else if (FskStrCompare(fs->f_fstypename, "devfs") == 0) *volumeType = kFskVolumeTypeUnknown; else { char *product; if ((err = FskFSVolumeGetDeviceInfo(volumeID, NULL, &product, NULL, NULL)) != kFskErrNone) return err; if (product == NULL) *volumeType = kFskVolumeTypeUnknown; else if (FskStrStr(product, "MS") || FskStrStr(product, "WM-MS")) *volumeType = kFskVolumeTypeMemoryStick; else if (FskStrStr(product, "MMC")) *volumeType = kFskVolumeTypeMMC; else if (FskStrStr(product, "CF")) *volumeType = kFskVolumeTypeCompactFlash; else if (FskStrStr(product, "SM")) *volumeType = kFskVolumeTypeSmartMedia; else if (FskStrStr(product, "SD")) *volumeType = kFskVolumeTypeSDMemory; else *volumeType = kFskVolumeTypeUnknown; } } return err; }
void KprServiceRegister(KprService service) { KprService *address = &gServices, current; if (!FskStrCompareWithLength(service->id, "xkpr", 4)) { while ((current = *address)) { if (!FskStrCompareWithLength(current->id, "xkpr", 4)) { if (FskStrCompare(current->id, service->id) <= 0) break; } address = &(current->next); } } else { while ((current = *address)) { address = &(current->next); } } service->next = current; *address = service; if (!service->accept) service->accept = KprServiceAccept; if (!service->cancel) service->cancel = KprServiceCancel; if (!service->invoke) service->invoke = KprServiceInvoke; if (!service->start) service->start = KprServiceStart; if (!service->stop) service->stop = KprServiceStop; }
static int KprWebSocketServerValidateRequest(FskHeaders *requestHeaders, FskHeaders *responseHeaders) { FskErr err; char *value; char *decoded = NULL; UInt32 len; int statusCode = 400; value = FskHeaderFind("Upgrade", requestHeaders); if (!value || FskStrCompareCaseInsensitive(value, "websocket") != 0) goto bail; value = FskHeaderFind("Connection", requestHeaders); if (!value || FskStrCompareCaseInsensitive(value, "Upgrade") != 0) goto bail; value = FskHeaderFind("Sec-WebSocket-Version", requestHeaders); if (!value || FskStrCompare(value, "13") != 0) { statusCode = 426; FskHeaderAddString("Sec-WebSocket-Version", "13", responseHeaders); goto bail; } value = FskHeaderFind("Sec-WebSocket-Key", requestHeaders); if (!value) goto bail; bailIfError(FskStrB64Decode(value, FskStrLen(value), &decoded, &len)); if (len != 16) goto bail; statusCode = 101; bail: FskMemPtrDispose(decoded); return statusCode; }
static Boolean KprWebSocketEndpointValidateResponse(KprWebSocketEndpoint self, FskHeaders *response) { FskErr err; char *value; char *encoded = NULL; Boolean result = false; { FskHeaderIterator iter = FskHeaderIteratorNew(response); FskDebugStr("HANDSHAKE: response headers\n"); while (iter) { FskDebugStr("> %s: %s\n", iter->name, iter->value); iter = FskHeaderIteratorNext(iter); } FskHeaderIteratorDispose(iter); } if (response->responseCode != 101) return false; if (!KprWebSocketEndpointCheckHeaderValue(response, "Upgrade", "websocket")) return false; if (!KprWebSocketEndpointCheckHeaderValue(response, "Connection", "Upgrade")) return false; value = FskHeaderFind("Sec-WebSocket-Accept", response); if (!value) return false; bailIfError(KprWebSocketCalculateHash(self->key, &encoded)); result = (FskStrCompare(value, encoded) == 0); bail: if (encoded) FskMemPtrDispose(encoded); return result; }
FskErr KprWebSocketEndpointConnect(KprWebSocketEndpoint self, char *url, char *origin) { FskErr err = kFskErrNone; self->url = FskStrDoCopy(url); bailIfNULL(self->url); bailIfError(FskStrParseUrl(self->url, &self->parts)); if (!KprWebSocketEndpointCheckURL(self)) { bailIfError(kFskErrInvalidParameter); } self->isSecure = (FskStrCompare(self->parts->scheme, "wss") == 0); if (origin) { self->origin = FskStrDoCopy(origin); bailIfNULL(self->origin); } self->state = kKprWebSocketStateConnecting; INVOKE_AFTER1(KprWebSocketEndpointStartConnect, self); bail: return err; }
FskErr FskFSVolumeGetInfoFromPath(const char *pathIn, char **pathOut, char **nameOut, UInt32 *volumeType, Boolean *isRemovable, FskInt64 *capacity, FskInt64 *freeSpace) { FskErr err = kFskErrOperationFailed; int drv = -1; FskAndroidFilesPrintfDebug("FskFSVolumeGetInfoFromPath: pathIn: %s\n", pathIn); if (0 == FskStrCompare("/", pathIn)) drv = 1; else { pMount theMount = gMounts; while (theMount) { int len = FskStrLen(theMount->mountPoint); if (0 == FskStrCompareWithLength(theMount->mountPoint, pathIn, len)) { drv = theMount->fsID; break; } theMount = theMount->next; } } if (drv == -1) { FskAndroidFilesPrintfDebug("FskFSVolumeGetInfoFromPath: pathIn: %s - not found\n", pathIn); return err; } else return FskFSVolumeGetInfo(drv, pathOut, nameOut, volumeType, isRemovable, capacity, freeSpace); }
KprZeroconfBrowser KprZeroconfBrowserFind(KprZeroconfBrowser self, const char* serviceType) { KprZeroconfBrowser browser = self ? self : gZeroconfBrowsers; while (browser && FskStrCompare(browser->serviceType, serviceType)) { browser = (KprZeroconfBrowser)browser->next; } return browser; }
// --------------------------------------------------------------------- SInt32 FskStrEndsWith(const char *s1, const char *s2) { int l1, l2; char *p; if (NULL == s1 && NULL == s2) return 1; l1 = FskStrLen(s1); l2 = FskStrLen(s2); if (l2 > l1) return 0; p = s1 + (l1 - l2); fprintf(stderr, "checking %s [%s] ends with %s - return %d\n", s1, p, s2, FskStrCompare(p, s2)); return FskStrCompare(p, s2); }
KprZeroconfPlatformService KprZeroconfPlatformServiceFindType(KprZeroconfPlatformService self, char* name) { KprZeroconfPlatformService service = self; while (service) { if (!FskStrCompare(service->name, name)) break; service = service->next; } return service; }
pMount volumesContain(char *path) { pMount mnt = gMounts; while (mnt) { if (0 == FskStrCompare(path, mnt->mountPoint)) break; mnt = mnt->next; } return mnt; }
xsIndex fxFindModuleKPR(xsMachine* the, xsIndex moduleID, xsSlot* slot) { char name[1024]; xsBooleanValue absolute, relative; xsStringValue dot, slash; xsIndex id; xsToStringBuffer(*slot, name, sizeof(name)); if ((!FskStrCompareWithLength(name, "./", 2)) || (!FskStrCompareWithLength(name, "../", 3))) { absolute = 0; relative = (moduleID == XS_NO_ID) ? 0 : 1; } else if ((!FskStrCompareWithLength(name, "/", 1))) { FskMemMove(name, name + 1, FskStrLen(name)); absolute = 1; relative = 0; } else { absolute = 1; relative = (moduleID == XS_NO_ID) ? 0 : 1; } slash = FskStrRChr(name, '/'); if (!slash) slash = name; dot = FskStrRChr(slash, '.'); if (dot) { xsBooleanValue known = 0; xsStringValue* extension; for (extension = gxExtensions; *extension; extension++) { if (!FskStrCompare(dot, *extension)) { known = 1; break; } } if (!known) dot = NULL; } if (!dot) dot = name + FskStrLen(name); if (relative) { if (fxFindURI(the, xsName(moduleID), name, dot, &id)) return id; } if (absolute) { xsStringValue* bases = gModulesBases; UInt32 c = gModulesBasesCount; UInt32 i = 1; while (i < c) { if (fxFindURI(the, bases[i], name, dot, &id)) return id; i++; } } return XS_NO_ID; }
extMount extMountsContain(char *path) { extMount mnt = gExtMounts; while (mnt) { if (0 == FskStrCompare(mnt->mountPoint, path)) break; mnt = (extMount)mnt->next; } return mnt; }
// --------------------------------------------------------------------- static FskNetInterfaceRecord *sFskNetInterfaceFindByName(char *name, FskNetInterfaceRecord *list) { FskNetInterfaceRecord *cur = list; while (cur) { if (FskStrCompare(cur->name, name) == 0) return cur; cur = cur->next; } return NULL; }
void xs_i2c_readBlockDataSMB(xsMachine* the) { xsI2C i2c = xsGetHostData(xsThis); FskErr err; char* formatString; int format = 2, i; SInt32 dataSize = 0; UInt8 command = (UInt8)xsToInteger(xsArg(0)); UInt8 data[34]; //needs to be 34 because we're using I2C_SMBUS_I2C_BLOCK_BROKEN in i2cdev.c //@@ WTF - not at this layer, at least SInt32 length = (SInt32)xsToInteger(xsArg(1)); DBG_I2C("xs_i2c_readBlockDataSMB\n"); xsThrowIfNULL(i2c); if ((length < 0) || (length > 32)) xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C readBlockDataSMB bad length %d %s.", length, i2c->diagnosticID); FskPinI2CSetAddress(i2c->pin, i2c->address); formatString = xsToString(xsArg(2)); if (!FskStrCompare(formatString, "Buffer")) format = 2; else if (!FskStrCompare(formatString, "Chunk")) format = 0; else if (!FskStrCompare(formatString, "Array")) format = 1; err = FskPinI2CReadDataBytes(i2c->pin, command, length, &dataSize, data); xsThrowDiagnosticIfFskErr(err, "I2C readBlockDataSMB register %d failed %s.", (int)command, i2c->diagnosticID); if (2 == format) { xsResult = xsArrayBuffer(data, dataSize); } else if (0 == format) { xsResult = xsNew1(xsGlobal, xsID("Chunk"), xsInteger(dataSize)); FskMemMove(xsGetHostData(xsResult), data, dataSize); } else if (1 == format) { xsResult = xsNew1(xsGlobal, xsID("Array"), xsInteger(dataSize)); for (i = 0; i < dataSize; i++) xsSet(xsResult, i, xsInteger(data[i])); } }
static void KPR_canvasRenderingContext2D_set_enum(xsMachine *the, void (*setter)(FskCanvas2dContext, UInt32), xsStringValue* array, UInt32 start, UInt32 stop) { FskCanvas2dContext ctx = xsGetHostData(xsThis); xsStringValue it = xsToString(xsArg(0)); UInt32 value; for (value = start; value <= stop; value++) { if (!FskStrCompare(it, array[value - start])) { (*setter)(ctx, value); break; } } }
FskErr FskFSVolumeGetID(const char *fullPath, UInt32 *volumeID) { int i; for (i = 0; i < gNumStatFS; i++) { if (FskStrCompare(gStatFS[i].f_mntonname, fullPath) == 0) { *volumeID = i; return kFskErrNone; } } return kFskErrInvalidParameter; }
void KprMessageCancelReferrer(char* url) { FskList messages = gShell->messages; KprMessage message = FskListGetNext(messages, NULL); while (message) { KprMessage next = FskListGetNext(messages, message); char* referrer = KprMessageGetRequestHeader(message, "referrer"); if (referrer && !FskStrCompare(referrer, url)) KprMessageCancel(message); message = next; } }
long FAR PASCAL interfaceTrackerProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam) { if (WM_SETTINGCHANGE == msg) { LPCTSTR foo = (LPCTSTR)lParam; if (0 == FskStrCompare("Software\\Microsoft\\Internet Explorer", (const char *)foo)) { FskHTTPSyncSystemProxy(); } } if (gNetworkInterfaceChangedMessage == msg) { sFskHandleNetworkInterfacesChanged(); return 1; } return DefWindowProc(hwnd, msg, wParam, lParam); }
void httpServerInterfaceDown(FskHTTPServer http, char *ifcName) { FskHTTPServerListener cur = http->listeners, next = NULL; FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerInterfaceDown - ifcName: %p\n", ifcName); if (ifcName == NULL) return; while (cur) { next = cur->next; if (0 == FskStrCompare(cur->ifcName, ifcName)) { FskHTTPServerListenerDispose(cur); } cur = next; } }
// --------------------------------------------------------------------- static int sCompareInterfaces(FskNetInterfaceRecord *a, FskNetInterfaceRecord *b) { int ret = -1; if (a->status != b->status) return ret; if (a->ip == b->ip) { if (FskMemCompare(a->MAC, b->MAC, 6) == 0) { if (FskStrCompare(a->name, b->name) == 0) { ret = 0; } } } return ret; }
FskErr FskFSVolumeGetInfoFromPath(const char *pathIn, char **pathOut, char **nameOut, UInt32 *volumeType, Boolean *isRemovable, FskInt64 *capacity, FskInt64 *freeSpace) { int i; FskErr err = kFskErrOperationFailed; if (gStatFS == NULL) updateStatFS(); for (i = 0; i < gNumStatFS; i++) { if (FskStrCompare(gStatFS[i].f_mntonname, pathIn) == 0) { err = FskFSVolumeGetInfo(i, pathOut, nameOut, volumeType, isRemovable, capacity, freeSpace); break; } } return err; }
void fxLoadModule(txMachine* the, txID moduleID) { txArchive* archive = the->archive; txSlot* key = fxGetKey(the, moduleID); txString path = NULL; char buffer[PATH_MAX]; txString dot = NULL; txString* extension; txLoader* loader; KprURLToPath(key->value.key.string, &path); c_strcpy(buffer, path); c_free(path); path = buffer; if (archive) { if (!c_strncmp(path, archive->base, archive->baseLength)) { txInteger c = archive->scriptCount, i; txScript* script = archive->scripts; path += archive->baseLength; #if mxWindows { char* separator = path; while (*separator) { if (*separator == '/') *separator = mxSeparator; separator++; } } #endif for (i = 0; i < c; i++) { if (!c_strcmp(path, script->path)) { fxResolveModule(the, moduleID, script, C_NULL, C_NULL); return; } script++; } } } dot = FskStrRChr(path, '.'); for (extension = gxExtensions, loader = gxLoaders; *extension; extension++, loader++) { if (!FskStrCompare(dot, *extension)) { (**loader)(the, buffer, moduleID); break; } } }
FskErr KplVolumeGetInfoFromPath(const char *pathIn, char **pathOut, char **nameOut, UInt32 *volumeType, Boolean *isRemovable, KplInt64 *capacity, KplInt64 *freeSpace) { volInfo vi; FskErr err = kFskErrOperationFailed; if (!volumeList) scanVolumes(); vi = volumeList; while (vi) { if (0 == FskStrCompare(vi->mountPoint, pathIn)) { err = KplVolumeGetInfo((UInt32)vi, pathOut, nameOut, volumeType, isRemovable, capacity, freeSpace); break; } vi = vi->next; } return err; }
void KprHTTPClientInvoke(KprService service UNUSED, KprMessage message) { FskErr err = kFskErrNone; KprHTTPClient self = gKprHTTPClient; if (KprMessageContinue(message)) { KprHTTPTarget target = NULL; KprHTTPCacheValue cached = NULL; char* value; FskInstrumentedItemSendMessageDebug(message, kprInstrumentedMessageHTTPBegin, message) bailIfError(KprHTTPTargetNew(&target, message)); if (!message->method || !FskStrCompare(message->method, "GET")) KprHTTPCacheFetch(self->cache, message->url, &cached); if (cached) { if (KprHTTPCacheValueIsFresh(cached)) { if (KprHTTPClientReadCache(message, cached) == kFskErrNone) { KprMessageTransform(message, gHTTPService.machine); KprHTTPClientResumeTarget(target); return; } } else { value = FskAssociativeArrayElementGetString(cached->headers, kprHTTPHeaderLastModified); if (value) (void)KprMessageSetRequestHeader(message, kprHTTPHeaderIfModifiedSince, value); value = FskAssociativeArrayElementGetString(cached->headers, kprHTTPHeaderETag); if (value) (void)KprMessageSetRequestHeader(message, kprHTTPHeaderIfNoneMatch, value); target->cached = cached; } } KprHTTPClientCookiesGet(message->url, &value); if (value) { (void)KprMessageSetRequestHeader(message, kprHTTPHeaderCookie, value); FskMemPtrDispose(value); } KprHTTPClientAddTarget(target); return; bail: message->error = err; } FskThreadPostCallback(KprShellGetThread(gShell), (FskThreadCallback)KprMessageComplete, message, NULL, NULL, NULL); }