cURL / Mailing Lists / curl-library / Single Mail

curl-library

$HOME patches

From: Gisle Vanem <gvanem_at_broadpark.no>
Date: Tue, 28 Oct 2003 20:21:40 +0100

I've patched libcurl with a new function 'curl_get_homedir()'
to hide the details and support Windows users which normally
doesn't ever set a $HOME.

Besides, the previous use of ExpandEnvironmentStrings()
was wrong. E.g. getenv ("%var%\foo") always returns NULL.
It now expands %var% to one level and returns non-NULL if
*no more* sub-variable(s) present. See test output below.

curl_get_homedir() uses the 'pw_dir' for for Unix/VMS
before testing $HOME (moved from netrc.c).

Patched curl's main.c and netrc.c to use the new function.

--- CVS-latest\lib\netrc.c Wed Aug 20 16:40:21 2003
+++ lib\netrc.c Tue Oct 28 19:58:26 2003
@@ -33,9 +33,6 @@
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
 #ifdef VMS
 #include <unixlib.h>
 #endif
@@ -90,29 +87,11 @@
 
 #define NETRC DOT_CHAR "netrc"
 
-#if defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
- struct passwd *pw;
- pw= getpwuid(geteuid());
- if (pw) {
-#ifdef VMS
- home = decc$translate_vms(pw->pw_dir);
-#else
- home = pw->pw_dir;
-#endif
- }
-#else
- void *pw=NULL;
-#endif
-
- if(NULL == pw) {
- home = curl_getenv("HOME"); /* portable environment reader */
- if(!home) {
+ home = curl_get_homedir();
+ if (!home)
       return -1;
- }
- }
 
   if(strlen(home)>(sizeof(netrcbuffer)-strlen(NETRC))) {
- if(NULL==pw)
       free(home);
     return -1;
   }
@@ -128,13 +107,11 @@
     char *override = curl_getenv("CURL_DEBUG_NETRC");
 
     if (override != NULL) {
- printf("NETRC: overridden .netrc file: %s\n", home);
+ printf("NETRC: overridden %s file: %s\n", NETRC, home);
 
       if (strlen(override)+1 > sizeof(netrcbuffer)) {
         free(override);
- if(NULL==pw)
           free(home);
-
         return -1;
       }
       strcpy(netrcbuffer, override);
@@ -223,7 +200,6 @@
     fclose(file);
   }
 
- if(NULL==pw)
     free(home);
 
   return retcode;

--- CVS-latest\lib\getenv.c Thu Jun 26 12:22:12 2003
+++ lib\getenv.c Tue Oct 28 19:27:01 2003
@@ -35,35 +35,132 @@
 #include <unixlib.h>
 #endif

+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
 #ifdef CURLDEBUG
 #include "memdebug.h"
 #endif

 static
-char *GetEnv(const char *variable)
+char *GetEnv(const char *variable, int do_expand)
 {
-#ifdef WIN32
- /* This shit requires windows.h (HUGE) to be included */
- char env[MAX_PATH]; /* MAX_PATH is from windef.h */
- char *temp = getenv(variable);
- env[0] = '\0';
- if (temp != NULL)
- ExpandEnvironmentStrings(temp, env, sizeof(env));
-#else
-#ifdef VMS
- char *env = getenv(variable);
+ char *env = NULL;
+
+#ifdef GETENV_TEST
+ printf ("looking for \"%s\" -> ", variable);
+#endif
+
+#if defined(WIN32)
+ {
+ char buf1[1024], buf2[1024];
+ DWORD rc;
+
+ /* Don't use getenv(); it doesn't find variable added after program
+ * was started. Don't accept truncated results (i.e. rc >= sizeof(buf1)).
+ */
+ rc = GetEnvironmentVariable(variable, buf1, sizeof(buf1));
+ if (rc > 0 && rc < sizeof(buf1)) {
+ env = buf1;
+ variable = buf1;
+ }
+
+ if (do_expand && strchr(variable,'%')) {
+ /* buf2 == variable if not expanded */
+ rc = ExpandEnvironmentStrings (variable, buf2, sizeof(buf2));
+ if (rc > 0 && rc < sizeof(buf2) &&
+ !strchr(buf2,'%')) /* no vars still unexpanded */
+ env = buf2;
+ }
+ }
+#elif defined(VMS)
+ env = getenv(variable);
   if (env && strcmp("HOME",variable) == 0) {
  env = decc$translate_vms(env);
   }
 #else
- /* no length control */
- char *env = getenv(variable);
+ env = getenv(variable); /* no length control */
 #endif
+
+#ifdef GETENV_TEST
+ printf ("\"%s\"\n", env);
 #endif
+
+ (void)do_expand;
   return (env && env[0])?strdup(env):NULL;
 }

 char *curl_getenv(const char *v)
 {
- return GetEnv(v);
+ if (!v || !v[0])
+ return (NULL);
+ return GetEnv(v,0); /* Expanding 'v' could be dangerous */
+}
+
+char *curl_get_homedir (void)
+{
+ char *home = NULL;
+
+#if defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
+ struct passwd *pw = getpwuid(geteuid());
+
+ if (pw) {
+#ifdef VMS
+ home = decc$translate_vms(pw->pw_dir);
+#else
+ home = pw->pw_dir;
+#endif
+ if (home && home[0])
+ home = strdup(home);
+ }
+#elif defined(WIN32)
+ home = GetEnv("APPDATA",1);
+ if (!home)
+ home = GetEnv("%USERPROFILE%\\Application Data",1); /* Normally only on Win-2K/XP */
+#endif
+
+ if (!home)
+ home = GetEnv("HOME",0);
+ return (home);
+}
+
+
+#ifdef GETENV_TEST
+int main (void)
+{
+ puts ("HOME dir:");
+ curl_get_homedir();
+
+ GetEnv ("proxy",1);
+ GetEnv ("PROXY",1);
+
+#ifdef WIN32
+ GetEnv ("pop3-%HOST%",1);
+ GetEnv ("pop3-%USERNAME%",1);
+ GetEnv ("WINDIR",1); /* check that Windows is case-insensitive */
+ GetEnv ("windir",1);
+ GetEnv ("USERPROFILE",1);
+ SetEnvironmentVariable ("foo", "%HOMEDRIVE%%HOMEPATH%");
+ printf ("%%foo%%: %s (should be same as %%USERPROFILE%%)\n", GetEnv("foo",1));
+#endif
+
+ return (0);
+
+/*
+
+HOME dir:
+looking for "APPDATA" -> "f:\Documents and Settings\Gisle Vanem\Programdata"
+looking for "proxy" -> "(null)"
+looking for "PROXY" -> "(null)"
+looking for "pop3-%HOST%" -> "(null)"
+looking for "pop3-%USERNAME%" -> "pop3-Gisle Vanem"
+looking for "WINDIR" -> "f:\windows"
+looking for "windir" -> "f:\windows"
+looking for "USERPROFILE" -> "f:\Documents and Settings\Gisle Vanem"
+looking for "foo" -> "f:\Documents and Settings\Gisle Vanem"
+%foo%: f:\Documents and Settings\Gisle Vanem (should be same as %USERPROFILE%)
+
+*/
 }
+#endif

--- CVS-latest\include\curl\curl.h Tue Oct 21 15:11:25 2003
+++ include\curl\curl.h Tue Oct 28 20:20:44 2003
@@ -897,6 +897,17 @@
 char *curl_getenv(const char *variable);
 
 /*
+ * NAME curl_get_homedir()
+ *
+ * DESCRIPTION
+ *
+ * Returns a malloc()'ed string of user's $HOME (Unix) or
+ * %APPDATA%, '%USERPROFILE%\Application Data' (Windows) directory.
+ * MUST be curl_free()ed after usage is complete.
+ */
+char *curl_get_homedir(void);
+
+/*
  * NAME curl_version()
  *
  * DESCRIPTION

--- CVS-latest\src\main.c Tue Oct 28 10:28:11 2003
+++ src\main.c Tue Oct 28 19:38:03 2003
@@ -1998,7 +1998,7 @@
 #define CURLRC DOT_CHAR "curlrc"

     filename = CURLRC; /* sensible default */
- home = curl_getenv("HOME"); /* portable environment reader */
+ home = curl_get_homedir();
     if(home) {
       if(strlen(home)<(sizeof(filebuffer)-strlen(CURLRC))) {

--- CVS-latest\docs\MANUAL Fri Aug 01 15:20:48 2003
+++ docs\MANUAL Tue Oct 28 19:46:02 2003
@@ -454,8 +454,12 @@

 CONFIG FILE

- Curl automatically tries to read the .curlrc file (or _curlrc file on win32
- systems) from the user's home dir on startup.
+ Curl automatically tries to read the .curlrc file (or _curlrc file on Win32
+ or DOS systems) from the user's home dir on startup. The home-directory on
+ Windows is determined by environment variables:
+ - "%APPDATA%" or
+ - "%USERPROFILE%\Application Data" or
+ - "%HOME%" as final resort.

   The config file could be made up with normal command line switches, but you
   can also specify the long options without the dashes to make it more

----------------

Gisle V.

There are only 10 types of people in this world...
those who understand binary, and those who don't.

-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
Does SourceForge.net help you be more productive? Does it
help you create better code? SHARE THE LOVE, and help us help
YOU! Click Here: http://sourceforge.net/donate/
Received on 2003-10-28