From: Jay Freeman (saurik) Date: Sat, 10 Oct 2009 14:41:59 +0000 (+0000) Subject: Moved HTTP server to its own file, implemented toJSON support, split off CYON from... X-Git-Tag: v0.9.432~363 X-Git-Url: https://git.saurik.com/cycript.git/commitdiff_plain/b4aa79afea0c26718af8880c3ee8fea63eb21563?hp=e0dc20ec507bb66f77da27c196c62d16b5e417c7 Moved HTTP server to its own file, implemented toJSON support, split off CYON from JSON, changed cy to a more general cy, added copyright notices, and optimized string serialization (using correct quoting as appropriate for single/double quote density). --- diff --git a/Application.mm b/Application.mm index 4982830..46b24ac 100644 --- a/Application.mm +++ b/Application.mm @@ -1,3 +1,42 @@ +/* Cycript - Remove Execution Server and Disassembler + * Copyright (C) 2009 Jay Freeman (saurik) +*/ + +/* Modified BSD License {{{ */ +/* + * Redistribution and use in source and binary + * forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the + * above copyright notice, this list of conditions + * and the following disclaimer. + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions + * and the following disclaimer in the documentation + * and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse + * or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* }}} */ + #define _GNU_SOURCE #include @@ -48,7 +87,7 @@ void Run(const char *code, FILE *fout) { _pooled CYPool pool; const char *json; - json = CYPoolJSONString(pool, context, result, &exception); + json = CYPoolCYONString(pool, context, result, &exception); if (exception != NULL) goto error; diff --git a/Cycript.y b/Cycript.y index cef2a42..a82e7f8 100644 --- a/Cycript.y +++ b/Cycript.y @@ -1,3 +1,42 @@ +/* Cycript - Remove Execution Server and Disassembler + * Copyright (C) 2009 Jay Freeman (saurik) +*/ + +/* Modified BSD License {{{ */ +/* + * Redistribution and use in source and binary + * forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the + * above copyright notice, this list of conditions + * and the following disclaimer. + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions + * and the following disclaimer in the documentation + * and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse + * or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* }}} */ + %code top { #include "Cycript.tab.hh" #define scanner driver.scanner_ diff --git a/Library.mm b/Library.mm index e43194f..64f7562 100644 --- a/Library.mm +++ b/Library.mm @@ -1,4 +1,4 @@ -/* Cyrker - Remove Execution Server and Disassembler +/* Cycript - Remove Execution Server and Disassembler * Copyright (C) 2009 Jay Freeman (saurik) */ @@ -53,8 +53,6 @@ #include #include -#include - #include #include @@ -113,19 +111,16 @@ static JSClassRef Struct_; static JSObjectRef Array_; static JSObjectRef Function_; -static JSStringRef name_; -static JSStringRef message_; static JSStringRef length_; +static JSStringRef message_; +static JSStringRef name_; +static JSStringRef toCYON_; +static JSStringRef toJSON_; static Class NSCFBoolean_; static NSArray *Bridge_; -struct Client { - CFHTTPMessageRef message_; - CFSocketRef socket_; -}; - struct CYData { apr_pool_t *pool_; @@ -407,12 +402,18 @@ JSValueRef CYJSUndefined(JSContextRef context) { @end @interface NSObject (Cycript) -- (bool) cy$isUndefined; -- (NSString *) cy$toJSON; + +- (JSType) cy$JSType; + +- (NSObject *) cy$toJSON:(NSString *)key; +- (NSString *) cy$toCYON; + - (JSValueRef) cy$JSValueInContext:(JSContextRef)context transient:(bool)transient; + - (NSObject *) cy$getProperty:(NSString *)name; - (bool) cy$setProperty:(NSString *)name to:(NSObject *)value; - (bool) cy$deleteProperty:(NSString *)name; + @end @interface NSString (Cycript) @@ -425,14 +426,18 @@ JSValueRef CYJSUndefined(JSContextRef context) { @implementation NSObject (Cycript) -- (bool) cy$isUndefined { - return false; +- (JSType) cy$JSType { + return kJSTypeObject; } -- (NSString *) cy$toJSON { +- (NSObject *) cy$toJSON:(NSString *)key { return [self description]; } +- (NSString *) cy$toCYON { + return [[self cy$toJSON:@""] cy$toCYON]; +} + - (JSValueRef) cy$JSValueInContext:(JSContextRef)context transient:(bool)transient { return CYMakeInstance(context, self, transient); } @@ -457,11 +462,15 @@ JSValueRef CYJSUndefined(JSContextRef context) { @implementation WebUndefined (Cycript) -- (bool) cy$isUndefined { - return true; +- (JSType) cy$JSType { + return kJSTypeUndefined; +} + +- (NSObject *) cy$toJSON:(NSString *)key { + return self; } -- (NSString *) cy$toJSON { +- (NSString *) cy$toCYON { return @"undefined"; } @@ -473,7 +482,15 @@ JSValueRef CYJSUndefined(JSContextRef context) { @implementation NSNull (Cycript) -- (NSString *) cy$toJSON { +- (JSType) cy$JSType { + return kJSTypeNull; +} + +- (NSObject *) cy$toJSON:(NSString *)key { + return self; +} + +- (NSString *) cy$toCYON { return @"null"; } @@ -481,7 +498,7 @@ JSValueRef CYJSUndefined(JSContextRef context) { @implementation NSArray (Cycript) -- (NSString *) cy$toJSON { +- (NSString *) cy$toCYON { NSMutableString *json([[[NSMutableString alloc] init] autorelease]); [json appendString:@"["]; @@ -491,8 +508,8 @@ JSValueRef CYJSUndefined(JSContextRef context) { [json appendString:@","]; else comma = true; - if (![object cy$isUndefined]) - [json appendString:[object cy$toJSON]]; + if ([object cy$JSType] != kJSTypeUndefined) + [json appendString:[object cy$toCYON]]; else { [json appendString:@","]; comma = false; @@ -539,7 +556,7 @@ JSValueRef CYJSUndefined(JSContextRef context) { @implementation NSDictionary (Cycript) -- (NSString *) cy$toJSON { +- (NSString *) cy$toCYON { NSMutableString *json([[[NSMutableString alloc] init] autorelease]); [json appendString:@"({"]; @@ -549,10 +566,10 @@ JSValueRef CYJSUndefined(JSContextRef context) { [json appendString:@","]; else comma = true; - [json appendString:[key cy$toJSON]]; + [json appendString:[key cy$toCYON]]; [json appendString:@":"]; NSObject *object([self objectForKey:key]); - [json appendString:[object cy$toJSON]]; + [json appendString:[object cy$toCYON]]; } [json appendString:@"})"]; @@ -585,12 +602,21 @@ JSValueRef CYJSUndefined(JSContextRef context) { @implementation NSNumber (Cycript) -- (NSString *) cy$toJSON { - return [self class] != NSCFBoolean_ ? [self stringValue] : [self boolValue] ? @"true" : @"false"; +- (JSType) cy$JSType { + // XXX: this just seems stupid + return [self class] == NSCFBoolean_ ? kJSTypeBoolean : kJSTypeNumber; +} + +- (NSObject *) cy$toJSON:(NSString *)key { + return self; +} + +- (NSString *) cy$toCYON { + return [self cy$JSType] != kJSTypeBoolean ? [self stringValue] : [self boolValue] ? @"true" : @"false"; } - (JSValueRef) cy$JSValueInContext:(JSContextRef)context transient:(bool)transient { - return [self class] != NSCFBoolean_ ? CYCastJSValue(context, [self doubleValue]) : CYCastJSValue(context, [self boolValue]); + return [self cy$JSType] != kJSTypeBoolean ? CYCastJSValue(context, [self doubleValue]) : CYCastJSValue(context, [self boolValue]); } - (void *) cy$symbol { @@ -601,7 +627,15 @@ JSValueRef CYJSUndefined(JSContextRef context) { @implementation NSString (Cycript) -- (NSString *) cy$toJSON { +- (JSType) cy$JSType { + return kJSTypeString; +} + +- (NSObject *) cy$toJSON:(NSString *)key { + return self; +} + +- (NSString *) cy$toCYON { CFMutableStringRef json(CFStringCreateMutableCopy(kCFAllocatorDefault, 0, (CFStringRef) self)); CFStringFindAndReplace(json, CFSTR("\\"), CFSTR("\\\\"), CFRangeMake(0, CFStringGetLength(json)), 0); @@ -630,6 +664,8 @@ JSValueRef CYJSUndefined(JSContextRef context) { - (id) initWithJSObject:(JSObjectRef)object inContext:(JSContextRef)context; +- (NSString *) cy$toJSON:(NSString *)key; + - (NSUInteger) count; - (id) objectForKey:(id)key; - (NSEnumerator *) keyEnumerator; @@ -674,7 +710,9 @@ apr_status_t CYPoolRelease_(void *data) { } id CYPoolRelease(apr_pool_t *pool, id object) { - if (pool == NULL) + if (object == nil) + return nil; + else if (pool == NULL) return [object autorelease]; else { apr_pool_cleanup_register(pool, object, &CYPoolRelease_, &apr_pool_cleanup_null); @@ -938,6 +976,18 @@ void CYThrow(JSContextRef context, id error, JSValueRef *exception) { *exception = CYCastJSValue(context, error); } +JSValueRef CYCallAsFunction(JSContextRef context, JSObjectRef function, JSObjectRef _this, size_t count, JSValueRef arguments[]) { + JSValueRef exception(NULL); + JSValueRef value(JSObjectCallAsFunction(context, function, _this, count, arguments, &exception)); + CYThrow(context, exception); + return value; +} + +bool CYIsCallable(JSContextRef context, JSValueRef value) { + // XXX: this isn't actually correct + return value != NULL && JSValueIsObject(context, value); +} + @implementation CYJSObject - (id) initWithJSObject:(JSObjectRef)object inContext:(JSContextRef)context { @@ -947,6 +997,28 @@ void CYThrow(JSContextRef context, id error, JSValueRef *exception) { } return self; } +- (NSObject *) cy$toJSON:(NSString *)key { + JSValueRef toJSON(CYGetProperty(context_, object_, toJSON_)); + if (!CYIsCallable(context_, toJSON)) + return [super cy$toJSON:key]; + else { + JSValueRef arguments[1] = {CYCastJSValue(context_, key)}; + JSValueRef value(CYCallAsFunction(context_, (JSObjectRef) toJSON, object_, 1, arguments)); + // XXX: do I really want an NSNull here?! + return CYCastNSObject(NULL, context_, value) ?: [NSNull null]; + } +} + +- (NSString *) cy$toCYON { + JSValueRef toCYON(CYGetProperty(context_, object_, toCYON_)); + if (!CYIsCallable(context_, toCYON)) + return [super cy$toCYON]; + else { + JSValueRef value(CYCallAsFunction(context_, (JSObjectRef) toCYON, object_, 0, NULL)); + return CYCastNSString(NULL, CYJSString(context_, value)); + } +} + - (NSUInteger) count { JSPropertyNameArrayRef names(JSObjectCopyPropertyNames(context_, object_)); size_t size(JSPropertyNameArrayGetCount(names)); @@ -1000,96 +1072,23 @@ void CYThrow(JSContextRef context, id error, JSValueRef *exception) { @end -CFStringRef CYCopyJSONString(JSContextRef context, JSValueRef value, JSValueRef *exception) { +CFStringRef CYCopyCYONString(JSContextRef context, JSValueRef value, JSValueRef *exception) { CYTry { CYPoolTry { - id object(CYCastNSObject(NULL, context, value)); - return reinterpret_cast([(object == nil ? @"null" : [object cy$toJSON]) retain]); + id object(CYCastNSObject(NULL, context, value) ?: [NSNull null]); + return reinterpret_cast([[object cy$toCYON] retain]); } CYPoolCatch(NULL) } CYCatch } -const char *CYPoolJSONString(apr_pool_t *pool, JSContextRef context, JSValueRef value, JSValueRef *exception) { - if (NSString *json = (NSString *) CYCopyJSONString(context, value, exception)) { +const char *CYPoolCYONString(apr_pool_t *pool, JSContextRef context, JSValueRef value, JSValueRef *exception) { + if (NSString *json = (NSString *) CYCopyCYONString(context, value, exception)) { const char *string(CYPoolCString(pool, json)); [json release]; return string; } else return NULL; } -static void OnData(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *value, void *info) { - switch (type) { - case kCFSocketDataCallBack: - CFDataRef data(reinterpret_cast(value)); - Client *client(reinterpret_cast(info)); - - if (client->message_ == NULL) - client->message_ = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, TRUE); - - if (!CFHTTPMessageAppendBytes(client->message_, CFDataGetBytePtr(data), CFDataGetLength(data))) - CFLog(kCFLogLevelError, CFSTR("CFHTTPMessageAppendBytes()")); - else if (CFHTTPMessageIsHeaderComplete(client->message_)) { - CFURLRef url(CFHTTPMessageCopyRequestURL(client->message_)); - Boolean absolute; - CFStringRef path(CFURLCopyStrictPath(url, &absolute)); - CFRelease(client->message_); - - CFStringRef code(CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault, path, CFSTR(""))); - CFRelease(path); - - JSStringRef script(JSStringCreateWithCFString(code)); - CFRelease(code); - - JSValueRef result(JSEvaluateScript(CYGetJSContext(), script, NULL, NULL, 0, NULL)); - JSStringRelease(script); - - CFHTTPMessageRef response(CFHTTPMessageCreateResponse(kCFAllocatorDefault, 200, NULL, kCFHTTPVersion1_1)); - CFHTTPMessageSetHeaderFieldValue(response, CFSTR("Content-Type"), CFSTR("application/json; charset=utf-8")); - - CFStringRef json(CYCopyJSONString(CYGetJSContext(), result, NULL)); - CFDataRef body(CFStringCreateExternalRepresentation(kCFAllocatorDefault, json, kCFStringEncodingUTF8, NULL)); - CFRelease(json); - - CFStringRef length(CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"), CFDataGetLength(body))); - CFHTTPMessageSetHeaderFieldValue(response, CFSTR("Content-Length"), length); - CFRelease(length); - - CFHTTPMessageSetBody(response, body); - CFRelease(body); - - CFDataRef serialized(CFHTTPMessageCopySerializedMessage(response)); - CFRelease(response); - - CFSocketSendData(socket, NULL, serialized, 0); - CFRelease(serialized); - - CFRelease(url); - } - break; - } -} - -static void OnAccept(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *value, void *info) { - switch (type) { - case kCFSocketAcceptCallBack: - Client *client(new Client()); - - client->message_ = NULL; - - CFSocketContext context; - context.version = 0; - context.info = client; - context.retain = NULL; - context.release = NULL; - context.copyDescription = NULL; - - client->socket_ = CFSocketCreateWithNative(kCFAllocatorDefault, *reinterpret_cast(value), kCFSocketDataCallBack, &OnData, &context); - - CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(kCFAllocatorDefault, client->socket_, 0), kCFRunLoopDefaultMode); - break; - } -} - static JSValueRef Instance_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry { CYPool pool; @@ -1444,10 +1443,7 @@ void Closure_(ffi_cif *cif, void *result, void **arguments, void *arg) { for (size_t index(0); index != count; ++index) values[index] = CYFromFFI(context, data->signature_.elements[1 + index].type, data->cif_.arg_types[index], arguments[index]); - JSValueRef exception(NULL); - JSValueRef value(JSObjectCallAsFunction(context, data->function_, NULL, count, values, &exception)); - CYThrow(context, exception); - + JSValueRef value(CYCallAsFunction(context, data->function_, NULL, count, values)); CYPoolFFI(NULL, context, data->signature_.elements[0].type, data->cif_.rtype, result, value); } @@ -1626,6 +1622,29 @@ static JSValueRef Pointer_callAsFunction_valueOf(JSContextRef context, JSObjectR } CYCatch } +static JSValueRef Pointer_callAsFunction_toJSON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { + return Pointer_callAsFunction_valueOf(context, object, _this, count, arguments, exception); +} + +static JSValueRef Instance_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { + CYTry { + Instance_privateData *data(reinterpret_cast(JSObjectGetPrivate(_this))); + CYPoolTry { + return CYCastJSValue(context, CYJSString([data->GetValue() cy$toCYON])); + } CYPoolCatch(NULL) + } CYCatch +} + +static JSValueRef Instance_callAsFunction_toJSON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { + CYTry { + Instance_privateData *data(reinterpret_cast(JSObjectGetPrivate(_this))); + CYPoolTry { + NSString *key(count == 0 ? nil : CYCastNSString(NULL, CYJSString(context, arguments[0]))); + return CYCastJSValue(context, CYJSString([data->GetValue() cy$toJSON:key])); + } CYPoolCatch(NULL) + } CYCatch +} + static JSValueRef Instance_callAsFunction_toString(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { Instance_privateData *data(reinterpret_cast(JSObjectGetPrivate(_this))); @@ -1642,6 +1661,20 @@ static JSValueRef Selector_callAsFunction_toString(JSContextRef context, JSObjec } CYCatch } +static JSValueRef Selector_callAsFunction_toJSON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { + return Selector_callAsFunction_toString(context, object, _this, count, arguments, exception); +} + +static JSValueRef Selector_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { + CYTry { + Selector_privateData *data(reinterpret_cast(JSObjectGetPrivate(_this))); + const char *name(sel_getName(data->GetValue())); + CYPoolTry { + return CYCastJSValue(context, CYJSString([NSString stringWithFormat:@"@selector(%s)", name])); + } CYPoolCatch(NULL) + } CYCatch +} + static JSValueRef Selector_callAsFunction_type(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { if (count != 2) @@ -1665,7 +1698,8 @@ static JSStaticValue Pointer_staticValues[2] = { {NULL, NULL, NULL, 0} }; -static JSStaticFunction Pointer_staticFunctions[2] = { +static JSStaticFunction Pointer_staticFunctions[3] = { + {"toJSON", &Pointer_callAsFunction_toJSON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"valueOf", &Pointer_callAsFunction_valueOf, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {NULL, NULL, 0} }; @@ -1675,12 +1709,16 @@ static JSStaticFunction Pointer_staticFunctions[2] = { {NULL, NULL, NULL, 0} };*/ -static JSStaticFunction Instance_staticFunctions[2] = { +static JSStaticFunction Instance_staticFunctions[4] = { + {"toCYON", &Instance_callAsFunction_toCYON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, + {"toJSON", &Instance_callAsFunction_toJSON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"toString", &Instance_callAsFunction_toString, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {NULL, NULL, 0} }; -static JSStaticFunction Selector_staticFunctions[3] = { +static JSStaticFunction Selector_staticFunctions[5] = { + {"toCYON", &Selector_callAsFunction_toCYON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, + {"toJSON", &Selector_callAsFunction_toJSON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"toString", &Selector_callAsFunction_toString, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"type", &Selector_callAsFunction_type, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {NULL, NULL, 0} @@ -1729,25 +1767,6 @@ MSInitialize { _pooled NSCFBoolean_ = objc_getClass("NSCFBoolean"); - pid_t pid(getpid()); - - struct sockaddr_in address; - address.sin_len = sizeof(address); - address.sin_family = AF_INET; - address.sin_addr.s_addr = INADDR_ANY; - address.sin_port = htons(10000 + pid); - - CFDataRef data(CFDataCreate(kCFAllocatorDefault, reinterpret_cast(&address), sizeof(address))); - - CFSocketSignature signature; - signature.protocolFamily = AF_INET; - signature.socketType = SOCK_STREAM; - signature.protocol = IPPROTO_TCP; - signature.address = data; - - CFSocketRef socket(CFSocketCreateWithSocketSignature(kCFAllocatorDefault, &signature, kCFSocketAcceptCallBack, &OnAccept, NULL)); - CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0), kCFRunLoopDefaultMode); - JSClassDefinition definition; definition = kJSClassDefinitionEmpty; @@ -1822,9 +1841,11 @@ MSInitialize { _pooled CYSetProperty(context, System_, CYJSString("print"), JSObjectMakeFunctionWithCallback(context, CYJSString("print"), &System_print)); - name_ = JSStringCreateWithUTF8CString("name"); - message_ = JSStringCreateWithUTF8CString("message"); length_ = JSStringCreateWithUTF8CString("length"); + message_ = JSStringCreateWithUTF8CString("message"); + name_ = JSStringCreateWithUTF8CString("name"); + toCYON_ = JSStringCreateWithUTF8CString("toCYON"); + toJSON_ = JSStringCreateWithUTF8CString("toJSON"); Array_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Array"))); Function_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Function"))); diff --git a/Output.cpp b/Output.cpp index 0728e82..1f1163d 100644 --- a/Output.cpp +++ b/Output.cpp @@ -495,10 +495,18 @@ void CYSource::Output(std::ostream &out, bool block) const { } void CYString::Output(std::ostream &out, CYFlags flags) const { - out << '\"'; + unsigned quot(0), apos(0); + for (const char *value(value_), *end(value_ + size_); value != end; ++value) + if (*value == '"') + ++quot; + else if (*value == '\'') + ++apos; + + bool single(quot > apos); + + out << (single ? '\'' : '"'); for (const char *value(value_), *end(value_ + size_); value != end; ++value) switch (*value) { - case '"': out << "\\\""; break; case '\\': out << "\\\\"; break; case '\b': out << "\\b"; break; case '\f': out << "\\f"; break; @@ -507,13 +515,25 @@ void CYString::Output(std::ostream &out, CYFlags flags) const { case '\t': out << "\\t"; break; case '\v': out << "\\v"; break; + case '"': + if (!single) + out << "\\\""; + else goto simple; + break; + + case '\'': + if (single) + out << "\\'"; + else goto simple; + break; + default: if (*value < 0x20 || *value >= 0x7f) out << "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value); - else + else simple: out << *value; } - out << '\"'; + out << (single ? '\'' : '"'); } void CYSwitch::Output(std::ostream &out) const { diff --git a/Parser.hpp b/Parser.hpp index 1599959..365d1a5 100644 --- a/Parser.hpp +++ b/Parser.hpp @@ -1,3 +1,42 @@ +/* Cycript - Remove Execution Server and Disassembler + * Copyright (C) 2009 Jay Freeman (saurik) +*/ + +/* Modified BSD License {{{ */ +/* + * Redistribution and use in source and binary + * forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the + * above copyright notice, this list of conditions + * and the following disclaimer. + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions + * and the following disclaimer in the documentation + * and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse + * or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* }}} */ + #ifndef CYPARSER_HPP #define CYPARSER_HPP diff --git a/Server.mm b/Server.mm new file mode 100644 index 0000000..8ce7811 --- /dev/null +++ b/Server.mm @@ -0,0 +1,139 @@ +/* Cycript - Remove Execution Server and Disassembler + * Copyright (C) 2009 Jay Freeman (saurik) +*/ + +/* Modified BSD License {{{ */ +/* + * Redistribution and use in source and binary + * forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the + * above copyright notice, this list of conditions + * and the following disclaimer. + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions + * and the following disclaimer in the documentation + * and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse + * or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* }}} */ + +#include + +struct Client { + CFHTTPMessageRef message_; + CFSocketRef socket_; +}; + +static void OnData(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *value, void *info) { + switch (type) { + case kCFSocketDataCallBack: + CFDataRef data(reinterpret_cast(value)); + Client *client(reinterpret_cast(info)); + + if (client->message_ == NULL) + client->message_ = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, TRUE); + + if (!CFHTTPMessageAppendBytes(client->message_, CFDataGetBytePtr(data), CFDataGetLength(data))) + CFLog(kCFLogLevelError, CFSTR("CFHTTPMessageAppendBytes()")); + else if (CFHTTPMessageIsHeaderComplete(client->message_)) { + CFURLRef url(CFHTTPMessageCopyRequestURL(client->message_)); + Boolean absolute; + CFStringRef path(CFURLCopyStrictPath(url, &absolute)); + CFRelease(client->message_); + + CFStringRef code(CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault, path, CFSTR(""))); + CFRelease(path); + + JSStringRef script(JSStringCreateWithCFString(code)); + CFRelease(code); + + JSValueRef result(JSEvaluateScript(CYGetJSContext(), script, NULL, NULL, 0, NULL)); + JSStringRelease(script); + + CFHTTPMessageRef response(CFHTTPMessageCreateResponse(kCFAllocatorDefault, 200, NULL, kCFHTTPVersion1_1)); + CFHTTPMessageSetHeaderFieldValue(response, CFSTR("Content-Type"), CFSTR("application/json; charset=utf-8")); + + CFStringRef json(CYCopyJSONString(CYGetJSContext(), result, NULL)); + CFDataRef body(CFStringCreateExternalRepresentation(kCFAllocatorDefault, json, kCFStringEncodingUTF8, NULL)); + CFRelease(json); + + CFStringRef length(CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"), CFDataGetLength(body))); + CFHTTPMessageSetHeaderFieldValue(response, CFSTR("Content-Length"), length); + CFRelease(length); + + CFHTTPMessageSetBody(response, body); + CFRelease(body); + + CFDataRef serialized(CFHTTPMessageCopySerializedMessage(response)); + CFRelease(response); + + CFSocketSendData(socket, NULL, serialized, 0); + CFRelease(serialized); + + CFRelease(url); + } + break; + } +} + +static void OnAccept(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *value, void *info) { + switch (type) { + case kCFSocketAcceptCallBack: + Client *client(new Client()); + + client->message_ = NULL; + + CFSocketContext context; + context.version = 0; + context.info = client; + context.retain = NULL; + context.release = NULL; + context.copyDescription = NULL; + + client->socket_ = CFSocketCreateWithNative(kCFAllocatorDefault, *reinterpret_cast(value), kCFSocketDataCallBack, &OnData, &context); + + CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(kCFAllocatorDefault, client->socket_, 0), kCFRunLoopDefaultMode); + break; + } +} + +MSInitialize { + pid_t pid(getpid()); + + struct sockaddr_in address; + address.sin_len = sizeof(address); + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons(10000 + pid); + + CFDataRef data(CFDataCreate(kCFAllocatorDefault, reinterpret_cast(&address), sizeof(address))); + + CFSocketSignature signature; + signature.protocolFamily = AF_INET; + signature.socketType = SOCK_STREAM; + signature.protocol = IPPROTO_TCP; + signature.address = data; + + CFSocketRef socket(CFSocketCreateWithSocketSignature(kCFAllocatorDefault, &signature, kCFSocketAcceptCallBack, &OnAccept, NULL)); + CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0), kCFRunLoopDefaultMode); +} diff --git a/cycript.hpp b/cycript.hpp index 3f95725..132c299 100644 --- a/cycript.hpp +++ b/cycript.hpp @@ -1,3 +1,42 @@ +/* Cycript - Remove Execution Server and Disassembler + * Copyright (C) 2009 Jay Freeman (saurik) +*/ + +/* Modified BSD License {{{ */ +/* + * Redistribution and use in source and binary + * forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the + * above copyright notice, this list of conditions + * and the following disclaimer. + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions + * and the following disclaimer in the documentation + * and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse + * or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* }}} */ + #ifndef CYCRIPT_HPP #define CYCRIPT_HPP @@ -11,7 +50,7 @@ #include JSGlobalContextRef CYGetJSContext(); -const char *CYPoolJSONString(apr_pool_t *pool, JSContextRef context, JSValueRef value, JSValueRef *exception); +const char *CYPoolCYONString(apr_pool_t *pool, JSContextRef context, JSValueRef value, JSValueRef *exception); void CYSetArgs(int argc, const char *argv[]); void CYSetProperty(JSContextRef context, JSObjectRef object, JSStringRef name, JSValueRef value); JSObjectRef CYGetGlobalObject(JSContextRef context); diff --git a/sig/ffi_type.cpp b/sig/ffi_type.cpp index 2955d47..7092dda 100644 --- a/sig/ffi_type.cpp +++ b/sig/ffi_type.cpp @@ -1,3 +1,42 @@ +/* Cycript - Remove Execution Server and Disassembler + * Copyright (C) 2009 Jay Freeman (saurik) +*/ + +/* Modified BSD License {{{ */ +/* + * Redistribution and use in source and binary + * forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the + * above copyright notice, this list of conditions + * and the following disclaimer. + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions + * and the following disclaimer in the documentation + * and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse + * or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* }}} */ + #include "minimal/stdlib.h" #include "sig/ffi_type.hpp" diff --git a/sig/ffi_type.hpp b/sig/ffi_type.hpp index bc7e800..813386a 100644 --- a/sig/ffi_type.hpp +++ b/sig/ffi_type.hpp @@ -1,3 +1,42 @@ +/* Cycript - Remove Execution Server and Disassembler + * Copyright (C) 2009 Jay Freeman (saurik) +*/ + +/* Modified BSD License {{{ */ +/* + * Redistribution and use in source and binary + * forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the + * above copyright notice, this list of conditions + * and the following disclaimer. + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions + * and the following disclaimer in the documentation + * and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse + * or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* }}} */ + #ifndef SIG_FFI_TYPE_H #define SIG_FFI_TYPE_H diff --git a/sig/parse.cpp b/sig/parse.cpp index a786039..5dcfd4f 100644 --- a/sig/parse.cpp +++ b/sig/parse.cpp @@ -1,3 +1,42 @@ +/* Cycript - Remove Execution Server and Disassembler + * Copyright (C) 2009 Jay Freeman (saurik) +*/ + +/* Modified BSD License {{{ */ +/* + * Redistribution and use in source and binary + * forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the + * above copyright notice, this list of conditions + * and the following disclaimer. + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions + * and the following disclaimer in the documentation + * and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse + * or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* }}} */ + #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif diff --git a/sig/parse.hpp b/sig/parse.hpp index ea90454..4557591 100644 --- a/sig/parse.hpp +++ b/sig/parse.hpp @@ -1,3 +1,42 @@ +/* Cycript - Remove Execution Server and Disassembler + * Copyright (C) 2009 Jay Freeman (saurik) +*/ + +/* Modified BSD License {{{ */ +/* + * Redistribution and use in source and binary + * forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the + * above copyright notice, this list of conditions + * and the following disclaimer. + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions + * and the following disclaimer in the documentation + * and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse + * or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* }}} */ + #ifndef SIG_PARSE_H #define SIG_PARSE_H diff --git a/sig/types.hpp b/sig/types.hpp index 92ad1f7..6af8fc6 100644 --- a/sig/types.hpp +++ b/sig/types.hpp @@ -1,3 +1,42 @@ +/* Cycript - Remove Execution Server and Disassembler + * Copyright (C) 2009 Jay Freeman (saurik) +*/ + +/* Modified BSD License {{{ */ +/* + * Redistribution and use in source and binary + * forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the + * above copyright notice, this list of conditions + * and the following disclaimer. + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions + * and the following disclaimer in the documentation + * and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse + * or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* }}} */ + #ifndef SIG_TYPES_H #define SIG_TYPES_H