From ebde083c541b5d202014c41450a3519f4d08e3c9 Mon Sep 17 00:00:00 2001 From: snowdrop Date: Wed, 20 Oct 2004 14:17:36 +0000 Subject: optimized for visualc 6 --- libcsoap/soap-client.c | 25 +++++++++++++++-------- libcsoap/soap-client.h | 13 +++++++++++- libcsoap/soap-server.c | 4 +--- nanohttp/nanohttp-client.c | 40 ++++++++++++++++++++++++++----------- nanohttp/nanohttp-client.h | 7 ++++--- nanohttp/nanohttp-common.c | 48 +++++++++++++++++++++++++++++++++++++++------ nanohttp/nanohttp-common.h | 19 +++++++++++++++--- nanohttp/nanohttp-mime.c | 27 ++++++------------------- nanohttp/nanohttp-mime.h | 6 +++--- nanohttp/nanohttp-request.c | 6 +++--- nanohttp/nanohttp-server.c | 19 ++++++++++++------ nanohttp/nanohttp-server.h | 5 +---- nanohttp/nanohttp-socket.c | 16 +++++++-------- nanohttp/nanohttp-stream.c | 4 +--- 14 files changed, 156 insertions(+), 83 deletions(-) diff --git a/libcsoap/soap-client.c b/libcsoap/soap-client.c index 58886ff..5562399 100644 --- a/libcsoap/soap-client.c +++ b/libcsoap/soap-client.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-client.c,v 1.8 2004/10/15 13:33:13 snowdrop Exp $ +* $Id: soap-client.c,v 1.9 2004/10/20 14:17:36 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -25,9 +25,21 @@ #include #include -/*--------------------------------- */ +/*--------------------------------- */ +static int _block_socket = 0; static SoapEnv *_soap_client_build_result(hresponse_t *res); /*--------------------------------- */ + +void soap_client_block_socket(int block) +{ + _block_socket = block; +} + +int soap_client_get_blockmode() +{ + return _block_socket; +} + int soap_client_init_args(int argc, char *argv[]) @@ -79,8 +91,6 @@ soap_client_invoke(SoapCtx *call, const char *url, const char *soap_action) static int counter=1; part_t *part; int file_count=0; - long total_size; - long file_size; /* Create buffer */ buffer = xmlBufferCreate(); @@ -88,7 +98,8 @@ soap_client_invoke(SoapCtx *call, const char *url, const char *soap_action) content = (char*)xmlBufferContent(buffer); /* Transport via HTTP */ - conn = httpc_new(); + conn = httpc_new(); + conn->block = soap_client_get_blockmode(); /* Set soap action */ if (soap_action != NULL) { @@ -224,9 +235,7 @@ soap_client_invoke(SoapCtx *call, const char *url, const char *soap_action) static SoapEnv* _soap_client_build_result(hresponse_t *res) { - xmlDocPtr doc; SoapEnv *env; - char *buffer; log_verbose2("Building result (%p)", res); @@ -252,7 +261,7 @@ SoapEnv* _soap_client_build_result(hresponse_t *res) env = soap_env_new_from_stream(res->in); if (env == NULL) { - xmlFreeDoc(doc); +/* xmlFreeDoc(doc);*/ return soap_env_new_with_fault(Fault_Client, "Can not create envelope","",""); } diff --git a/libcsoap/soap-client.h b/libcsoap/soap-client.h index 439a96d..6820c14 100644 --- a/libcsoap/soap-client.h +++ b/libcsoap/soap-client.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: soap-client.h,v 1.4 2004/10/15 13:33:13 snowdrop Exp $ + * $Id: soap-client.h,v 1.5 2004/10/20 14:17:36 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -52,6 +52,17 @@ SoapCtx* soap_client_invoke(SoapCtx *ctx, SoapCtx *soap_client_ctx_new(const char *urn, const char *method); +/** + Sets the underlaying socket to use while connecting + into block mode or not block mode. + The default mode is always non-blocking mode. + + @param block 1 to creat blocked sockets, 0 to create non + blocking sockets. +*/ +void soap_client_block_socket(int block); +int soap_client_get_blockmode(); + #endif diff --git a/libcsoap/soap-server.c b/libcsoap/soap-server.c index 5fb4efe..690fa6b 100644 --- a/libcsoap/soap-server.c +++ b/libcsoap/soap-server.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-server.c,v 1.5 2004/10/15 13:33:13 snowdrop Exp $ +* $Id: soap-server.c,v 1.6 2004/10/20 14:17:36 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -107,11 +107,9 @@ void soap_server_destroy() void soap_server_entry(httpd_conn_t *conn, hrequest_t *req) { hpair_t *header = NULL; - char *postdata; char buffer[1054]; char urn[150]; char method[150]; - long received; SoapCtx *ctx, *ctxres; SoapRouter *router; SoapService *service; diff --git a/nanohttp/nanohttp-client.c b/nanohttp/nanohttp-client.c index 9c0c7d0..de55427 100644 --- a/nanohttp/nanohttp-client.c +++ b/nanohttp/nanohttp-client.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-client.c,v 1.21 2004/10/15 15:10:37 snowdrop Exp $ +* $Id: nanohttp-client.c,v 1.22 2004/10/20 14:17:41 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -50,8 +50,19 @@ NOTE: This will be called from soap_client_init_args() ----------------------------------------------------*/ int httpc_init(int argc, char *argv[]) -{ - hsocket_module_init(); +{ + int i; + + hsocket_module_init(); + + /* initialize from arguments */ + for (i = 0; i < argc; i++) + { + if (!strcmp (argv[i], NHTTP_ARG_LOGFILE) && i < argc - 1) + { + log_set_file(argv[i+1]); + } + } return 0; } @@ -73,7 +84,8 @@ httpc_new() res->out = NULL; res->_dime_package_nr = 0; res->_dime_sent_bytes = 0; - res->id = counter++; + res->id = counter++; + res->block = 0; return res; } @@ -156,7 +168,7 @@ void _httpc_set_error(httpc_conn_t *conn, int errcode, conn->errcode = errcode; va_start(ap, format); - vsnprintf(conn->errmsg, 149, format, ap); + vsprintf(conn->errmsg, format, ap); va_end(ap); } @@ -287,7 +299,7 @@ httpc_talk_to_server(hreq_method_t method, httpc_conn_t * conn, SAVE_STR(url.host), status); return 3; } - status = hsocket_block(conn->sock, 0); + status = hsocket_block(conn->sock, conn->block); if (status != H_OK) { log_error1("Cannot make socket non-blocking"); return status; @@ -498,10 +510,10 @@ int httpc_dime_next(httpc_conn_t* conn, long content_length, header[6] = tmp >> 8; header[7] = tmp; - header[8] = content_length >> 24; - header[9] = content_length >> 16; - header[10] = content_length >> 8; - header[11] = content_length; + header[8] = (byte_t)content_length >> 24; + header[9] = (byte_t)content_length >> 16; + header[10] = (byte_t)content_length >> 8; + header[11] = (byte_t)content_length; _print_binary_ascii32(header[0], header[1], header[2], header[3]); @@ -581,7 +593,13 @@ int httpc_mime_begin(httpc_conn_t *conn, const char *url, */ sprintf(buffer, "multipart/related;"); - + /* + using sprintf instead of snprintf because visual c does not support snprintf + */ +#ifdef WIN32 +#define snprintf(buffer, num, s1, s2) sprintf(buffer, s1,s2) +#endif + if (related_type) { snprintf(temp, 75, " type=\"%s\";", related_type); strcat(buffer, temp); diff --git a/nanohttp/nanohttp-client.h b/nanohttp/nanohttp-client.h index ec4a837..6b54a03 100644 --- a/nanohttp/nanohttp-client.h +++ b/nanohttp/nanohttp-client.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-client.h,v 1.10 2004/10/15 15:10:37 snowdrop Exp $ + * $Id: nanohttp-client.h,v 1.11 2004/10/20 14:17:41 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -47,6 +47,7 @@ typedef struct httpc_conn char errmsg[150]; http_output_stream_t *out; int id; /* uniq id */ + int block; }httpc_conn_t; @@ -140,8 +141,8 @@ hresponse_t *httpc_mime_end(httpc_conn_t *conn); Send boundary and part header and continue with next part */ -int -httpc_mime_send_file (httpc_conn_t * conn, + +int httpc_mime_send_file (httpc_conn_t * conn, const char *content_id, const char *content_type, const char *transfer_encoding, diff --git a/nanohttp/nanohttp-common.c b/nanohttp/nanohttp-common.c index e31c20f..df968c3 100644 --- a/nanohttp/nanohttp-common.c +++ b/nanohttp/nanohttp-common.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-common.c,v 1.13 2004/10/15 13:29:36 snowdrop Exp $ +* $Id: nanohttp-common.c,v 1.14 2004/10/20 14:17:41 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -34,7 +34,8 @@ #include #endif -static log_level_t loglevel = HLOG_DEBUG; +static log_level_t loglevel = HLOG_DEBUG; +static char logfile[75] = {'\0'}; log_level_t log_set_level(log_level_t level) @@ -45,11 +46,26 @@ log_set_level(log_level_t level) } -log_level_t +log_level_t log_get_level() { return loglevel; } + + +void log_set_file(const char *filename) +{ + if (filename) + strncpy(logfile, filename, 75); + else + logfile[0] = '\0'; +} + +char *log_get_file() +{ + if (logfile[0] == '\0') return NULL; + return logfile; +} static void @@ -57,7 +73,8 @@ log_write(log_level_t level, const char *prefix, const char *func, const char *format, va_list ap) { char buffer[1054]; - char buffer2[1054]; + char buffer2[1054]; + FILE *f; if (level < loglevel) return; @@ -65,7 +82,17 @@ log_write(log_level_t level, const char *prefix, sprintf(buffer, "*%s*: [%s] %s\n", prefix, func, format); vsprintf(buffer2, buffer, ap); printf(buffer2); - fflush(stdout); + fflush(stdout); + + if (log_get_file()) { + f = fopen(log_get_file(), "a"); + if (!f) f = fopen(log_get_file(), "w"); + if (f) { + fprintf(f, buffer2); + fflush(f); + fclose(f); + } + } } void @@ -574,6 +601,15 @@ part_t *part_new(const char *id, const char* filename, return part; } +void part_free(part_t *part) +{ + if (part == NULL) + return; + + hpairnode_free_deep(part->header); + + free(part); +} attachments_t *attachments_new() /* should be used internally */ { @@ -612,7 +648,7 @@ void attachments_free(attachments_t *message) part = message->parts; while (part) { tmp = part->next; - mime_part_free(part); + part_free(part); part= tmp; } diff --git a/nanohttp/nanohttp-common.h b/nanohttp/nanohttp-common.h index d37c43a..f7b6c10 100644 --- a/nanohttp/nanohttp-common.h +++ b/nanohttp/nanohttp-common.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-common.h,v 1.12 2004/10/15 13:29:36 snowdrop Exp $ + * $Id: nanohttp-common.h,v 1.13 2004/10/20 14:17:41 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -37,6 +37,12 @@ #define HEADER_HOST "Host" #define HEADER_DATE "Date" #define HEADER_ACCEPT "Accept" + + +#define NHTTPD_ARG_PORT "-NHTTPport" +#define NHTTPD_ARG_TERMSIG "-NHTTPtsig" +#define NHTTPD_ARG_MAXCONN "-NHTTPmaxconn" +#define NHTTP_ARG_LOGFILE "-NHTTPlog" #ifndef SAVE_STR #define SAVE_STR(str) ((str==0)?("(null)"):(str)) @@ -131,7 +137,8 @@ struct tm *localtime_r(const time_t *const timep, struct tm *p_tm); typedef unsigned char byte_t; typedef int hstatus_t; - + + /** Indicates the version of the @@ -186,7 +193,7 @@ struct hpair @returns A newly crated hpair_t object. Use hpair_free() or hpair_free_deep() to free the pair. */ -hpair_t *hpairnode_new(const char* key, const char* value, hpair_t* next); +hpair_t *hpairnode_new(const char* key, const char* value, hpair_t* next); /** @@ -398,6 +405,9 @@ typedef struct _part part_t *part_new(const char *id, const char* filename, const char* content_type, const char* transfer_encoding, part_t *next); +void part_free(part_t *part); + + /* @@ -419,6 +429,7 @@ attachments_t *attachments_new(); /* should be used internally */ @see mime_get_attachments */ void attachments_free(attachments_t *message); +void attachments_add_part(attachments_t *attachments, part_t *part); @@ -439,6 +450,8 @@ typedef enum log_level log_level_t log_set_level(log_level_t level); log_level_t log_get_level(); +void log_set_file(const char *filename); +char *log_get_file(); #ifdef WIN32 #ifndef __MINGW32__ diff --git a/nanohttp/nanohttp-mime.c b/nanohttp/nanohttp-mime.c index 51f3219..952cc22 100755 --- a/nanohttp/nanohttp-mime.c +++ b/nanohttp/nanohttp-mime.c @@ -3,7 +3,7 @@ * | \/ | | | | \/ | | _/ * |_''_| |_| |_''_| |_'/ PARSER * -* $Id: nanohttp-mime.c,v 1.1 2004/10/15 13:30:42 snowdrop Exp $ +* $Id: nanohttp-mime.c,v 1.2 2004/10/20 14:17:41 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -49,7 +49,7 @@ typedef void (*MIME_part_end) (void*); typedef void (*MIME_parse_begin) (void*); typedef void (*MIME_parse_end) (void*); typedef void (*MIME_ERROR_bytes) (void*, - const unsigned char*, size_t); + const unsigned char*, int); typedef enum _MIME_parser_status { @@ -127,10 +127,10 @@ void MIME_reader_init(MIME_reader *reader, Read data from a reader source. */ MIME_read_status MIME_reader_read(MIME_reader *reader, - unsigned char *buffer, size_t size) + unsigned char *buffer, int size) { MIME_read_status status; - size_t readed_size; + int readed_size; unsigned char tempBuffer[MIME_READER_MAX_BUFFER_SIZE]; int rest_size; @@ -241,7 +241,7 @@ int MIME_buffer_is_empty(MIME_buffer *buffer) return buffer->size == 0; } -int MIME_buffer_clear(MIME_buffer *buffer) +void MIME_buffer_clear(MIME_buffer *buffer) { buffer->size = 0; } @@ -651,7 +651,7 @@ hpair_t *_mime_process_header(char *buffer) static -void _mime_received_bytes(void *data, const unsigned char* bytes, size_t size) +void _mime_received_bytes(void *data, const unsigned char* bytes, int size) { int i=0; char *id; @@ -852,21 +852,6 @@ mime_message_parse_from_file(FILE *in, const char* root_id, } } -/* - Free a mime part -*/ -void -mime_part_free(part_t *part) -{ - if (part == NULL) - return; - - hpairnode_free_deep(part->header); - - free(part); -} - - hstatus_t mime_get_attachments(content_type_t *ctype, http_input_stream_t *in, attachments_t **dest) diff --git a/nanohttp/nanohttp-mime.h b/nanohttp/nanohttp-mime.h index e863488..f78efa1 100755 --- a/nanohttp/nanohttp-mime.h +++ b/nanohttp/nanohttp-mime.h @@ -3,7 +3,7 @@ * | \/ | | | | \/ | | _/ * |_''_| |_| |_''_| |_'/ PARSER * -* $Id: nanohttp-mime.h,v 1.1 2004/10/15 13:30:42 snowdrop Exp $ +* $Id: nanohttp-mime.h,v 1.2 2004/10/20 14:17:41 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -29,10 +29,10 @@ #ifndef NANO_HTTP_MIME_PARSER_H #define NANO_HTTP_MIME_PARSER_H +#include +#include #include -#include -#include /* ------------------------------------------------------------------ "multipart/related" MIME Message Builder diff --git a/nanohttp/nanohttp-request.c b/nanohttp/nanohttp-request.c index bed59f2..0eb5a22 100755 --- a/nanohttp/nanohttp-request.c +++ b/nanohttp/nanohttp-request.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-request.c,v 1.1 2004/10/15 13:30:42 snowdrop Exp $ +* $Id: nanohttp-request.c,v 1.2 2004/10/20 14:17:41 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -44,7 +44,8 @@ hrequest_t *hrequest_new() req->in = NULL; req->attachments = NULL; req->content_type = NULL; - + + return req; } static @@ -61,7 +62,6 @@ _hrequest_parse_header(char *data) char *saveptr3; char *result; char *key; - char *value; char *opt_key; char *opt_value; int firstline = 1; diff --git a/nanohttp/nanohttp-server.c b/nanohttp/nanohttp-server.c index ad4f02c..2ee15c7 100644 --- a/nanohttp/nanohttp-server.c +++ b/nanohttp/nanohttp-server.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-server.c,v 1.26 2004/10/15 13:29:36 snowdrop Exp $ +* $Id: nanohttp-server.c,v 1.27 2004/10/20 14:17:41 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -32,6 +32,7 @@ #endif #ifndef WIN32 + /* According to POSIX 1003.1-2001 */ #include @@ -39,7 +40,11 @@ #include #include #include - + +#else + +#include + #endif #ifdef MEM_DEBUG @@ -370,10 +375,8 @@ httpd_session_main (void *data) conndata_t *conn = (conndata_t *) data; const char *msg = "SESSION 1.0\n"; int len = strlen (msg); - char ch[2]; char buffer[256]; /* temp buffer for recv() */ char header[4064]; /* received header */ - int total; /* result from recv() */ int headerreached = 0; /* whether reach header * "\n\n" */ hrequest_t *req = NULL; /* only for test */ httpd_conn_t *rconn; @@ -808,11 +811,9 @@ httpd_mime_send_header (httpd_conn_t * conn, const char *related_start_info, const char *related_type, int code, const char *text) { - int status; char buffer[300]; char temp[250]; char boundary[250]; - hpair_t *header; /* Set Content-type @@ -820,6 +821,12 @@ httpd_mime_send_header (httpd_conn_t * conn, type=..; start=.. ; start-info= ..; boundary=... */ + /* + using sprintf instead of snprintf because visual c does not support snprintf + */ +#ifdef WIN32 +#define snprintf(buffer, num, s1, s2) sprintf(buffer, s1,s2) +#endif sprintf (buffer, "multipart/related;"); if (related_type) diff --git a/nanohttp/nanohttp-server.h b/nanohttp/nanohttp-server.h index 7e5263e..513f4de 100644 --- a/nanohttp/nanohttp-server.h +++ b/nanohttp/nanohttp-server.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-server.h,v 1.6 2004/10/15 13:29:37 snowdrop Exp $ + * $Id: nanohttp-server.h,v 1.7 2004/10/20 14:17:41 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -30,9 +30,6 @@ #include #include -#define NHTTPD_ARG_PORT "-NHTTPport" -#define NHTTPD_ARG_TERMSIG "-NHTTPtsig" -#define NHTTPD_ARG_MAXCONN "-NHTTPmaxconn" typedef struct httpd_conn diff --git a/nanohttp/nanohttp-socket.c b/nanohttp/nanohttp-socket.c index f31bf08..d7a1d59 100644 --- a/nanohttp/nanohttp-socket.c +++ b/nanohttp/nanohttp-socket.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-socket.c,v 1.28 2004/10/18 11:43:06 snowdrop Exp $ +* $Id: nanohttp-socket.c,v 1.29 2004/10/20 14:17:41 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -145,7 +145,7 @@ hsocket_open (hsocket_t * dsock, const char *hostname, int port) /* set server addresss */ address.sin_family = host->h_addrtype; - address.sin_port = htons (port); + address.sin_port = htons((unsigned short)port); /* connect to the server */ if (connect (sock, (struct sockaddr *) &address, sizeof (address)) != 0) @@ -173,7 +173,7 @@ hsocket_bind (hsocket_t * dsock, int port) } /* bind socket */ addr.sin_family = AF_INET; - addr.sin_port = htons (port); /* short, network byte order */ + addr.sin_port = htons ((unsigned short)port); /* short, network byte order */ addr.sin_addr.s_addr = INADDR_ANY; memset (&(addr.sin_zero), '\0', 8); /* zero the rest of the * struct */ @@ -291,10 +291,11 @@ void hsocket_close (hsocket_t sock) { char junk[10]; - struct linger _linger; /* _hsocket_wait_until_receive(sock);*/ log_verbose1 ("closing socket ..."); -/* hsocket_block(sock,1); +/* + struct linger _linger; + hsocket_block(sock,1); _linger.l_onoff =1; _linger.l_linger = 30000; setsockopt(sock, SOL_SOCKET, SO_LINGER, (const char*)&_linger, sizeof(struct linger)); @@ -401,14 +402,12 @@ hsocket_read (hsocket_t sock, byte_t *buffer, int total, int force) #endif if (!force) { - _log_str("socket.recv", buffer, status); return status; } totalRead += status; if (totalRead == total) { - _log_str("socket.recv", buffer, totalRead); return totalRead; } } @@ -429,7 +428,8 @@ hsocket_block(hsocket_t sock, int block) #ifdef WIN32 /*#define HSOCKET_BLOCKMODE 0 #define HSOCKET_NONBLOCKMODE 1 -*/ +*/ + iMode = (block==0)?1:0; /* Non block mode */ if (ioctlsocket (sock, FIONBIO, (u_long FAR *) & iMode) == INVALID_SOCKET) { diff --git a/nanohttp/nanohttp-stream.c b/nanohttp/nanohttp-stream.c index 77aee28..039eadc 100755 --- a/nanohttp/nanohttp-stream.c +++ b/nanohttp/nanohttp-stream.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-stream.c,v 1.2 2004/10/15 14:26:15 snowdrop Exp $ +* $Id: nanohttp-stream.c,v 1.3 2004/10/20 14:17:41 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -75,7 +75,6 @@ http_input_stream_t *http_input_stream_new(hsocket_t sock, hpair_t *header) { http_input_stream_t *result; char *content_length; - char *chunked; /* Paranoya check */ /*if (header == NULL) @@ -446,7 +445,6 @@ http_output_stream_t *http_output_stream_new(hsocket_t sock, hpair_t *header) { http_output_stream_t *result; char *content_length; - char *chunked; /* Paranoya check */ /* if (header == NULL) -- cgit v1.1-32-gdbae