Index: sope-gdl1/PostgreSQL/PostgreSQL72Channel.m =================================================================== --- sope-gdl1/PostgreSQL/PostgreSQL72Channel.m (révision 1546) +++ sope-gdl1/PostgreSQL/PostgreSQL72Channel.m (copie de travail) @@ -713,6 +713,39 @@ return ms; } +/* GCSEOAdaptorChannel protocol */ +static NSString *sqlFolderFormat = (@"CREATE TABLE %@ (\n" \ + @" c_name VARCHAR (256) NOT NULL,\n" + @" c_content VARCHAR (100000) NOT NULL,\n" + @" c_creationdate INT4 NOT NULL,\n" + @" c_lastmodified INT4 NOT NULL,\n" + @" c_version INT4 NOT NULL,\n" + @" c_deleted INT4 NULL\n" + @")"); +static NSString *sqlFolderACLFormat = (@"CREATE TABLE %@ (\n" \ + @" c_uid VARCHAR (256) NOT NULL,\n" + @" c_object VARCHAR (256) NOT NULL,\n" + @" c_role VARCHAR (80) NOT NULL\n" + @")"); + +- (NSException *) createGCSFolderTableWithName: (NSString *) tableName +{ + NSString *sql; + + sql = [NSString stringWithFormat: sqlFolderFormat, tableName]; + + return [self evaluateExpressionX: sql]; +} + +- (NSException *) createGCSFolderACLTableWithName: (NSString *) tableName +{ + NSString *sql; + + sql = [NSString stringWithFormat: sqlFolderACLFormat, tableName]; + + return [self evaluateExpressionX: sql]; +} + @end /* PostgreSQL72Channel */ @implementation PostgreSQL72Channel(PrimaryKeyGeneration) Index: sope-gdl1/Oracle8/GNUmakefile =================================================================== --- sope-gdl1/Oracle8/GNUmakefile (révision 1546) +++ sope-gdl1/Oracle8/GNUmakefile (copie de travail) @@ -28,15 +28,23 @@ SOPE_ROOT=../.. ORACLE_VERSION=10.2.0.3 #ORACLE_VERSION=11.1.0.1 -ADDITIONAL_INCLUDE_DIRS += -I../GDLAccess -I.. -I/usr/include/oracle/$(ORACLE_VERSION)/client +ADDITIONAL_INCLUDE_DIRS += -I../../sope-core -I../../sope-core/NGExtensions -I../GDLAccess -I.. -I/usr/include/oracle/$(ORACLE_VERSION)/client +local_arch = $(subst 64,,$(shell uname -m)) + +ifeq ($(local_arch),ppc) +PPC_LDFLAGS=-L/opt/ibmcmp/lib -libmc++ +else +PPC_LDFLAGS= +endif + ifneq ($(frameworks),yes) -Oracle8_BUNDLE_LIBS += -L/usr/lib/oracle/$(ORACLE_VERSION)/client/lib/ -locci -lociei -lclntsh -lnnz10 -lGDLAccess -lEOControl -otest_TOOL_LIBS += -L/usr/lib/oracle/$(ORACLE_VERSION)/client/lib/ -locci -lociei -lclntsh -lnnz10 -lGDLAccess -lEOControl +common_LIBS = -L/usr/lib/oracle/$(ORACLE_VERSION)/client/lib/ -locci -lociei -lclntsh -lnnz10 -L../GDLAccess/obj -lGDLAccess -L../../sope-core/EOControl/obj -lEOControl $(PPC_LDFLAGS) else -Oracle8_BUNDLE_LIBS += -L/usr/lib/oracle/$(ORACLE_VERSION)/client/lib/ -locci -lociei -lclntsh -lnnz10 -framework GDLAccess -framework EOControl -otest_TOOL_LIBS += -L/usr/lib/oracle/$(ORACLE_VERSION)/client/lib/ -locci -lociei -lclntsh -lnnz10 -framework GDLAccess -framework EOControl +common_LIBS = -L/usr/lib/oracle/$(ORACLE_VERSION)/client/lib/ -locci -lociei -lclntsh -lnnz10 -framework GDLAccess -framework EOControl $(PPC_LDFLAGS) endif +Oracle8_BUNDLE_LIBS += $(common_LIBS) +otest_TOOL_LIBS += $(common_LIBS) # Bundle BUNDLE_NAME = Oracle8 Index: sope-gdl1/Oracle8/OracleAdaptorChannel.m =================================================================== --- sope-gdl1/Oracle8/OracleAdaptorChannel.m (révision 1546) +++ sope-gdl1/Oracle8/OracleAdaptorChannel.m (copie de travail) @@ -53,14 +53,17 @@ while (c--) { info = [[_row_buffer objectAtIndex: c] pointerValue]; - [_row_buffer removeObjectAtIndex: c]; // We free our LOB object. If it fails, it likely mean it isn't a LOB // so we just free the value instead. - if (OCIDescriptorFree((dvoid *)info->value, (ub4)OCI_DTYPE_LOB) != OCI_SUCCESS) - { - free(info->value); - } + if (info->value) + { + if (OCIDescriptorFree((dvoid *)info->value, (ub4)OCI_DTYPE_LOB) != OCI_SUCCESS) + free(info->value); + info->value = NULL; + } + free(info); + [_row_buffer removeObjectAtIndex: c]; } OCIHandleFree(_current_stm, OCI_HTYPE_STMT); @@ -75,6 +78,30 @@ // @implementation OracleAdaptorChannel +static void +DBTerminate() +{ + if (OCITerminate(OCI_DEFAULT)) + NSLog(@"FAILED: OCITerminate()"); + else + NSLog(@"Oracle8: environment shut down"); +} + ++ (void) initialize +{ + // We Initialize the OCI process environment. + if (OCIInitialize((ub4)OCI_DEFAULT, (dvoid *)0, + (dvoid * (*)(dvoid *, size_t)) 0, + (dvoid * (*)(dvoid *, dvoid *, size_t))0, + (void (*)(dvoid *, dvoid *)) 0 )) + NSLog(@"FAILED: OCIInitialize()"); + else + { + NSLog(@"Oracle8: environment initialized"); + atexit(DBTerminate); + } +} + - (id) initWithAdaptorContext: (EOAdaptorContext *) theAdaptorContext { if ((self = [super initWithAdaptorContext: theAdaptorContext])) @@ -134,10 +161,14 @@ NSLog(@"FAILED: OCILogoff()"); } - if (OCITerminate(OCI_DEFAULT)) - { - NSLog(@"FAILED: OCITerminate()"); - } + + OCIHandleFree(_oci_ctx, OCI_HTYPE_SVCCTX); + OCIHandleFree(_oci_err, OCI_HTYPE_ERROR); + // OCIHandleFree(_oci_env, OCI_HTYPE_ENV); + + _oci_ctx = (OCISvcCtx *)0; + _oci_err = (OCIError *)0; + _oci_env = (OCIEnv *)0; } } @@ -151,11 +182,6 @@ [self _cleanup]; RELEASE(_resultSetProperties); - - OCIHandleFree(_oci_ctx, OCI_HTYPE_SVCCTX); - OCIHandleFree(_oci_err, OCI_HTYPE_ERROR); - OCIHandleFree(_oci_env, OCI_HTYPE_ENV); - RELEASE(delegate); [super dealloc]; @@ -368,16 +394,7 @@ return NO; } - // We Initialize the OCI process environment. - if (OCIInitialize((ub4)OCI_DEFAULT, (dvoid *)0, - (dvoid * (*)(dvoid *, size_t)) 0, - (dvoid * (*)(dvoid *, dvoid *, size_t))0, - (void (*)(dvoid *, dvoid *)) 0 )) - { - NSLog(@"FAILED: OCIInitialize()"); - return NO; - } - + if (OCIEnvInit((OCIEnv **)&_oci_env, (ub4)OCI_DEFAULT, (size_t)0, (dvoid **)0)) { NSLog(@"FAILED: OCIEnvInit()"); Index: sope-gdl1/Oracle8/OracleAdaptorChannelController.m =================================================================== --- sope-gdl1/Oracle8/OracleAdaptorChannelController.m (révision 1546) +++ sope-gdl1/Oracle8/OracleAdaptorChannelController.m (copie de travail) @@ -155,7 +155,9 @@ OCILobFreeTemporary([theChannel serviceContext], [theChannel errorHandle], info->value); OCIDescriptorFree((dvoid *)info->value, (ub4)OCI_DTYPE_LOB); } + free(info); } + [theColumns release]; OCIHandleFree(theStatement, OCI_HTYPE_STMT); } Index: sope-mime/NGImap4/NGImap4Connection.m =================================================================== --- sope-mime/NGImap4/NGImap4Connection.m (révision 1546) +++ sope-mime/NGImap4/NGImap4Connection.m (copie de travail) @@ -381,7 +381,7 @@ if (debugCache) [self logWithFormat:@" no folders cached yet .."]; - result = [[self client] list:(onlyFetchInbox ? @"INBOX" : @"*") + result = [[self client] list:(onlyFetchInbox ? @"INBOX" : @"") pattern:@"*"]; if (![[result valueForKey:@"result"] boolValue]) { [self errorWithFormat:@"Could not list mailbox hierarchy!"]; Index: sope-mime/NGImap4/NGImap4ResponseNormalizer.m =================================================================== --- sope-mime/NGImap4/NGImap4ResponseNormalizer.m (révision 1546) +++ sope-mime/NGImap4/NGImap4ResponseNormalizer.m (copie de travail) @@ -648,14 +648,13 @@ enumerator = [_flags objectEnumerator]; cnt = 0; while ((obj = [enumerator nextObject])) { - if (![obj isNotEmpty]) - continue; - - if (![[obj substringToIndex:1] isEqualToString:@"\\"]) - continue; - - objs[cnt] = [obj substringFromIndex:1]; - cnt++; + if ([obj isNotEmpty]) { + if ([obj hasPrefix:@"\\"]) + objs[cnt] = [obj substringFromIndex:1]; + else + objs[cnt] = obj; + cnt++; + } } result = [NSArray arrayWithObjects:objs count:cnt]; if (objs) free(objs); Index: sope-mime/NGImap4/NGImap4ResponseParser.m =================================================================== --- sope-mime/NGImap4/NGImap4ResponseParser.m (révision 1546) +++ sope-mime/NGImap4/NGImap4ResponseParser.m (copie de travail) @@ -84,6 +84,8 @@ static NSDictionary *_parseMultipartBody(NGImap4ResponseParser *self, BOOL isBodyStructure); +static NSArray *_parseLanguages(); + static NSString *_parseBodyString(NGImap4ResponseParser *self, BOOL _convertString); static NSString *_parseBodyDecodeString(NGImap4ResponseParser *self, @@ -111,6 +113,7 @@ static NSNumber *_parseUnsigned(NGImap4ResponseParser *self); static NSString *_parseUntil(NGImap4ResponseParser *self, char _c); static NSString *_parseUntil2(NGImap4ResponseParser *self, char _c1, char _c2); +static BOOL _endsWithCQuote(NSString *_string); static __inline__ NSException *_consumeIfMatch (NGImap4ResponseParser *self, unsigned char _m); @@ -649,12 +652,31 @@ } - (NSString *)_parseQuotedString { + NSMutableString *quotedString; + NSString *tmpString; + BOOL stop; + /* parse a quoted string, eg '"' */ if (_la(self, 0) == '"') { _consume(self, 1); - return _parseUntil(self, '"'); + quotedString = [NSMutableString string]; + stop = NO; + while (!stop) { + tmpString = _parseUntil(self, '"'); + [quotedString appendString: tmpString]; + if(_endsWithCQuote(tmpString)) { + [quotedString deleteSuffix: @"\\"]; + [quotedString appendString: @"\""]; + } + else { + stop = YES; + } + } } - return nil; + else { + quotedString = nil; + } + return quotedString; } - (void)_consumeOptionalSpace { if (_la(self, 0) == ' ') _consume(self, 1); @@ -1185,7 +1207,7 @@ route = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace]; mailbox = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace]; host = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace]; - + if (_la(self, 0) != ')') { [self logWithFormat:@"WARNING: IMAP4 envelope " @"address not properly closed (c0=%c,c1=%c): %@", @@ -1197,6 +1219,7 @@ address = [[NGImap4EnvelopeAddress alloc] initWithPersonalName:pname sourceRoute:route mailbox:mailbox host:host]; + return address; } @@ -1627,6 +1650,29 @@ return _parseBodyDecodeString(self, _convertString, NO /* no decode */); } +static NSArray *_parseLanguages(NGImap4ResponseParser *self) { + NSMutableArray *languages; + NSString *language; + + languages = [NSMutableArray array]; + if (_la(self, 0) == '(') { + while (_la(self, 0) != ')') { + _consume(self,1); + language = _parseBodyString(self, YES); + if ([language length]) + [languages addObject: language]; + } + _consume(self,1); + } + else { + language = _parseBodyString(self, YES); + if ([language length]) + [languages addObject: language]; + } + + return languages; +} + static NSDictionary *_parseBodyParameterList(NGImap4ResponseParser *self) { NSMutableDictionary *list; @@ -1734,10 +1780,11 @@ *encoding, *bodysize; NSDictionary *parameterList; NSMutableDictionary *dict; + NSArray *languages; type = [_parseBodyString(self, YES) lowercaseString]; _consumeIfMatch(self, ' '); - subtype = _parseBodyString(self, YES); + subtype = [_parseBodyString(self, YES) lowercaseString]; _consumeIfMatch(self, ' '); parameterList = _parseBodyParameterList(self); _consumeIfMatch(self, ' '); @@ -1762,7 +1809,8 @@ _consumeIfMatch(self, ' '); [dict setObject:_parseBodyString(self, YES) forKey:@"lines"]; } - else if ([type isEqualToString:@"message"]) { + else if ([type isEqualToString:@"message"] + && [subtype isEqualToString:@"rfc822"]) { if (_la(self, 0) != ')') { _consumeIfMatch(self, ' '); _consumeIfMatch(self, '('); @@ -1805,14 +1853,9 @@ forKey: @"disposition"]; if (_la(self, 0) != ')') { _consume(self,1); - if (_la(self, 0) == '(') { - [dict setObject: _parseBodyParameterList(self) - forKey: @"language"]; - } - else { - [dict setObject: _parseBodyString(self, YES) - forKey: @"language"]; - } + languages = _parseLanguages(self); + if ([languages count]) + [dict setObject: languages forKey: @"languages"]; if (_la(self, 0) != ')') { _consume(self,1); [dict setObject: _parseBodyString(self, YES) @@ -1829,6 +1872,7 @@ static NSDictionary *_parseMultipartBody(NGImap4ResponseParser *self, BOOL isBodyStructure) { NSMutableArray *parts; + NSArray *languages; NSString *kind; NSMutableDictionary *dict; @@ -1854,14 +1898,9 @@ forKey: @"disposition"]; if (_la(self, 0) != ')') { _consume(self,1); - if (_la(self, 0) == '(') { - [dict setObject: _parseBodyParameterList(self) - forKey: @"language"]; - } - else { - [dict setObject: _parseBodyString(self, YES) - forKey: @"language"]; - } + languages = _parseLanguages(self); + if ([languages count]) + [dict setObject: languages forKey: @"languages"]; if (_la(self, 0) != ')') { _consume(self,1); [dict setObject: _parseBodyString(self, YES) @@ -2170,6 +2209,21 @@ } } +static BOOL _endsWithCQuote(NSString *_string){ + unsigned int quoteSlashes; + int pos; + + quoteSlashes = 0; + pos = [_string length] - 1; + while (pos > -1 + && [_string characterAtIndex: pos] == '\\') { + quoteSlashes++; + pos--; + } + + return ((quoteSlashes % 2) == 1); +} + - (NSException *)exceptionForFailedMatch:(unsigned char)_match got:(unsigned char)_avail { Index: sope-mime/NGMail/NGSmtpClient.m =================================================================== --- sope-mime/NGMail/NGSmtpClient.m (révision 1546) +++ sope-mime/NGMail/NGSmtpClient.m (copie de travail) @@ -442,10 +442,10 @@ [self->text flush]; if (self->isDebuggingEnabled) - [NGTextErr writeFormat:@"C: data(%i bytes) ..\n", [_data bytes]]; + [NGTextErr writeFormat:@"C: data(%i bytes) ..\n", [_data length]]; [self->connection safeWriteBytes:[_data bytes] count:[_data length]]; - [self->connection safeWriteBytes:".\r\n" count:3]; + [self->connection safeWriteBytes:"\r\n.\r\n" count:5]; [self->connection flush]; reply = [self receiveReply]; Index: sope-mime/NGMail/NGMimeMessageGenerator.m =================================================================== --- sope-mime/NGMail/NGMimeMessageGenerator.m (révision 1546) +++ sope-mime/NGMail/NGMimeMessageGenerator.m (copie de travail) @@ -86,37 +86,40 @@ char *des = NULL; unsigned int cnt; BOOL doEnc; - NSString *str; +// NSString *str; // TODO: this s***s big time! +// NSLog (@"class: '%@'", NSStringFromClass ([_data class])); +// #if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY +// str = [[NSString alloc] initWithData:_data +// encoding:NSISOLatin1StringEncoding]; +// str = [str autorelease]; + +// #else +// str = [[NSString alloc] initWithData:_data +// encoding:NSISOLatin9StringEncoding]; +// #endif +// bytes = [str cString]; +// length = [str cStringLength]; -#if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY - str = [[NSString alloc] initWithData:_data - encoding:NSISOLatin1StringEncoding]; -#else - str = [[NSString alloc] initWithData:_data - encoding:NSISOLatin9StringEncoding]; -#endif - str = [str autorelease]; - - bytes = [str cString]; - length = [str cStringLength]; - + bytes = [_data bytes]; + length = [_data length]; + /* check whether we need to encode */ - - for (cnt = 0, doEnc = NO; cnt < length; cnt++) { - if ((unsigned char)bytes[cnt] > 127) { + cnt = 0; + doEnc = NO; + while (!doEnc && cnt < length) + if ((unsigned char)bytes[cnt] > 127) doEnc = YES; - break; - } - } - + else + cnt++; + if (!doEnc) return _data; /* encode quoted printable */ { - char iso[] = "=?iso-8859-15?q?"; + char iso[] = "=?utf-8?q?"; unsigned isoLen = 16; char isoEnd[] = "?="; unsigned isoEndLen = 2; Index: sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m =================================================================== --- sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m (révision 1546) +++ sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m (copie de travail) @@ -285,24 +285,16 @@ - (id)parseValue:(id)_data ofHeaderField:(NSString *)_field { // TODO: use UNICODE NSCalendarDate *date = nil; - unsigned char buf[256]; - unsigned char *bytes = buf, *pe; + unsigned char *bytes, *pe; unsigned length = 0; NSTimeZone *tz = nil; char dayOfMonth, monthOfYear, hour, minute, second; short year; BOOL flag; - - if ((length = [_data cStringLength]) > 254) { - [self logWithFormat: - @"header field value to large for date parsing: '%@'(%i)", - _data, length]; - length = 254; - } - - [_data getCString:(char *)buf maxLength:length]; - buf[length] = '\0'; - + + length = [_data length]; + bytes = [_data cStringUsingEncoding: NSASCIIStringEncoding]; + /* remove leading chars (skip to first digit, the day of the month) */ while (length > 0 && (!isdigit(*bytes))) { bytes++; Index: sope-mime/NGMime/NGMimeBodyPart.m =================================================================== --- sope-mime/NGMime/NGMimeBodyPart.m (révision 1546) +++ sope-mime/NGMime/NGMimeBodyPart.m (copie de travail) @@ -31,18 +31,6 @@ return 2; } -static NGMimeType *defaultType = nil; - -+ (void)initialize { - static BOOL isInitialized = NO; - if (!isInitialized) { - isInitialized = YES; - - defaultType = - [[NGMimeType mimeType:@"text/plain; charset=us-ascii"] retain]; - } -} - + (id)bodyPartWithHeader:(NGHashMap *)_header { return [[[self alloc] initWithHeader:_header] autorelease]; } @@ -156,13 +144,12 @@ if (!Fields) Fields = (NGMimeHeaderNames *)[NGMimePartParser headerFieldNames]; - type = [self->header objectForKey:Fields->contentType]; if (![type isKindOfClass:[NGMimeType class]]) type = [NGMimeType mimeType:[type stringValue]]; - return (type != nil ? type : (id)defaultType); + return type; } - (NSString *)contentId { Index: sope-mime/NGMime/NGMimeBodyParser.m =================================================================== --- sope-mime/NGMime/NGMimeBodyParser.m (révision 1546) +++ sope-mime/NGMime/NGMimeBodyParser.m (copie de travail) @@ -67,7 +67,10 @@ if (_data == nil) return nil; ctype = [_part contentType]; - + if (!ctype + && [_d respondsToSelector: @selector(parser:contentTypeOfPart:)]) + ctype = [_d parser: self contentTypeOfPart: _part]; + if (![ctype isKindOfClass:[NGMimeType class]]) ctype = [NGMimeType mimeType:[ctype stringValue]]; Index: sope-mime/NGMime/NGMimePartParser.h =================================================================== --- sope-mime/NGMime/NGMimePartParser.h (révision 1546) +++ sope-mime/NGMime/NGMimePartParser.h (copie de travail) @@ -117,6 +117,7 @@ BOOL parserParseRawBodyDataOfPart:1; BOOL parserBodyParserForPart:1; BOOL parserDecodeBodyOfPart:1; + BOOL parserContentTypeOfPart:1; } delegateRespondsTo; @@ -275,6 +276,9 @@ - (id)parser:(NGMimePartParser *)_parser bodyParserForPart:(id)_part; +- (NGMimeType *)parser:(id)_parser + contentTypeOfPart:(id)_part; + @end /* NSObject(NGMimePartParserDelegate) */ @interface NSObject(NGMimePartParser) Index: sope-mime/NGMime/NGMimePartParser.m =================================================================== --- sope-mime/NGMime/NGMimePartParser.m (révision 1546) +++ sope-mime/NGMime/NGMimePartParser.m (copie de travail) @@ -227,7 +227,7 @@ } + (NSStringEncoding)defaultHeaderFieldEncoding { - return NSISOLatin1StringEncoding; + return NSUTF8StringEncoding; } - (id)valueOfHeaderField:(NSString *)_name data:(id)_data { @@ -1091,7 +1091,10 @@ id bodyParser = nil; ctype = [_p contentType]; - + if (!ctype + && self->delegateRespondsTo.parserContentTypeOfPart) + ctype = [self->delegate parser: self contentTypeOfPart: _p]; + contentType = ([ctype isKindOfClass:[NGMimeType class]]) ? ctype : [NGMimeType mimeType:[ctype stringValue]]; Index: sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m =================================================================== --- sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m (révision 1546) +++ sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m (copie de travail) @@ -49,80 +49,70 @@ // TODO: move the stuff below to some NSString or NSData category? - data = [NSMutableData dataWithCapacity:64]; + data = [NSMutableData dataWithCapacity: 64]; tmp = [field type]; [data appendBytes:[tmp cString] length:[tmp length]]; tmp = [field filename]; if (tmp != nil) { [data appendBytes:"; " length:2]; [data appendBytes:"filename=\"" length:10]; - { - unsigned char *ctmp; - int cnt, len; - BOOL doEnc; - - // TODO: unicode? - len = [tmp cStringLength]; - ctmp = malloc(len + 3); - [tmp getCString:(char *)ctmp]; ctmp[len] = '\0'; - cnt = 0; - doEnc = NO; - while (cnt < len) { - if ((unsigned char)ctmp[cnt] > 127) { - doEnc = YES; - break; - } - cnt++; + + NSData *d; + unsigned char* bytes; + unsigned length; + int cnt; + BOOL doEnc; + + //d = [tmp dataUsingEncoding: NSUTF8StringEncoding]; + //bytes = [d bytes]; + //length = [d length]; + bytes = [tmp cStringUsingEncoding: NSUTF8StringEncoding]; + length = strlen(bytes); + + cnt = 0; + doEnc = NO; + while (cnt < length) { + if ((unsigned char)bytes[cnt] > 127) { + doEnc = YES; + break; } - if (doEnc) { - char iso[] = "=?iso-8859-15?q?"; - unsigned isoLen = 16; - char isoEnd[] = "?="; - unsigned isoEndLen = 2; - unsigned desLen; - char *des; - - if (ctmp) free(ctmp); - { - NSData *data; + cnt++; + } -#if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY - data = [tmp dataUsingEncoding:NSISOLatin1StringEncoding]; -#else - data = [tmp dataUsingEncoding:NSISOLatin9StringEncoding]; -#endif - - len = [data length]; - ctmp = malloc(len+1); - [data getBytes:ctmp]; ctmp[len] = '\0'; - } - - desLen = len * 3 + 20; - des = calloc(desLen + 10, sizeof(char)); - - memcpy(des, ctmp, cnt); - memcpy(des + cnt, iso, isoLen); - desLen = - NGEncodeQuotedPrintableMime((unsigned char *)ctmp + cnt, len - cnt, - (unsigned char *)des + cnt + isoLen, - desLen - cnt - isoLen); - if ((int)desLen != -1) { - memcpy(des + cnt + isoLen + desLen, isoEnd, isoEndLen); - [data appendBytes:des length:(cnt + isoLen + desLen + isoEndLen)]; - } - else { + if (doEnc) + { + char iso[] = "=?utf-8?q?"; + unsigned isoLen = 10; + char isoEnd[] = "?="; + unsigned isoEndLen = 2; + int desLen; + char *des; + + desLen = length * 3 + 20; + + des = calloc(desLen + 2, sizeof(char)); + + memcpy(des, iso, isoLen); + desLen = NGEncodeQuotedPrintableMime((unsigned char *)bytes, length, + (unsigned char *)(des + isoLen), + desLen - isoLen); + if (desLen != -1) { + memcpy(des + isoLen + desLen, isoEnd, isoEndLen); + [data appendBytes:des length:(isoLen + desLen + isoEndLen)]; + } + else { [self logWithFormat:@"WARNING(%s:%i): An error occour during " @"quoted-printable decoding", __PRETTY_FUNCTION__, __LINE__]; - } - if (des) free(des); + if (des != NULL) free(des); + } } - else { - [data appendBytes:ctmp length:len]; + else + { + [data appendBytes:[tmp cString] length:[tmp length]]; } - } - // [data appendBytes:[tmp cString] length:[tmp length]]; - [data appendBytes:"\"" length:1]; + + [data appendBytes:"\"" length:1]; } return data; } Index: sope-core/NGExtensions/FdExt.subproj/NSString+Encoding.m =================================================================== --- sope-core/NGExtensions/FdExt.subproj/NSString+Encoding.m (révision 1546) +++ sope-core/NGExtensions/FdExt.subproj/NSString+Encoding.m (copie de travail) @@ -140,8 +140,12 @@ #ifdef __linux__ +#if __BYTE_ORDER == __LITTLE_ENDIAN static NSString *unicharEncoding = @"UCS-2LE"; #else +static NSString *unicharEncoding = @"UCS-2BE"; +#endif /* __BYTE_ORDER */ +#else static NSString *unicharEncoding = @"UCS-2-INTERNAL"; #endif static int IconvLogEnabled = -1; @@ -149,21 +153,12 @@ static void checkDefaults(void) { NSUserDefaults *ud; - if (IconvLogEnabled != -1) - return; - ud = [NSUserDefaults standardUserDefaults]; - IconvLogEnabled = [ud boolForKey:@"IconvLogEnabled"]?1:0; + if (IconvLogEnabled == -1) { + ud = [NSUserDefaults standardUserDefaults]; + IconvLogEnabled = [ud boolForKey:@"IconvLogEnabled"]?1:0; -#ifdef __linux__ - if (NSHostByteOrder() == NS_BigEndian) { - NSLog(@"Note: using UCS-2 big endian on Linux."); - unicharEncoding = @"UCS-2BE"; + NSLog(@"Note: using '%@' on Linux.", unicharEncoding); } - else { - NSLog(@"Note: using UCS-2 little endian on Linux."); - unicharEncoding = @"UCS-2LE"; - } -#endif } static char *iconv_wrapper(id self, char *_src, unsigned _srcLen, Index: sope-appserver/NGObjWeb/GNUmakefile.postamble =================================================================== --- sope-appserver/NGObjWeb/GNUmakefile.postamble (révision 1546) +++ sope-appserver/NGObjWeb/GNUmakefile.postamble (copie de travail) @@ -23,14 +23,20 @@ # install makefiles -after-install :: +after-install :: $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/Additional/ngobjweb.make + +ifneq ($(GNUSTEP_MAKE_VERSION),1.3.0) +after-install :: $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/woapp.make $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/wobundle.make +endif + +$(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/Additional/ngobjweb.make: ngobjweb.make $(MKDIRS) $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/Additional/ $(INSTALL_DATA) ngobjweb.make $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/Additional/ngobjweb.make -ifneq ($(GNUSTEP_MAKE_VERSION),1.3.0) -after-install :: +$(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/woapp.make: woapp-gs.make $(INSTALL_DATA) woapp-gs.make \ $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/woapp.make + +$(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/wobundle.make: wobundle-gs.make $(INSTALL_DATA) wobundle-gs.make \ $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/wobundle.make -endif Index: sope-appserver/NGObjWeb/WOContext.m =================================================================== --- sope-appserver/NGObjWeb/WOContext.m (révision 1546) +++ sope-appserver/NGObjWeb/WOContext.m (copie de travail) @@ -64,11 +64,13 @@ static BOOL testNSURLs = NO; static BOOL newCURLStyle = NO; static NSString *WOApplicationSuffix = nil; +static NSURL *redirectURL = nil; + (void)initialize { static BOOL didInit = NO; NSUserDefaults *ud; NSString *cn; + NSString *url; if (didInit) return; @@ -91,6 +93,9 @@ debugCursor = [ud boolForKey:@"WODebugCursor"] ? 1 : 0; debugComponentAwake = [ud boolForKey:@"WODebugComponentAwake"]; WOApplicationSuffix = [[ud stringForKey:@"WOApplicationSuffix"] copy]; + url = [ud stringForKey:@"WOApplicationRedirectURL"]; + if (url != nil) + redirectURL = [NSURL URLWithString: url]; } + (id)contextWithRequest:(WORequest *)_r { @@ -503,6 +508,11 @@ return nil; } + if (redirectURL) { + // Use URL from user defaults (WOApplicationRedirectURL) + return redirectURL; + } + if ((serverURL = [rq headerForKey:@"x-webobjects-server-url"]) == nil) { if ((host = [rq headerForKey:@"host"])) serverURL = [@"http://" stringByAppendingString:host]; Index: sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.m =================================================================== --- sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.m (révision 1546) +++ sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.m (copie de travail) @@ -216,6 +216,12 @@ assocCount++; } } + if (count > 0) { + if ((self->isAbsolute = OWGetProperty(_config, @"absolute"))) { + count--; + assocCount++; + } + } self->rest = _config; Index: sope-appserver/NGObjWeb/DynamicElements/_WOComplexHyperlink.m =================================================================== --- sope-appserver/NGObjWeb/DynamicElements/_WOComplexHyperlink.m (révision 1546) +++ sope-appserver/NGObjWeb/DynamicElements/_WOComplexHyperlink.m (copie de travail) @@ -40,6 +40,7 @@ WOAssociation *string; WOAssociation *target; WOAssociation *disabled; + WOAssociation *isAbsolute; WOElement *template; /* new in WO4: */ @@ -359,6 +360,7 @@ { if ((self = [super initWithName:_name hyperlinkInfo:_info template:_t])) { self->href = _info->href; + self->isAbsolute = _info->isAbsolute; } return self; } @@ -374,6 +376,9 @@ // TODO: we need a binding to disable rewriting! NSRange r; + if ([[self->isAbsolute valueInContext:_ctx] boolValue] == YES) + return NO; + r = [_s rangeOfString:@":"]; if (r.length == 0) return YES; Index: sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.h =================================================================== --- sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.h (révision 1546) +++ sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.h (copie de travail) @@ -41,7 +41,8 @@ WOAssociation *pageName; WOAssociation *actionClass; WOAssociation *directActionName; - + WOAssociation *isAbsolute; + BOOL sidInUrl; /* 'ivar' associations */ Index: sope-appserver/NGObjWeb/SoObjects/SoObject.m =================================================================== --- sope-appserver/NGObjWeb/SoObjects/SoObject.m (révision 1546) +++ sope-appserver/NGObjWeb/SoObjects/SoObject.m (copie de travail) @@ -39,22 +39,34 @@ static int debugLookup = -1; static int debugBaseURL = -1; static int useRelativeURLs = -1; +static int redirectInitted = -1; +static NSURL *redirectURL = nil; + static void _initialize(void) { + NSString *url; + NSUserDefaults *ud; + + ud = [NSUserDefaults standardUserDefaults]; + if (debugLookup == -1) { - debugLookup = [[NSUserDefaults standardUserDefaults] - boolForKey:@"SoDebugKeyLookup"] ? 1 : 0; + debugLookup = [ud boolForKey:@"SoDebugKeyLookup"] ? 1 : 0; NSLog(@"Note(SoObject): SoDebugKeyLookup is enabled!"); } if (debugBaseURL == -1) { - debugBaseURL = [[NSUserDefaults standardUserDefaults] - boolForKey:@"SoDebugBaseURL"] ? 1 : 0; + debugBaseURL = [ud boolForKey:@"SoDebugBaseURL"] ? 1 : 0; NSLog(@"Note(SoObject): SoDebugBaseURL is enabled!"); } if (useRelativeURLs == -1) { - useRelativeURLs = [[NSUserDefaults standardUserDefaults] - boolForKey:@"WOUseRelativeURLs"] ?1:0; + useRelativeURLs = [ud boolForKey:@"WOUseRelativeURLs"] ?1:0; NSLog(@"Note(SoObject): relative base URLs are enabled."); } + if (redirectInitted == -1) { + url = [ud stringForKey:@"WOApplicationRedirectURL"]; + if ([url length]) { + redirectURL = [[NSURL alloc] initWithString: url]; + } + redirectInitted = 1; + } } /* classes */ @@ -318,56 +330,61 @@ rq = [_ctx request]; ms = [[NSMutableString alloc] initWithCapacity:128]; + + if (redirectURL) { + [ms appendString: [redirectURL absoluteString]]; + } + else { + if (!useRelativeURLs) { + port = [[rq headerForKey:@"x-webobjects-server-port"] intValue]; - if (!useRelativeURLs) { - port = [[rq headerForKey:@"x-webobjects-server-port"] intValue]; - - /* this is actually a bug in Apache */ - if (port == 0) { - static BOOL didWarn = NO; - if (!didWarn) { - [self warnWithFormat:@"(%s:%i): got an empty port from Apache!", - __PRETTY_FUNCTION__, __LINE__]; - didWarn = YES; + /* this is actually a bug in Apache */ + if (port == 0) { + static BOOL didWarn = NO; + if (!didWarn) { + [self warnWithFormat:@"(%s:%i): got an empty port from Apache!", + __PRETTY_FUNCTION__, __LINE__]; + didWarn = YES; + } + port = 80; } - port = 80; - } - if ((tmp = [rq headerForKey:@"host"]) != nil) { - /* check whether we have a host header with port */ - if ([tmp rangeOfString:@":"].length == 0) - tmp = nil; - } - if (tmp != nil) { /* we have a host header with port */ - isHTTPS = - [[rq headerForKey:@"x-webobjects-server-url"] hasPrefix:@"https"]; - [ms appendString:isHTTPS ? @"https://" : @"http://"]; - [ms appendString:tmp]; - } - else if ((tmp = [rq headerForKey:@"x-webobjects-server-url"]) != nil) { - /* sometimes the URL is just wrong! (suggests port 80) */ - if ([tmp hasSuffix:@":0"] && [tmp length] > 2) { // TODO: bad bad bad - [self warnWithFormat:@"%s: got incorrect URL from Apache: '%@'", - __PRETTY_FUNCTION__, tmp]; - tmp = [tmp substringToIndex:([tmp length] - 2)]; + if ((tmp = [rq headerForKey:@"host"]) != nil) { + /* check whether we have a host header with port */ + if ([tmp rangeOfString:@":"].length == 0) + tmp = nil; } - else if ([tmp hasSuffix:@":443"] && [tmp hasPrefix:@"http://"]) { - /* see OGo bug #1435, Debian Apache hack */ - [self warnWithFormat:@"%s: got 'http' protocol but 443 port, " - @"assuming Debian/Apache bug (OGo #1435): '%@'", - __PRETTY_FUNCTION__, tmp]; - tmp = [tmp substringWithRange:NSMakeRange(4, [tmp length] - 4 - 4)]; - tmp = [@"https" stringByAppendingString:tmp]; + if (tmp != nil) { /* we have a host header with port */ + isHTTPS = + [[rq headerForKey:@"x-webobjects-server-url"] hasPrefix:@"https"]; + [ms appendString:isHTTPS ? @"https://" : @"http://"]; + [ms appendString:tmp]; } - [ms appendString:tmp]; - } - else { - // TODO: isHTTPS always no in this case? - [ms appendString:isHTTPS ? @"https://" : @"http://"]; + else if ((tmp = [rq headerForKey:@"x-webobjects-server-url"]) != nil) { + /* sometimes the URL is just wrong! (suggests port 80) */ + if ([tmp hasSuffix:@":0"] && [tmp length] > 2) { // TODO: bad bad bad + [self warnWithFormat:@"%s: got incorrect URL from Apache: '%@'", + __PRETTY_FUNCTION__, tmp]; + tmp = [tmp substringToIndex:([tmp length] - 2)]; + } + else if ([tmp hasSuffix:@":443"] && [tmp hasPrefix:@"http://"]) { + /* see OGo bug #1435, Debian Apache hack */ + [self warnWithFormat:@"%s: got 'http' protocol but 443 port, " + @"assuming Debian/Apache bug (OGo #1435): '%@'", + __PRETTY_FUNCTION__, tmp]; + tmp = [tmp substringWithRange:NSMakeRange(4, [tmp length] - 4 - 4)]; + tmp = [@"https" stringByAppendingString:tmp]; + } + [ms appendString:tmp]; + } + else { + // TODO: isHTTPS always no in this case? + [ms appendString:isHTTPS ? @"https://" : @"http://"]; - [ms appendString:[rq headerForKey:@"x-webobjects-server-name"]]; - if ((isHTTPS ? (port != 443) : (port != 80)) && port != 0) - [ms appendFormat:@":%i", port]; + [ms appendString:[rq headerForKey:@"x-webobjects-server-name"]]; + if ((isHTTPS ? (port != 443) : (port != 80)) && port != 0) + [ms appendFormat:@":%i", port]; + } } } Index: sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpTransaction.m =================================================================== --- sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpTransaction.m (révision 1546) +++ sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpTransaction.m (copie de travail) @@ -31,6 +31,7 @@ #include #include #include +#include #include "common.h" #include @@ -1016,6 +1017,12 @@ - (void)parser:(NGMimePartParser *)_parser didParseHeader:(NGHashMap *)_header { } +- (NGMimeType *)parser:(id)_parser + contentTypeOfPart:(id)_part +{ + return [NGMimeType mimeType: @"text/plain; charset=utf-8"]; +} + @end /* WOHttpAdaptor */ @implementation WOCoreApplication(SimpleParserSelection)