mirror of https://github.com/BOINC/boinc.git
Add input file URL substitution for http and attic files (TODO: docs).
git-svn-id: svn+ssh://cvs.lpds.sztaki.hu/var/lib/svn/szdg/dcapi/trunk@2505 a7169a2c-3604-0410-bc95-c702d8d87f7a
This commit is contained in:
parent
7ac33bb384
commit
814237b798
|
@ -44,6 +44,10 @@ extern "C" {
|
||||||
#define CFG_ENABLESUSPEND "EnableSuspend"
|
#define CFG_ENABLESUSPEND "EnableSuspend"
|
||||||
/* Client uses native BOINC API instead of DC-API */
|
/* Client uses native BOINC API instead of DC-API */
|
||||||
#define CFG_NATIVECLIENT "NativeClient"
|
#define CFG_NATIVECLIENT "NativeClient"
|
||||||
|
/* Remote file rewrite regexp match string */
|
||||||
|
#define CFG_REGEXPMATCH "InputURLRewriteRegExpMatch"
|
||||||
|
/* Remote file rewrite regexp replace string */
|
||||||
|
#define CFG_REGEXPREPLACE "InputURLRewriteRegExpReplace"
|
||||||
|
|
||||||
/* File types in the working directory */
|
/* File types in the working directory */
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|
116
dcapi/boinc/wu.C
116
dcapi/boinc/wu.C
|
@ -286,6 +286,46 @@ static DC_Workunit *alloc_wu(void)
|
||||||
return wu;
|
return wu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform regular expression replacement for a given URL.
|
||||||
|
* @param url the URL to perform the replace on
|
||||||
|
* @return NULL-terminated string array of replacement result(s)
|
||||||
|
*/
|
||||||
|
gchar **replace_regex(const char *url)
|
||||||
|
{
|
||||||
|
if (!url)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
char *regex = DC_getCfgStr(CFG_REGEXPMATCH);
|
||||||
|
if (!regex)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
char *replace = DC_getCfgStr(CFG_REGEXPREPLACE);
|
||||||
|
if (!replace)
|
||||||
|
{
|
||||||
|
g_free(regex);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GRegex *reg = g_regex_new(regex, (GRegexCompileFlags)0, (GRegexMatchFlags)0, NULL);
|
||||||
|
if (!reg)
|
||||||
|
{
|
||||||
|
g_free(regex);
|
||||||
|
g_free(replace);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *res = g_regex_replace(reg, url, -1, 0, replace, (GRegexMatchFlags)0, NULL);
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
g_free(regex);
|
||||||
|
g_free(replace);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_strsplit(res, "\n", 0);
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* The WU description parser
|
* The WU description parser
|
||||||
*/
|
*/
|
||||||
|
@ -719,7 +759,7 @@ int DC_addWUInput(DC_Workunit *wu, const char *logicalFileName, const char *URL,
|
||||||
int ret;
|
int ret;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char *workpath;
|
char *workpath;
|
||||||
DC_PhysicalFile *file;
|
DC_PhysicalFile *file = NULL;
|
||||||
DC_RemoteFile *rfile;
|
DC_RemoteFile *rfile;
|
||||||
|
|
||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
|
@ -771,19 +811,40 @@ int DC_addWUInput(DC_Workunit *wu, const char *logicalFileName, const char *URL,
|
||||||
size_t size = va_arg(ap, size_t);
|
size_t size = va_arg(ap, size_t);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
|
// If regular expression for the Attic file gives valid substitutions,
|
||||||
|
// use substitued URLs and keep the file remote
|
||||||
|
gchar **repl = replace_regex(URL);
|
||||||
|
if (repl)
|
||||||
|
{
|
||||||
|
g_strfreev(repl);
|
||||||
|
_DC_destroyPhysicalFile(file);
|
||||||
|
|
||||||
|
rfile = _DC_createRemoteFile(logicalFileName, URL, md5, size);
|
||||||
|
if (!rfile)
|
||||||
|
return DC_ERR_INTERNAL;
|
||||||
|
|
||||||
|
wu->remote_input_files = g_list_append(wu->remote_input_files, rfile);
|
||||||
|
wu->num_remote_inputs++;
|
||||||
|
|
||||||
|
if (wu->serialized)
|
||||||
|
write_wudesc(wu);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
char *physicalFileName = g_strrstr(URL,"/");
|
char *physicalFileName = g_strrstr(URL,"/");
|
||||||
if ( !physicalFileName )
|
if (!physicalFileName)
|
||||||
{
|
{
|
||||||
DC_log(LOG_ERR, "URL of attic file has wrong format! URL: '%s'", URL);
|
DC_log(LOG_ERR, "URL of attic file has wrong format! URL: '%s'", URL);
|
||||||
return DC_ERR_BADPARAM;
|
return DC_ERR_BADPARAM;
|
||||||
}
|
}
|
||||||
physicalFileName++;
|
physicalFileName++;
|
||||||
physicalFileName = g_strdup(physicalFileName);
|
physicalFileName = g_strdup(physicalFileName);
|
||||||
|
|
||||||
char *physicalFileHashString = g_strdup_printf("%s %i\n",md5,(int)size);
|
char *physicalFileHashString = g_strdup_printf("%s %i\n", md5, (int)size);
|
||||||
|
|
||||||
DC_log(LOG_DEBUG, "Attic file details: logic: %s, url:%s, md5:%s, size:%i, file:%s, filecont:%s",
|
DC_log(LOG_DEBUG, "Attic file details: logic: %s, url:%s, md5:%s, size:%i, file:%s, filecont:%s",
|
||||||
logicalFileName,URL,md5,(int)size,physicalFileName,physicalFileHashString);
|
logicalFileName, URL, md5, (int)size, physicalFileName, physicalFileHashString);
|
||||||
|
|
||||||
file->physicalfilename = strdup(physicalFileName);
|
file->physicalfilename = strdup(physicalFileName);
|
||||||
g_free(physicalFileName);
|
g_free(physicalFileName);
|
||||||
|
@ -905,14 +966,14 @@ static int install_input_files(DC_Workunit *wu)
|
||||||
/* By creating the hard link ourselves we prevent BOINC from
|
/* By creating the hard link ourselves we prevent BOINC from
|
||||||
* copying the file later */
|
* copying the file later */
|
||||||
ret = link(file->path, dest);
|
ret = link(file->path, dest);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
if (file->physicalfilename)
|
if (file->physicalfilename)
|
||||||
{
|
{
|
||||||
if (errno == EEXIST)
|
if (errno == EEXIST)
|
||||||
{
|
{
|
||||||
DC_log(LOG_NOTICE, "File %s already exists under Boinc at %s. Skipping...",file->physicalfilename,dest);
|
DC_log(LOG_NOTICE, "File %s already exists under Boinc at %s. Skipping...",file->physicalfilename,dest);
|
||||||
}
|
}
|
||||||
else if (errno == ENOENT)
|
else if (errno == ENOENT)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
@ -921,22 +982,22 @@ static int install_input_files(DC_Workunit *wu)
|
||||||
{
|
{
|
||||||
DC_log(LOG_ERR, "Cannot create file %s: %s",dest,strerror(errno));
|
DC_log(LOG_ERR, "Cannot create file %s: %s",dest,strerror(errno));
|
||||||
g_free(dest);
|
g_free(dest);
|
||||||
return DC_ERR_INTERNAL;
|
return DC_ERR_INTERNAL;
|
||||||
}
|
}
|
||||||
fprintf(f, "This file has been generated by DC-API.\nOriginal location of this file:%s", dest);
|
fprintf(f, "This file has been generated by DC-API.\nOriginal location of this file:%s", dest);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
DC_log(LOG_DEBUG, "File %s has been created by DC-API under Boinc.",dest);
|
DC_log(LOG_DEBUG, "File %s has been created by DC-API under Boinc.",dest);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DC_log(LOG_ERR, "---Failed to install file %s to the "
|
DC_log(LOG_ERR, "---Failed to install file %s to the "
|
||||||
"Boinc download directory at %s: %s",
|
"Boinc download directory at %s: %s",
|
||||||
file->path, dest, strerror(errno));
|
file->path, dest, strerror(errno));
|
||||||
g_free(dest);
|
g_free(dest);
|
||||||
return DC_ERR_INTERNAL;
|
return DC_ERR_INTERNAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DC_log(LOG_ERR, "Failed to install file %s to the "
|
DC_log(LOG_ERR, "Failed to install file %s to the "
|
||||||
"Boinc download directory at %s: %s",
|
"Boinc download directory at %s: %s",
|
||||||
|
@ -950,7 +1011,7 @@ static int install_input_files(DC_Workunit *wu)
|
||||||
const char *hashFileExt=".md5";
|
const char *hashFileExt=".md5";
|
||||||
GString *hashFile;
|
GString *hashFile;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
hashFile = g_string_new(dest);
|
hashFile = g_string_new(dest);
|
||||||
g_string_append(hashFile, hashFileExt);
|
g_string_append(hashFile, hashFileExt);
|
||||||
|
|
||||||
|
@ -975,7 +1036,7 @@ static int install_input_files(DC_Workunit *wu)
|
||||||
fclose(f);
|
fclose(f);
|
||||||
DC_log(LOG_DEBUG, "Hash file \"%s\" has been created with content \"%s\".", hashFile->str, file->physicalfilehash);
|
DC_log(LOG_DEBUG, "Hash file \"%s\" has been created with content \"%s\".", hashFile->str, file->physicalfilehash);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_string_free(hashFile, TRUE);
|
g_string_free(hashFile, TRUE);
|
||||||
}
|
}
|
||||||
g_free(dest);
|
g_free(dest);
|
||||||
|
@ -1047,7 +1108,18 @@ static void append_wu_remote_file_info(GString *tmpl, int idx, DC_RemoteFile *fi
|
||||||
{
|
{
|
||||||
g_string_append(tmpl, "<file_info>\n");
|
g_string_append(tmpl, "<file_info>\n");
|
||||||
g_string_append_printf(tmpl, "\t<number>%d</number>\n", idx);
|
g_string_append_printf(tmpl, "\t<number>%d</number>\n", idx);
|
||||||
g_string_append_printf(tmpl, "\t<url>%s</url>\n", file->url);
|
gchar **alts = replace_regex(file->url);
|
||||||
|
if (!alts)
|
||||||
|
{
|
||||||
|
g_string_append_printf(tmpl, "\t<url>%s</url>\n", file->url);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; alts[i]; i++)
|
||||||
|
g_string_append_printf(tmpl, "\t<url>%s</url>\n", alts[i]);
|
||||||
|
g_strfreev(alts);
|
||||||
|
}
|
||||||
g_string_append_printf(tmpl, "\t<md5_cksum>%s</md5_cksum>\n", file->remotefilehash);
|
g_string_append_printf(tmpl, "\t<md5_cksum>%s</md5_cksum>\n", file->remotefilehash);
|
||||||
g_string_append_printf(tmpl, "\t<nbytes>%lu</nbytes>\n", file->remotefilesize);
|
g_string_append_printf(tmpl, "\t<nbytes>%lu</nbytes>\n", file->remotefilesize);
|
||||||
g_string_append(tmpl, "</file_info>\n");
|
g_string_append(tmpl, "</file_info>\n");
|
||||||
|
|
Loading…
Reference in New Issue