*
* Email: crh@ubiqx.mn.org
*
- * $Id: PrequelD.c 2012-09-20 12:19:52 -0500 crh$
+ * $Id: PrequelD.c 2012-10-05 17:15:18 -0500 crh$
*
* -------------------------------------------------------------------------- **
*
*
* FIX:
*
- * + The exclude configuration command doesn't yet work.
+ * + The 'exclude' configuration command doesn't yet work.
*
* + Need to detect whether we are running already or not. We can run
* multiple daemons at once, as long as their src directories don't
* forEach( V, L ) - A macro for traversing a linked list of <pd_ConfigRec>
* records.
* V - The variable that will point to each node in the
- * list. V must be substituted by a pointer to a
+ * list. <V> must be substituted by a pointer to a
* <pd_ConfigRec>.
* L - The list to be traversed.
*
* is true, then the client did provide a value and that value
* is stored in the <val> field.
*
- * ProtVers - PeerDist protocol major/minor number structure.
- *
* WorkItem - A queue entry and a string pointer pointing to the pathname
* of a source file that is in need of hashing.
*
uint64_t val; /* The given value. */
} RangeVal;
-typedef struct
- {
- unsigned char major; /* PeerDist major version number. */
- unsigned char minor; /* PeerDist minor version number. */
- } ProtVers;
-
typedef struct
{
ubi_slNode node; /* Linked list node. */
static const char *Revision =
"$Revision$";
static const char *Id =
- "$Id: PrequelD.c 2012-09-20 12:19:52 -0500 crh$";
+ "$Id: PrequelD.c 2012-10-05 17:15:18 -0500 crh$";
static const char *HelpMsg[] =
{
*
* Notes: The <RecvErrs> type defines the list of possible error codes.
* Note, however, that a return value of zero (0) should not be
- * interpreted as <rv_success>. It should be interpreted as '\0'
+ * interpreted as <rv_success>. It should be interpreted as '\0',
* a valid input character.
*
* The buffer is refilled if it is empty, which means that the
* most recent character returned will still be in the buffer.
* so "unget" of one character is always safe. There are no
- * guarantees beyond that.
+ * guarantees beyond that (...and we don't do "unget" in this
+ * program, so it's a moot point).
*
* ------------------------------------------------------------------------ **
*/
} /* QueuePath */
-static RecvErrs QueryPath( int outSock, char const *pathname )
+static RecvErrs QueryPath( int outSock,
+ const int vMajor,
+ char const *pathname )
/* ------------------------------------------------------------------------ **
* Map a source file pathname to the matching cachefile name.
*
* Input: outSock - Output socket, so we can communicate the results
* to the client.
+ * vMajor - Requested PeerDist major version.
* pathname - The pathname to be added to the queue.
*
* Output: A <RecvErrs> error code.
*
+ * Notes: This function, as written, does not accept a PeerDist minor
+ * version number. At the time of writing, the only PeerDist
+ * defined PeerDist versions are 1.0 and 2.0. It is not clear
+ * how we would use the minor number.
+ *
* ------------------------------------------------------------------------ **
*/
{
}
/* We have mutex and a configuration entry.
- * Copy all of the config values so that we can release the mutex.
+ * Look up the name of the matching cache file, based on PeerDist version.
+ * Note: We don't yet support PeerDistv2, so we don't test for it.
*/
- tmpstr = pd_v1GenCacheName( pathname, entry->cacheDir );
+ switch( vMajor )
+ {
+ case 1:
+ tmpstr = pd_v1GenCacheName( pathname, entry->cacheDir );
+ break;
+ default:
+ tmpstr = NULL;
+ }
+
+ /* Did we map to a cachefile name? */
if( NULL == tmpstr )
{
(void)SendResponse( outSock, "ERROR: Queried file not found.\n" );
}
(void)pthread_mutex_unlock( &GlobalMutex );
}
+
return( result );
} /* QueryPath */
+static char const *extractVersion( int vNumArray[], char const *src )
+ /* ------------------------------------------------------------------------ **
+ * Extract a version number from a QUERY request.
+ *
+ * Input: vNumArray - A pointer to an array of two integers. The major
+ * and minor version numbers will be written into
+ * this array:
+ * vNumArray[0] == PeerDist Major Number
+ * vNumArray[1] == PeerDist Minor Number
+ *
+ * src - The source string from which to read the version
+ * number. This should be beyond the
+ *
+ * Output: A pointer to the position in the string following the version
+ * information, if any. If there is no version information in,
+ * the string, the return value will be the same as <src>.
+ *
+ * Notes: This is an internal function, so it's not particularly
+ * comprehensive. It expects that the "QUERY " prefix of the
+ * QUERY command has already been stripped off of the <src>
+ * string.
+ *
+ * The version number should be passed as:'
+ * '[' <int> [ '.' <int> ] ']'
+ * For example, "[2]" or "[1,0]".
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ char const *c;
+ char *endptr;
+ long int tmp;
+
+ /* Initialize to default values. */
+ vNumArray[0] = 1;
+ vNumArray[1] = 0;
+
+ /* Look for the square bracket, which indicates a version specifier.
+ * Anything else will cause us to ignore the rest of the string.
+ */
+ while( ' ' == *src ) /* Should never happen, but eat spaces anyway. */
+ src++;
+ if( '[' != *src ) /* Not an opening bracket? */
+ return( src );
+
+ /* Looks good. Let's try to parse out major and minor numbers. */
+ c = src + 1;
+ tmp = strtol( c, &endptr, 10 );
+ /* The major number must be 1 or greater.
+ * strtol() returns zero on error, but we handle that the same way.
+ */
+ if( tmp > 0 )
+ {
+ c = endptr; /* Move beyond the numeric string we've read. */
+ vNumArray[0] = tmp;
+ while( ' ' == *c ) /* Eat any erroneous spaces. */
+ c++;
+ if( '.' == *c ) /* A dot indicates that a minor number exists. */
+ {
+ /* Read the minor version number.
+ * For the minor number, zero is the default.
+ */
+ c++;
+ tmp = strtol( c, &endptr, 10 );
+ c = endptr;
+ if( tmp > 0 )
+ vNumArray[1] = tmp;
+ }
+
+ /* Consume the closing bracket, and any additional spaces. */
+ while( (' ' == *c) || (']' == *c) )
+ c++;
+ return( c );
+ }
+
+ /* No major number found, so return the (updated?) source pointer. */
+ return( src );
+ } /* extractVersion */
+
+
static RecvErrs ParseRequest( RecvBufr *Rb )
/* ------------------------------------------------------------------------ **
* Parse and respond to a client request.
* ------------------------------------------------------------------------ **
*/
{
- char const *s; /* General purpose string pointer. */
- Gstr gsBufr[1]; /* A growable string to receive input. */
- RecvErrs result; /* Function call results. */
+ char const *s; /* General purpose string pointer. */
+ Gstr gsBufr[1]; /* A growable string to receive input. */
+ RecvErrs result; /* Function call results. */
+ int vNum[2]; /* PeerDist major/minor version number. */
/* Initialize the Gstr. */
if( NULL == initGstr( gsBufr ) )
else
{
if( 0 == strncasecmp( "QUERY ", s, 6 ) )
- result = QueryPath( Rb->sock, &s[6] );
+ {
+ s = extractVersion( vNum, &s[6] );
+ result = QueryPath( Rb->sock, vNum[0], s );
+ }
else
{
SendResponse( Rb->sock, "ERROR: Invalid request.\n" );
if( Verbosity > 3 )
- LockLog( "Error: Client sent invalid request: \"%s\".\n", s );
+ {
+ LockLog( "Error: Client sent invalid request: \"%s\".\n",
+ strGstr( gsBufr ) );
+ }
result = rv_invalid;
}
}