scottmk [Sat, 6 Feb 2010 20:53:31 +0000 (20:53 +0000)]
1. For the "request" command: removed the calls to osrfAppSessionConnect()
and osrf_app_session_disconnect(). There's no point in opening and closing
a connection for a single request.
2. For the "math_bench" command: coerce the first command argument to a
positive value. In the old code, a zero value led to a division-by-zero,
and a negative value led to a segfault.
3. For the "math_bench" command: accept an optional second parameter
to control whether and when we call osrf_app_session_disconnect(). It
has valid values of 0 (the default), 1, and 2; values out of range are
coerced to valid values.
4. In do_math(): initialize the array of floats by setting each float
to zero, instead of by using memset() to fill the array with
all-bits-zero. The C Standard does not guarantee that all-bits-zero
represents zero for a float.
(This last change shouldn't make any difference anyway, because each float
in the array is overwritten before it is read. Still, anything not worth
doing is not worth doing badly.)
dbs [Thu, 28 Jan 2010 03:14:32 +0000 (03:14 +0000)]
Provide a thread if the translator wasn't passed one in the request headers
The OpenSRF-over-HTTP spec says that the translator will generate a thread
in the response if one wasn't passed in the request; however, we were trying
to pass a null pointer back and that doesn't work so well.
As we're already generating a reasonably unique string for the purposes
of delim in the multipart data response, let's also use that for the
response thread when necessary.
erickson [Mon, 25 Jan 2010 16:29:19 +0000 (16:29 +0000)]
Added some fault tolerance to the inbound-to-unixserver message handoff process. In some conditions, the unix socket will result in sigpipe (anecdotally, seen more oftenvirtualized environments). these changes add a call to select before writing to the socket to check for socket availability and add a sigpipe handler that forces the inbound process to wait a brief period of time before trying the delivery again
erickson [Thu, 21 Jan 2010 03:51:33 +0000 (03:51 +0000)]
similar to recent opensrf-c changes, keep active and idle child procs in separate lists for faster access and simpler code. also some formatting/comment updates
scottmk [Thu, 21 Jan 2010 01:08:37 +0000 (01:08 +0000)]
Bug fix.
When all the servers for a given server go away, the router deletes the
server class from its internal data structures. However that can happen
in the middle of a loop receiving successive messages from that server.
The old code would continue trying to read more messages from the
deleted server class, leading to a segfault.
The new code checks to see whether the server class still exists. If
not, it breaks out of the loop.
erickson [Tue, 19 Jan 2010 18:41:24 +0000 (18:41 +0000)]
Patch from Joe Atzberger:
When running from command-line, logger warns "Logger found no config. Using STDERR" but in fact fails to do so. That blocks atomic testing of dependent modules, including almost all of EG's Application and Utils.
Also, in _write_file when failing to sysopen the target file, the die message reports a different variable than the one actually targeted.
scottmk [Mon, 18 Jan 2010 03:00:13 +0000 (03:00 +0000)]
Instead of keeping all child processes in a single list, keep them in two
separate lists: one list of those which are currently servicing requests,
and another list of idle children. Move the children back and forth as
their status changes.
This change has three advantages:
1. When searching for an active child, there is a smaller list to search.
2. When doing a select() to identify children that have become available,
we can look for messages only from the active children, since the idle
ones won't write anything back to the parent. (Actually we could have
done this with a single list, but we didn't.)
3. Probably most important: since the idle list functions as a stack, we
assign the next request to the child that was most recently active, or was
most recently launched. That's the child that is most likely still to be
physically in memory. Formerly we assigned requests to children approximately
on a round-robin basis. As a result we assigned each new request to the
child that was most likely to be swapped out.
Also, in prefork_clear(): kill each child process individually. Sending a
SIGKILL to the entire process group kills the parent as well as the
children.
scottmk [Fri, 15 Jan 2010 04:52:00 +0000 (04:52 +0000)]
Close a substantial resource leak in drone processes.
A drone inherits the transport_client of its parent process,
including a socket and a substantial amount of memory. The
old code avoided freeing the transport_client in order to
avoid disconnecting the parent from Jabber.
The new code contrives to reclaim the resources without
sending a disconnect to Jabber. Hence the parent remains
connected.
M include/opensrf/transport_client.h
M include/opensrf/transport_session.h
M src/libopensrf/osrf_system.c
M src/libopensrf/transport_session.c
M src/libopensrf/transport_client.c
scottmk [Sat, 9 Jan 2010 20:54:57 +0000 (20:54 +0000)]
1. For keeping track of the child processes: use a doubly-linked
list instead of a singly-linked list. The resulting list manipulations
are both simpler (fewer special cases) and faster (no need to traverse
then entire list just to find the end).
2. Maintain a free list of prefork_child structures that have been
allocated but are not currently in use. Allocate from the free list
when possible, in order to avoid churning through malloc() and free().
3. When initializing prefork_child.appname: assign it the same value
as the corresponding field in the parental prefork_simple, instead of
creating a separate copy. The parental copy will remain valid until
after all the prefork_children are gone.
scottmk [Fri, 8 Jan 2010 21:14:35 +0000 (21:14 +0000)]
Added or modified a lot of comments; made some minor tweaks to white space.
Eliminated the min_children member of the prefork_child structure. We
didn't use it for anything, and it made no sense anyway.
Moved the closing of the child's file descriptors into prefork_child_free()
in order to eliminate duplicated code. Also we were closing two of the
file descriptors twice.
prefork_child_free() now returns void instead of a pointless int.
In reap_children(): reset the child_dead at the beginning of the function
instead of at the end. Otherwise we could miss a SIGCHLD that occurs during
the function.
Pass NULL as the second parameter to waitpid(). We don't do anything with the
children's return codes, so there's no need to capture them.
Eliminated all calls to osrf_clearbuf() as pointless.
In prefork_clear(): instead of sleeping for a second after sending the SIGKILL
to the child processes, go through a waitpid() loop. (In practice this
function is all but unreachable anyway.)
scottmk [Wed, 6 Jan 2010 05:15:24 +0000 (05:15 +0000)]
Moved nested #includes out of osrf_prefork.h and into the implementation files.
Somne of the #includes turned out to be unnecessary, so I eliminated them.
In osrf_prefork.c: instead of dynamically allocating a prefork_simple,
allocate it on the stack. That way we avoid a malloc() and free().
Renamed prefork_free() to prefork_clear(), since it no longer frees the
prefork_simple itself, but only memory owned by the prefork_simple. Also
it now returns void instead of int, since there are no errors to detect
or report.
Added some comments.
M include/opensrf/osrf_prefork.h
M src/libopensrf/osrf_system.c
M src/libopensrf/osrf_prefork.c
scottmk [Sun, 3 Jan 2010 19:28:02 +0000 (19:28 +0000)]
Finished adding doxygen-style comments to document the app session
functions. Removed comments from the header so that they wouldn't
override more complete comments in the implementation file.
Tweaked the white space here and there.
Changed the return code in a few cases, for consistency. A couple of
functions seemed unable to decide whether 0 was good and 1 was bad,
or vice versa.
M include/opensrf/osrf_app_session.h
M src/libopensrf/osrf_app_session.c
scottmk [Fri, 1 Jan 2010 22:16:01 +0000 (22:16 +0000)]
Incorporate _osrf_app_request_resend into osrf_app_session_request_resend(),
which had been its only caller. The code is trivial enough that it will be
simple to break out again if necessary. Meanwhile having it all in a single
function makes it more readable.
Free the hash table of requests correctly; i.e. all of each linked list, not
just the first node.
Various additions and refinements to comments; occasional tweaks to white space.
M include/opensrf/osrf_app_session.h
M src/libopensrf/osrf_app_session.c
scottmk [Fri, 1 Jan 2010 14:49:16 +0000 (14:49 +0000)]
Changed the way pending requests are stored in an osrfAppSession.
Before, pending requests were stored in a so-called request_queue.
However it wasn't a queue at all, except in name. It was an
osrfList, i.e. an expandable pointer array used as a random
access container. Request ids were used as subscripts into the
array.
Since we don't reuse request ids (except in the theoretical case
of a wraparound), the array grew without limit. This unbounded
growth in the memory footprint could create problems for a
long-running busy process. It might have contributed to the
rumored instabililty of chopchop, our homegrown Jabber server.
Now, pending requests are stored in a hash table, where each
of 64 slots holds a doubly linked list. There should be no
effect on performance unless there are hundreds or thousands
of pending requests at once, in which case we would probably
get bogged down anyway.
M include/opensrf/osrf_app_session.h
M src/libopensrf/osrf_app_session.c
scottmk [Mon, 28 Dec 2009 03:50:38 +0000 (03:50 +0000)]
Add routines for calculating SHA1 and MD5 digests, based on the
gnutls package. These routines are designed to replace the
current functions shahash() and md5sum(), but they are not
drop-in replacements because they have different signatures.
Prerequisites: packages gcrypt and gnutls.
This code is based on a contribution by Jason Stephenson.
A include/opensrf/osrf_digest.h
A src/libopensrf/osrf_digest.c
scottmk [Sun, 20 Dec 2009 06:37:02 +0000 (06:37 +0000)]
1. In the parent router process: wait for all of the immediate
child processes to terminate before exiting.
This change eliminates the need for the shell script invoking
the router to sleep before running a ps to identify the effective
router processes (which are grandchildren of the parent). By the
time the parent exits, the children will have launched the
grandchildren and exited.
2. If any of the immediate child processes terminates abnormally
(either a non-zero return code or termination by a signal), issue
a warning message to that effect. This message goes to standard
error, since the parent process never opens a log file.
3. Apply the volatile qualifier to a couple of variables that
are updated asynchronously by a signal handler.
M src/router/osrf_router.c
M src/router/osrf_router_main.c
scottmk [Mon, 14 Dec 2009 20:38:44 +0000 (20:38 +0000)]
1. In osrf_app_session.[ch]: Create a new function
osrfAppSessionSendRequest(), similar to osrfAppSessionMakeRequest()
but without the param_strings parameter.
2. Replace the old function with the new one in srfsh.c.
M include/opensrf/osrf_app_session.h
M src/libopensrf/osrf_app_session.c
M src/srfsh/srfsh.c
scottmk [Tue, 8 Dec 2009 03:40:00 +0000 (03:40 +0000)]
Eliminated the function pointer osrf_stack_entry_point so that
osrf_app_session_queue_wait() can call osrf_stack_process() directly.
This change entails some juggling of declarations, headers, and the
like, but does not substantively affect the processing.
Also: made a number of other minor changes, mostly to comments
and white space.
M include/opensrf/osrf_stack.h
M include/opensrf/osrf_app_session.h
M src/libopensrf/osrf_app_session.c
M src/libopensrf/osrf_stack.c
erickson [Wed, 2 Dec 2009 22:42:36 +0000 (22:42 +0000)]
Prevent infinite loop (with logging) in child process reaping.
From the perl docs on waitpid:
Note that on some systems, a return value of "-1" could mean that child processes are being automatically reaped. See perlipc for details, and for other examples.
dbs [Fri, 27 Nov 2009 22:47:49 +0000 (22:47 +0000)]
Partial fix for launchpad bug 489294: OpenSRF seems to depend on explicit --prefix configure option
In the process of creating Perl and Python scripts using AC_SUBST(sysconfdir),
autoconf would generate variables like '${prefix}' if no explicit --prefix
option was passed to configure - and this would cause those scripts to fail
with syntax errors.
We can work around that, and so we shall. The bigger question is whether
creating scripts with hardcoded defaults results in problems when it comes
to creating system packages; according to http://www.gnu.org/software/hello/manual/autoconf/Installation-Directory-Variables.html
one should try to defer these changes to the Makefile so that the
destination directory can be specified at make or make install time,
instead.
At least this gets us working with no explicit configure options again.
Perhaps a packaging expert can help us out of this mire :)
scottmk [Wed, 25 Nov 2009 16:05:55 +0000 (16:05 +0000)]
Replacing calls to the old JSON parser with calls to the
new JSON parser.
M src/gateway/osrf_json_gateway.c
M src/c-apps/osrf_math.c
M src/c-apps/timejson.c
M src/libopensrf/osrf_json_test.c
M src/libopensrf/osrf_message.c
M src/libopensrf/osrf_cache.c
scottmk [Mon, 16 Nov 2009 04:57:11 +0000 (04:57 +0000)]
Eliminated two members of the osrfMessage structure:
result_string and sender_tz_offset. Neither is used for
anything, and either may be easily reinstated if necessary.
I was tempted to eliminate the protocol member as well,
since it isn't used for anything either. However it's
populated from one of the parameters to osrf_message_init().
Getting rid of the protocol member properly would ramify
to all the code that calls osrf_message_init(), which would
be a lot of work to undo if necessary, so I left it alone.
M include/opensrf/osrf_message.h
M src/libopensrf/osrf_message.c
scottmk [Mon, 16 Nov 2009 03:53:18 +0000 (03:53 +0000)]
1. Changes to comments and white space.
2. Eliminated the macro OSRF_MAX_PARAMS, which is nowhere used. It was
all but unusable anyway, since it included a terminal semicolon.
I considered eliminating the macro OSRF_XML_NAMESPACE as well, since
it is also unused. However I stayed my hand, since it would be more
difficult to reconstruct if the need arose.
M include/opensrf/osrf_message.h
M src/libopensrf/osrf_message.c
scottmk [Sun, 15 Nov 2009 18:39:44 +0000 (18:39 +0000)]
Move the libxml headers out of the header and into the
implementation file.
The files that #include osrf_message.h compile just fine
without the nested libxml headers, and there's no reason
to make the compiler paw through them.
M include/opensrf/osrf_message.h
M src/libopensrf/osrf_message.c
scottmk [Sun, 15 Nov 2009 17:57:33 +0000 (17:57 +0000)]
Create a new function osrfMessageDeserialize(), as a
replacement for osrf_message_deserialize().
The older osrf_message_deserialize() receives an array of
pointers to populate, along with a maximum number. If the
JSON input contains more than the maximum number of
messages, the extras are silently discarded. This design
forces the calling code to guess how many messages it
might ever receive at one time, with no way to determine
whether its guess was good enough.
The newer function returns an osrfList of pointers, and
can therefore return all the messages it finds in the
input, with no risk of loss.
M include/opensrf/osrf_message.h
M src/libopensrf/osrf_message.c
scottmk [Sat, 14 Nov 2009 18:39:32 +0000 (18:39 +0000)]
Pulled the creation of a single osrfMessage from a jsonObject
into a separate function. This change simplifies
osrf_message_deserialize(), and will make it easier to create
a replacement for it.
Also: tinkered with some of the comments and white space.
scottmk [Sat, 14 Nov 2009 05:32:55 +0000 (05:32 +0000)]
Tidied up various things:
1. Miscellaneous adjustments to white space.
2. Added doxygen-style comments to document all functions. Removed most
comments from the header so that they won't override those in the
implementation file.
3. Slightly rearranged or otherwise tweaked the logic here and there
for clarity.
4. osrf_messasge_set_locale() now returns a const pointer, to discourage
the calling code from changing or freeing the message's copy of the
locale.
5. Eliminated the full_param_string member of osrfMessage. We weren't
using it for anything, except to initialize it to NULL.
6. Plugged several memory leaks (potential but not actual).
7. Made osrfMessageToJSON a static function. No other source file
needs to call it.
8. Replaced a couple of calls to jsonObjectToSimpleString() with calls
to jsonObjectGetString(), in order to eliminate a malloc and free.
M include/opensrf/osrf_message.h
M src/libopensrf/osrf_message.c
scottmk [Tue, 10 Nov 2009 22:50:14 +0000 (22:50 +0000)]
1. Fixed a bug whereby the display of request results was not showing up
when pretty-printing was turned off. We were calling jsonObjectGetString()
when we should have been calling jsonObjectToJSON(), and thereby getting
NULL instead of a usable string, for any but the most trivial of results.
Also: applied some minor refinements to nearby code.
2. In handle_request(): eliminated a couple of superfluous variables.
3. Corrected an erroneous statement in the help message. Request output
passes through less when raw_print is false, not when it's true.
scottmk [Mon, 9 Nov 2009 02:47:26 +0000 (02:47 +0000)]
Miscellaneous minor tweaks:
1. Moved nested #includes out of the header file and into the
implementation files as needed.
2. Additions and refinements to comments; adjustments to white space.
3. Changed several functions to return void instead of int, since we don't
look at the return values anyway.
4. Added the const qualifier to several function parameters.
5. In osrfRouterHandleAppRequest(): initialize arr[], an array of pointers,
by setting each pointer to NULL. We had been using memset() on the lot,
relying on a the non-portable assumption that a NULL pointer is
represented by all-bits-zero.
6. Minor rearrangements of the logic here and there, mostly to free things
as soon as we're done with them instead of waiting until the end of the block,
or to defer the declarations of things until we're about to use them.
7. Replaced a couple of calls to jsonObjectToSimpleString() with calls to
jsonObjectGetString(), in order to eliminate a malloc() and a free().
8. Renamed osrfRouterHandleAppResponse() to osrfRouterSendAppResponse(),
which is more descriptive and less vague.
M src/router/osrf_router.h
M src/router/osrf_router.c
M src/router/osrf_router_main.c
scottmk [Fri, 6 Nov 2009 12:34:34 +0000 (12:34 +0000)]
Corrected a glitch in the command-line parser. Now commas
are treated as the equivalent of white space between
parameters. For example { "a":5 },{ "b":true } is parsed as
two separate JSON objects, even though there is no white space
between them.
scottmk [Thu, 5 Nov 2009 21:03:36 +0000 (21:03 +0000)]
Several bug fixes:
1. In osrfRouterRun(): eliminate the counting of sockets. Rely
on the traversal of the class list to cover all the active
sockets. Otherwise we would enter an infinite loop if we had just
deleted a class with an active socket.
2. In osrfRouterClassHandleIncoming(): in the case of an error
message that we can't reroute to a different node, do a continue
instead of a return. Otherwise we delay any further messages that
may be enqueued for the same class, and possibly skip them entirely.
Also, in the same scenario: free the message before continuing, in
order to avoid a memory leak, and clear the transaction id for the
logging routines.
3. In osrfRouterClassHandleBounce(): remove the dead node when it is the
last one left for its class. Remove the class as well, since it is
no longer usable. We had been leaving the dead node around, for no
good reason.
scottmk [Wed, 4 Nov 2009 16:32:10 +0000 (16:32 +0000)]
1. Added an osrfHashIterator as a member of osrfRouter, so that
we can reuse it when repeatedly traversing the list of classes.
This way we don't have to create and destroy an osrfHashIterator
on every iteration.
2. In osrfRouterRun(): eliminated a pointless hash look up in the
innermost loop.
scottmk [Tue, 3 Nov 2009 22:25:12 +0000 (22:25 +0000)]
1. Changed several functions that were returning int so that
they return void instead. We weren't checking the return codes
anyway, since the functions in question handle their error
conditions on their own.
2. Eliminated a pointless memset().
3. For message received from the top-level transport_client, we
have to branch according to whether the message is a command
or an app request. I moved that decision up one level in the
calling hierarchy.
Rationale: the two branches are peers. Neither should be
treated as if it is a subordinate of the other. That peerage
is better expressed by making them two branches of the same if
statement, rather than conditionally calling one of the branches
from inside the other.
Minor performance benefit: for one of the branches we avoid an
extra layer of function call.
4. Related to the above: renamed osrfRouterHandleMessage() to
osrfRouterHandleCommand(), since handling commands is all it
does now. Also rearranged its logic a bit.
scottmk [Tue, 3 Nov 2009 00:00:59 +0000 (00:00 +0000)]
In the main loop of the router: if the select call fails for
any reason other than an harmless signal (i.e. one whose
handler didn't set a switch to stop the loop), then break
out of the loop and terminate.
The old code would ignore the error and keep looping, using up
ca. 98% of the CPU until somebody killed it.
scottmk [Mon, 2 Nov 2009 23:21:52 +0000 (23:21 +0000)]
1. Move the declaration of osrfRouter out of the header
and into osrf_router.c. There's no need for any other
source file to know about the internals.
2. Eliminate the ROUTER_SOCKFD macro in favor of the new
client_sock_fd() function. Reason: it needlessly coupled
the osrfRouter and osrfRouterClass structures by requiring
each of them to have a member named "connection".
3. Further tinkering with the comments.
M src/router/osrf_router.h
M src/router/osrf_router.c
scottmk [Mon, 2 Nov 2009 14:41:22 +0000 (14:41 +0000)]
Changed the signal handling.
There are very few things you can safely do within a signal handler, and
shutting down an osrfRouter is not among them.
Now the signal handler just sets a switch for the main loop to look at.
The select call looks for errno == EINTR and then looks at the switch
that the signal handler sets. If the switch is set, we exit the otherwise
infinite loop. Then we free the osrfRouter and re-raise the signal.
M src/router/osrf_router.h
M src/router/osrf_router.c
M src/router/osrf_router_main.c
dbs [Sun, 25 Oct 2009 21:44:26 +0000 (21:44 +0000)]
Improve the 'help' output for srfsh:
* Document the method-name parameter for the introspect command
* Document the currently supported srfsh variables
* Reorganize the help slightly to place more emphasis on
introspect and request and cut down on some of the blank lines.
scottmk [Sun, 25 Oct 2009 17:02:06 +0000 (17:02 +0000)]
1. Moved several macros from the header to the implementation file. They aren't used
anywhere else.
2. Renamed SERVER_SOCKET and CLIENT_SOCKET to LISTENER_SOCKET and DATA_SOCKET,
respectively. The new names more accurately reflect the uses to which the two
socket types are put. (Note that some so-called CLIENT_SOCKETs were, in fact,
opened by servers.)
3. Changed socket_open_udp_server() to open a DATA_SOCKET (formerly called a
CLIENT_SOCKET) instead of a LISTENER_SOCKET (formerly called a SERVER_SOCKET).
Otherwise an attempt to wait on such a socket would wind up treating it like
a listener. That doesn't work for UDP. In practice this change has no effect,
since no application ever calls this function anyway.
4. Always close a socket before removing the associated socket_node. Otherwise we
will leak sockets in some situations.
5. Tinkered further with the comments, especially in the header file.
M include/opensrf/socket_bundle.h
M src/libopensrf/socket_bundle.c
scottmk [Sun, 25 Oct 2009 05:35:47 +0000 (05:35 +0000)]
Merged _socket_route_data() into its only caller, after untangling its logic.
The old function traversed the linked list of socket_nodes in a loop,
examining each node at the bottom of the loop in order to identify the next
node. It went through elaborate and confusing gyrations to avoid dereferencing
a pointer for a node that had been deleted.
A better solution is to get a pointer to the next node *before* deleting the
current one. The resulting code is simple and easy to understand.
scottmk [Thu, 22 Oct 2009 03:21:31 +0000 (03:21 +0000)]
Various cleanups in transport_session.c:
1. In init_transport(): guard against a NULL server parameter.
2. In session_free(): if the session is still open, disconnect it.
3. In session_connect(): if we open a socket but are unable to connect to Jabber, close the
socket and set the sock_id member to zero. If the socket is already open, return an error,
instead of reusing the existing socket (and trying to overlay any open Jabber session).
4. In session_connect(): guard against an invalid auth_type.
5. In session_connect(): corrected some errors in the way we calculate buffer sizes,
6. In session_disconnect(): send a disconnect message only if the socket is still open.
7. Tidied up white space and comments in various places.
8. Added doxygen-style comments to document some of the functions.
scottmk [Sun, 18 Oct 2009 02:00:18 +0000 (02:00 +0000)]
Eliminated _socket_route_data_id() as a separate function, incorporating
its contents into the end of socket_wait().
Rationale: _socket_route_data_id() was called in only a single place.
It was little more than a mildly obfuscated if test, branching to two
very different functions. Having this code fragment in a separate function
just made the logic harder to follow.
scottmk [Tue, 13 Oct 2009 01:51:34 +0000 (01:51 +0000)]
1. Moved the declaration of socket_node from the header into the
implementation file. No other source files need to be exposed
to it.
2. Contrived to avoid leaking sockets in case of error exits;
sometimes by changing the sequence of operations, sometimes by
inserting a close().
3. In socket_open_tcp_client() and socket_open_udp_client():
removed the call to bind(). Ordinarily a client socket doesn't
need to know or care what its local address is.
4. In socket_open_udp_client(): eliminated the second and third
parameters, which define the remote address. That information
wasn't going anywhare anyway. For a UDP socket, you have no
use for the remote address until you actually try to send or
receive.
5. Added doxygen-style comments to document some of the functions.
M include/opensrf/socket_bundle.h
M src/libopensrf/socket_bundle.c
scottmk [Mon, 12 Oct 2009 18:09:18 +0000 (18:09 +0000)]
1. Replace the old JSON parser (jsonParseString()) with a newer, faster one
(jsonParse()).
2. Because the new JSON parser is strict about syntax errors that the old
parser would ignore, it was necessary to parse the srfsh command line more
intelligently. Otherwise it would be impossible to build a JSON string
internally with reliably correct syntax.
Hence: instead of using strtok() to break up the command line into tokens, we
now use a rudimentary recursive descent parser to isolate JSON strings as
distinct arguments, even if they contain embedded white space.
As a fairly benign side effect of these changes, the treatment of commas
in the command line is changing a bit. All parts of the command line
(not just JSON strings) may now be optionally separated by commas.
3. We now use an osrfStringArray to hold the results of parsing, rather
than a bare array of pointers.
4. The function formerly known as "parse_request" is now named "process_request",
because it does a lot more than just parsing.
scottmk [Sat, 10 Oct 2009 02:28:49 +0000 (02:28 +0000)]
Performance tweak to the logging routines.
_osrfLogToFile() is no longer a variadic function. We always sent it the
same format string, and there was no point in sending a variable-length
parameter list that never actually varied in length.
Now we send it a fixed-length parameter list -- and thereby avoid two
calls to vsnprintf() that had been hidden in the VA_LIST_TO_STRING macro.
Also: added doxygen-style comments to several of the functions.
scottmk [Thu, 8 Oct 2009 18:26:37 +0000 (18:26 +0000)]
Fix a bug in md5sum() (which only affected code compiled
with debugging turned on).
md5sum() builds an md5 message digest in a buffer. Originally
it used memset() to initialize the buffer with binary zeroes.
At some point the call to memset() was replaced with the
osrf_clearbuf() macro. When compiled in debugging mode,
osrf_clearbuf() fills the buffer with exclamation points;
otherwise it reverts to the original memset().
In this case the use of osrf_clearbuf is inappropriate, because
we use strcat() to build the message digest, two bytes at a
time. We don't need to use memset(), but the first byte needs
to be initialized to a nul byte so that strcat() will work as
intended. Hence:
1. Remove the call to osrf_clearbuf().
2. Put a nul byte at the beginning of the buffer.
Also, I made the buffer smaller. There's no reason for it
to be 256 bytes long.