/* * Modification History * * 2003-October-13 Jason Rohrer * Created. * * 2003-October-14 Jason Rohrer * Finished implementation and got it to compile. * * 2003-October-16 Jason Rohrer * Fixed a deletion bug. * Added support for a file size return pointer in muteShareGetFile. * * 2003-November-4 Jason Rohrer * Added a function for getting upload info. * * 2003-November-6 Jason Rohrer * Added hashes and file sizes to search results. * * 2003-November-11 Jason Rohrer * Added b flag to fopen of binary files. * * 2003-December-23 Jason Rohrer * Added hash checking for incoming files. * * 2004-January-12 Jason Rohrer * Increased default timeout from 10 seconds to 30 seconds. * * 2004-February-12 Jason Rohrer * Added upload stats patch submitted by Mycroftxxx. * * 2004-February-13 Jason Rohrer * Cleaned up the patched upload-tracking code. * * 2004-February-21 Jason Rohrer * Changed GetFile callback spec to support fine-grained retry reporting. * * 2004-March-8 Jason Rohrer * Added support for passing fileInfo timeouts to file chunk handler. */ /** * The API for the file sharing layer of MUTE. * * All calls are thread-safe. * * All function parameters must be destroyed by caller. * All string parameters must be \0-terminated. * * Before calling this API, application should call * muteSeedRandomGenerator and muteStart * from the messageRouting layer * * After using this API, application should call * muteStop * from the messageRouting layer. * Application may also optionally call * muteGetRandomGeneratorState * from the messageRouting layer to save the state of the random generator. * * @author Jason Rohrer. */ #ifndef MUTE_FILE_SHARING_API #define MUTE_FILE_SHARING_API #include /** * Starts the file sharing layer of this node. * * Must be called before using the file sharing API. * * Should be called after calling muteSeedRandomGenerator and muteStart * from the messageRouting layer. */ void muteShareStart(); /** * Stops the file sharing layer of this node. * * Must be called after using the file sharing API. * * Should be called before calling muteStop from the messageRouting layer. */ void muteShareStop(); /** * Sets the root path that this node will share files from. * * If no path is set, this node defaults to sharing files from the "files" * directory. * * This path is saved between startups by this API (in the settings folder). * * @param inPath the platform-dependent path, relative to the main directory * of this node. * * Example:
 * muteSetSharingPath( "temp/myFiles" );
 * 
*/ void muteShareSetSharingPath( char *inPath ); /** * Gets the root path that this node is sharing files from. * * @return the platform-dependent path, relative to the main directory * of this node. */ char *muteShareGetSharingPath(); /** * Initiates a search on the network. * * This call returns after the search has been canceled by the handler. * * @param inSearchString a string of words to search for. * @param inResultHandler a callback function to pass received results to. * This function must return (char) and take the following arguments: * (char *inFileHostVirtualAddress, char *inFilePath, * int inFileLengthInBytes, char *inFileSHA1Hash, * void *inExtraArgument ). * inFileHostVirtualAddress is the virtual address of the host * returning the result. Will be destroyed by handler's caller. * inFilePath is the /-delimited file path of the result. * Will be destroyed by handler's caller. * inFileLengthInBytes is the length of the file in bytes. * inFileSHA1Hash is the SHA1 hash of the file contents as a hex-encoded * string. * Will be destroyed by handler's caller. * If no new results have been received after inTimeoutInMilliseconds * passes since the last handler call, the handler will be called * with inFileHostVirtualAddress, inFilePath, and inFileSHA1Hash set to NULL. * The handler should return true to continue the search or false * to cancel the search and ignore future results. * @param inExtraHandlerArgument pointer to an extra argument to be passed * in to the handler function each time it is called. * Must be destroyed by caller after the search has been canceled. * @param inTimeoutInMilliseconds the time to wait between results before * calling the handler with NULL arguments. * Defaults to 10 seconds (10,000 milliseconds). * * Example:
 * // define a handler function (this one writes results to a file)
 * char myResultHandler( char *inFileHostVirtualAddress, char *inFilePath,
 *                       unsigned long inFileLength, char *inFileHash,
 *                       void *inExtraArgument ) {
 *     // unwrap a file handle from our extra argument
 *     FILE *file = (FILE *)inExtraArgument;
 *         
 *     // check that arguments are not NULL
 *     // (in other words, new results have arrived)
 *     if( inFileHostVirtualAddress != NULL && inFilePath != NULL ) {
 *         fprintf( file, "%s : %s\n", inFileHostVirtualAddress, inFilePath );
 *         return true;
 *         }
 *     else {
 *         // no new results, must have timed out
 *         fclose( file );
 *         // cancel this search
 *         return false;
 *         }
 *     }
 *
 * // elsewhere in code, register the handler function to catch the results
 * // wrap file handle in extra argument
 * FILE *file = fopen( "searchResults", "w" );
 *
 * // use default timeout of 10 seconds
 * muteShareSearch( "test tone mp3", myChunkHandler, (void *)file );
 * 
*/ void muteShareSearch( char *inSearchString, char (*inResultHandler)( char *, char *, unsigned long, char *,void * ), void *inExtraHandlerArgument, int inTimeoutInMilliseconds = 10000 ); // constants returned by muteGetSharedFile const int MUTE_SHARE_FILE_NOT_FOUND = 0; const int MUTE_SHARE_FILE_TRANSFER_FAILED = 1; const int MUTE_SHARE_FILE_TRANSFER_CANCELED = 2; const int MUTE_SHARE_FILE_TRANSFER_COMPLETE = 3; const int MUTE_SHARE_FILE_TRANSFER_HASH_MISMATCH = 4; /** * Gets a file from a node on the network. * * This call returns after the file has been completely fetched and * passed through the handler. * * @param inVirtualAddress the virtual address of the file host. * @param inFilePath a /-delimited file path, relative to the host's * root sharing directory. * @param inFileHash the SHA1 hash of the file as a hex-encoded * ascii string. The received file will be checked against this hash. * @param inFileChunkHandler a callback function to pass received file * chunks to. This function must return (char) and take the following * arguments: * (unsigned char *inChunk, int inChunkLengthInBytes, * void *inExtraArgument ). * inChunk is the raw bytes of chunk data, or NULL to indicate that * the current chunk (or file info request) has timed out and will be * retried. * Will be destroyed by handler's caller. * inChunkLengthInBytes is the length of the chunk in bytes, or -1 if * the current chunk (or file info request) has timed out and will be * retried. * Will be destroyed by handler's caller. * The handler should return true to continue the transfer or false * to cancel the transfer. * @param inExtraHandlerArgument pointer to an extra argument to be passed * in to the handler function each time it is called. * Must be destroyed by caller after the file transmission is complete. * @param outFileSizeInBytes pointer to where the file size should be * returned. This value is set before the handler is called, so the * handler can use this value. * @param inTimeoutInMilliseconds the time to wait for the file info * to return. Defaults to 30 seconds (30,000 milliseconds). * * @return one of MUTE_SHARE_FILE_NOT_FOUND, * MUTE_SHARE_FILE_TRANSFER_CANCELED, MUTE_SHARE_FILE_TRANSFER_FAILED, * MUTE_SHARE_FILE_TRANSFER_COMPLETE, * or MUTE_SHARE_FILE_TRANSFER_HASH_MISMATCH. * * Example:
 * // define a handler function
 * char myChunkHandler( unsigned char *inChunk, int inChunkLengthInBytes,
 *                      void *inExtraArgument ) {
 *     // unwrap a file handle from our extra argument
 *     FILE *file = (FILE *)inExtraArgument;
 *     if( inChunk != NULL ) {
 *         // we have real data for this chunk, write it to file
 *         fwrite( inChunk, 1, inChunkLengthInBytes, file );
 *         }
 *     else {
 *         // chunk timed out, no data yet, do nothing
 *         }
 *     // do not cancel
 *     return true;
 *     }
 *
 * // elsewhere in code, register the handler function to fetch the file
 * // wrap file handle in extra argument
 * FILE *file = fopen( "receivedFile", "wb" );
 * int fileSize;
 * // use default timeout of 10 seconds
 * int result = muteShareGetFile( "C0D62D331359BF2A27BEA46693F1CD32E3B7519E",
 *                                "songs/test.mp3",
 *                                "9E6D1F25D46633BA1EC296A1D3813D887EBB8417",
 *                                myChunkHandler, (void *)file, &fileSize );
 * // after it returns, the file transfer is complete
 * fclose( file );
 * if( result != MUTE_SHARE_FILE_TRANSFER_COMPLETE ) {
 *     // handle a failure
 *     ...
 *     }
 * 
*/ int muteShareGetFile( char *inVirtualAddress, char *inFilePath, char *inFileHash, char (*inFileChunkHandler)( unsigned char *, int, void * ), void *inExtraHandlerArgument, int *outFileSizeInBytes, int inTimeoutInMilliseconds = 30000 ); /** * Gets a list of upload status information. * * @param outUploadIDs pointer to location where an array of unique IDs * for the uploads should be returned. * The array must be destroyed by caller. * @param outHostAddresses pointer to location where an array of host virutal * addresses strings, one for each upload, should be returned. * The array and the strings it contains must be destroyed by caller. * @param outFilePaths pointer to location where an array of file path * strings, one for each upload, should be returned. * The array and the strings it contains must be destroyed by caller. * @param outChunksInFile pointer to location where an array of chunk counts, * one for each upload, should be returned. * The returned values indicate how many chunks are in each file. * The array must be destroyed by caller. * @param outLastChunks pointer to location where an array of indexes of last * chunk sent, one for each upload should be returned. * These values give an estimate of how close an upload is to completion. * The array must be destroyed by caller. * @param outFirstChunkTimes pointer to location where an array of * first chunk times, one for each upload should be returned. * These values are times in seconds as returned by the system call * time( NULL ). * The array must be destroyed by caller. * @param outLastChunkTimes pointer to location where an array of * last chunk times, one for each upload should be returned. * These values are times in seconds as returned by the system call * time( NULL ). * The array must be destroyed by caller. * * @return the number of uploads. * (in other words, the length of each returned array). * * Example:
 * int *uploadIDs;
 * char **hostAddresses;
 * char **filePaths;
 * int *chunkCounts;
 * int *lastChunks;
 * unsigned long *firstChunkTimes;
 * unsigned long *lastChunkTimes;
 * int numUploads = muteShareGetUploadStatus( &uploadIDs, &hostAddresses,
 *                                            &filePaths, &chunkCounts,
 *                                            &lastChunks, &firstChunkTimes,
 *                                            &lastChunkTimes );
 *
 * // process information here
 * ...
 * // now destroyed returned arrays
 * for( int i=0; i
 */
int muteShareGetUploadStatus( int **outUploadIDs,
                              char ***outHostAddresses,
                              char ***outFilePaths,
                              int **outChunksInFile,
                              int **outLastChunks,
                              unsigned long **outFirstChunkTimes,
                              unsigned long **outLastChunkTimes );



#endif