diff --git a/checkin_notes b/checkin_notes
index 84a9a9d717..deac2388b8 100644
--- a/checkin_notes
+++ b/checkin_notes
@@ -6809,3 +6809,13 @@ Charlie 18 Aug 2008
clientgui/
AsyncRPC.cpp
+
+David 19 Aug 2008
+ - lib: added string_substitute() function
+ - lib: changed boinc_copy() to replace " " with "\ " in its args
+ (to allow pathnames containing spaces).
+ From Tolu Aina
+
+ lib/
+ filesys.C
+ str_util.C,h
diff --git a/doc/boinc_news.php b/doc/boinc_news.php
index 2258bfb310..21b851abff 100644
--- a/doc/boinc_news.php
+++ b/doc/boinc_news.php
@@ -33,12 +33,6 @@ array("July 9, 2008",
a PHP script to display BOINC stats on a webpage,
and store or retrieve these stats to a mySQL database."
),
-array("June 26, 2008",
- "Congratulations and thanks to volunteer
- Banshee from
- L'Alliance Francophone,
- who has recently contributed over 10 TeraFLOPS to several projects."
-),
array("June 16, 2008",
"3-D versions of the BOINC logo
are now available; thanks to John from Ireland for creating these."
diff --git a/lib/filesys.C b/lib/filesys.C
index 464f2eecce..0e48c0c92b 100644
--- a/lib/filesys.C
+++ b/lib/filesys.C
@@ -492,13 +492,15 @@ int boinc_copy(const char* orig, const char* newf) {
}
return 0;
#elif defined(__EMX__)
- char cmd[256];
+ char cmd[1024], cmd_esc[1024];
sprintf(cmd, "copy %s %s", orig, newf);
- return system(cmd);
+ string_substitute(cmd, cmd_esc, sizeof(cmd_esc), " ", "\\ ");
+ return system(cmd_esc);
#else
- char cmd[256];
+ char cmd[1024], cmd_esc[1024];
sprintf(cmd, "cp %s %s", orig, newf);
- return system(cmd);
+ string_substitute(cmd, cmd_esc, sizeof(cmd_esc), " ", "\\ ");
+ return system(cmd_esc);
#endif
}
diff --git a/lib/str_util.C b/lib/str_util.C
index 1407eded5b..d4fc8b3dab 100644
--- a/lib/str_util.C
+++ b/lib/str_util.C
@@ -843,4 +843,37 @@ char* windows_format_error_string(
}
#endif
+// string substitution:
+// haystack is the input string
+// out is the output buffer
+// out_len is the length of the output buffer
+// needle is string to search for within the haystack
+// target is string to replace with
+//
+int string_substitute(
+ const char* haystack, char* out, int out_len,
+ const char* needle, const char* target
+) {
+ unsigned int i=0, j=0;
+ int needle_len = strlen(needle);
+ int target_len = strlen(target);
+ int retval = 0;
+
+ while (haystack[i]) {
+ if (j+target_len >= out_len-1) {
+ retval = ERR_BUFFER_OVERFLOW;
+ break;
+ }
+ if (!strncmp(&haystack[i], needle, needle_len)){
+ strcpy(out+j, target);
+ i += strlen(needle);
+ j += strlen(target);
+ } else {
+ out[j++] = haystack[i++];
+ }
+ }
+ out[j] = 0;
+ return retval;
+}
+
const char *BOINC_RCSID_ab90e1e = "$Id$";
diff --git a/lib/str_util.h b/lib/str_util.h
index 22b9a4c763..2e4ceb0f96 100644
--- a/lib/str_util.h
+++ b/lib/str_util.h
@@ -78,6 +78,11 @@ inline void downcase_string(std::string& w) {
}
}
+extern int string_substitute(
+ const char* haystack, char* out, int out_len,
+ const char* needle, const char* target
+);
+
// convert UNIX time to MySQL timestamp (yyyymmddhhmmss)
//
extern void mysql_timestamp(double, char*);