mirror of https://github.com/BOINC/boinc.git
252 lines
5.2 KiB
C
252 lines
5.2 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <dc_client.h>
|
|
|
|
/********************************************************************
|
|
* Helper Functions
|
|
*/
|
|
|
|
// Fortran strings are passed as character array which is not null-terminated plus length
|
|
//
|
|
static char *string_from_fortran(const char *string, int string_len)
|
|
{
|
|
char *p;
|
|
|
|
p = (char *)malloc(string_len + 1);
|
|
memcpy(p, string, string_len);
|
|
p[string_len] = 0;
|
|
|
|
return p;
|
|
}
|
|
|
|
// remove terminating null and pad with blanks for FORTRAN
|
|
//
|
|
static void string_to_fortran(char *string, int string_len)
|
|
{
|
|
int i;
|
|
for (i = strlen(string); i < string_len; i++)
|
|
{
|
|
string[i] = ' ';
|
|
}
|
|
}
|
|
|
|
// remove whitespace from start and end of a string
|
|
//
|
|
void strip_whitespace(char *string)
|
|
{
|
|
int n;
|
|
|
|
while (1)
|
|
{
|
|
if (!string[0]) break;
|
|
if (!isascii(string[0])) break;
|
|
if (!isspace(string[0])) break;
|
|
strcpy(string, string+1);
|
|
}
|
|
|
|
while (1)
|
|
{
|
|
n = (int)strlen(string);
|
|
if (n == 0) break;
|
|
if (!isascii(string[n-1])) break;
|
|
if (!isspace(string[n-1])) break;
|
|
string[n-1] = 0;
|
|
}
|
|
}
|
|
|
|
/********************************************************************
|
|
* FORTRAN DC Client API Functions
|
|
*/
|
|
|
|
void dc_initclient_(int* retval)
|
|
{
|
|
*retval = DC_initClient();
|
|
}
|
|
|
|
char *DC_resolveFileNameAuto(const char *logicalFileName)
|
|
{
|
|
char *filename;
|
|
|
|
filename = DC_resolveFileName(DC_FILE_IN, filename);
|
|
if (!filename)
|
|
{
|
|
DC_resolveFileName(DC_FILE_TMP, filename);
|
|
if (!filename)
|
|
{
|
|
DC_log(LOG_ERR, "Resolving file '%s' failed!", filename);
|
|
return NULL;
|
|
}
|
|
DC_log(LOG_DEBUG, "file %s resolved by DC_FILE_TMP", filename);
|
|
return filename;
|
|
}
|
|
DC_log(LOG_DEBUG, "file %s resolved by DC_FILE_IN", filename);
|
|
return filename;
|
|
}
|
|
|
|
void dc_resolvefilename_(int* fileType, const char *logicalFileName, char *physicalFileName,
|
|
int logicalFileNameLen, int physicalFileNameLen)
|
|
{
|
|
char *filename;
|
|
|
|
filename = string_from_fortran(logicalFileName, logicalFileNameLen);
|
|
strip_whitespace(filename);
|
|
|
|
switch(*fileType)
|
|
{
|
|
case 1:
|
|
physicalFileName = DC_resolveFileName(DC_FILE_IN, filename);
|
|
break;
|
|
case 2:
|
|
physicalFileName = DC_resolveFileName(DC_FILE_OUT, filename);
|
|
break;
|
|
case 3:
|
|
physicalFileName = DC_resolveFileName(DC_FILE_TMP, filename);
|
|
break;
|
|
case 4:
|
|
physicalFileName = DC_resolveFileNameAuto(filename);
|
|
break;
|
|
default:
|
|
DC_log(LOG_ERR, "Undefined DC_FileType in DC_resolveFileName_ function call.");
|
|
DC_log(LOG_ERR, "DC_FileType: %d, logicalFileName: %s", *fileType, filename);
|
|
if (filename)
|
|
free(filename);
|
|
exit(1);
|
|
}
|
|
|
|
string_to_fortran(physicalFileName, physicalFileNameLen);
|
|
if(filename)
|
|
free(filename);
|
|
}
|
|
|
|
void dc_sendresult_(const char *logicalFileName, const char *path,
|
|
int* fileMode, int logicalFileNameLen, int pathLen, int* retval)
|
|
{
|
|
char *filename;
|
|
char *filePath;
|
|
|
|
filename = string_from_fortran(logicalFileName, logicalFileNameLen);
|
|
strip_whitespace(filename);
|
|
filePath = string_from_fortran(path, pathLen);
|
|
strip_whitespace(filePath);
|
|
|
|
switch(*fileMode)
|
|
{
|
|
case 1:
|
|
*retval = DC_sendResult(filename, filePath, DC_FILE_REGULAR);
|
|
break;
|
|
case 2:
|
|
*retval = DC_sendResult(filename, filePath, DC_FILE_PERSISTENT);
|
|
break;
|
|
case 3:
|
|
*retval = DC_sendResult(filename, filePath, DC_FILE_VOLATILE);
|
|
break;
|
|
default:
|
|
DC_log(LOG_ERR, "Undefined DC_FileMode in DC_sendResult function call.");
|
|
DC_log(LOG_ERR, "DC_FileMode: %d, logicalFileName: %s, path: %s",
|
|
*fileMode, filename, filePath);
|
|
if (filename)
|
|
free(filename);
|
|
if (filePath)
|
|
free(filePath);
|
|
exit(1);
|
|
}
|
|
if (filename)
|
|
free(filename);
|
|
if (filePath)
|
|
free(filePath);
|
|
}
|
|
|
|
void dc_sendmessage_(const char *message, int messageLen, int* retval)
|
|
{
|
|
char *msg;
|
|
|
|
msg = string_from_fortran(message, messageLen);
|
|
strip_whitespace(msg);
|
|
*retval = DC_sendMessage(msg);
|
|
if(msg)
|
|
free(msg);
|
|
}
|
|
|
|
void dc_checkclientevent_(void)
|
|
{
|
|
// XXX not impl yet
|
|
}
|
|
|
|
void dc_destroyclientevent_(void)
|
|
{
|
|
// XXX not impl yet
|
|
}
|
|
|
|
void dc_checkpointmade_(const char *filename, int filename_len)
|
|
{
|
|
char *file;
|
|
|
|
file = string_from_fortran(filename, filename_len);
|
|
strip_whitespace(file);
|
|
DC_checkpointMade(file);
|
|
if (file)
|
|
free(file);
|
|
}
|
|
|
|
void dc_fractiondone_(double* fraction)
|
|
{
|
|
DC_fractionDone(*fraction);
|
|
}
|
|
|
|
void dc_finishclient_(int* exitcode)
|
|
{
|
|
DC_finishClient(*exitcode);
|
|
}
|
|
|
|
void dc_getmaxmessagesize_(int* retval)
|
|
{
|
|
*retval = DC_getMaxMessageSize();
|
|
}
|
|
|
|
void dc_getmaxsubresults_(int* retval)
|
|
{
|
|
*retval = DC_getMaxSubresults();
|
|
}
|
|
|
|
void dc_getgridcapabilities_(void)
|
|
{
|
|
// XXX not impl yet
|
|
}
|
|
|
|
void dc_getcfgstr_(const char *name, char *string, int nameLen, int stringLen)
|
|
{
|
|
char *key;
|
|
char *value;
|
|
|
|
key = string_from_fortran(name, nameLen);
|
|
strip_whitespace(key);
|
|
string = DC_getCfgStr(key);
|
|
string_to_fortran(string, stringLen);
|
|
if (key)
|
|
free(key);
|
|
}
|
|
|
|
void dc_getcfgint_(const char *name, int* defaultValue, int nameLen, int* retval)
|
|
{
|
|
char *key;
|
|
|
|
key = string_from_fortran(name, nameLen);
|
|
strip_whitespace(key);
|
|
*retval = DC_getCfgInt(key, *defaultValue);
|
|
if (key)
|
|
free(key);
|
|
}
|
|
|
|
void dc_getcfgbool_(const char *name, int* defaultValue, int nameLen, int* retval)
|
|
{
|
|
char *key;
|
|
|
|
key = string_from_fortran(name, nameLen);
|
|
strip_whitespace(key);
|
|
*retval = DC_getCfgBool(key, *defaultValue);
|
|
if (key)
|
|
free(key);
|
|
}
|