minor cleanup
[p5sagit/p5-mst-13.2.git] / win32 / win32.c
index 1f7883b..5f7d487 100644 (file)
 #include <tchar.h>
 #ifdef __GNUC__
 #define Win32_Winsock
-#  ifdef __cplusplus
-#undef __attribute__           /* seems broken in 2.8.0 */
-#define __attribute__(p)
-#  endif
 #endif
 #include <windows.h>
 
@@ -95,7 +91,7 @@ static DWORD          os_id(void);
 static void            get_shell(void);
 static long            tokenize(char *str, char **dest, char ***destv);
        int             do_spawn2(char *cmd, int exectype);
-static BOOL            has_redirection(char *ptr);
+static BOOL            has_shell_metachars(char *ptr);
 static long            filetime_to_clock(PFILETIME ft);
 static BOOL            filetime_from_time(PFILETIME ft, time_t t);
 static char *          get_emd_part(char *leading, char *trailing, ...);
@@ -149,7 +145,7 @@ GetRegStrFromKey(HKEY hkey, const char *lpszValueName, char** ptr, DWORD* lpData
     if (retval == ERROR_SUCCESS){
        retval = RegQueryValueEx(handle, lpszValueName, 0, &type, NULL, lpDataLen);
        if (retval == ERROR_SUCCESS && type == REG_SZ) {
-           if (*ptr != NULL) {
+           if (*ptr) {
                Renew(*ptr, *lpDataLen, char);
            }
            else {
@@ -158,7 +154,7 @@ GetRegStrFromKey(HKEY hkey, const char *lpszValueName, char** ptr, DWORD* lpData
            retval = RegQueryValueEx(handle, lpszValueName, 0, NULL, (PBYTE)*ptr, lpDataLen);
            if (retval != ERROR_SUCCESS) {
                Safefree(*ptr);
-               *ptr = NULL;
+               *ptr = Nullch;
            }
        }
        RegCloseKey(handle);
@@ -170,7 +166,7 @@ char*
 GetRegStr(const char *lpszValueName, char** ptr, DWORD* lpDataLen)
 {
     *ptr = GetRegStrFromKey(HKEY_CURRENT_USER, lpszValueName, ptr, lpDataLen);
-    if (*ptr == NULL)
+    if (*ptr == Nullch)
     {
        *ptr = GetRegStrFromKey(HKEY_LOCAL_MACHINE, lpszValueName, ptr, lpDataLen);
     }
@@ -240,7 +236,7 @@ win32_get_privlib(char *pl)
     /* $stdlib = $HKCU{"lib-$]"} || $HKLM{"lib-$]"} || $HKCU{"lib"} || $HKLM{"lib"} || "";  */
     sprintf(buffer, "%s-%s", stdlib, pl);
     path = GetRegStr(buffer, &path, &datalen);
-    if (path == NULL)
+    if (!path)
        path = GetRegStr(stdlib, &path, &datalen);
 
     /* $stdlib .= ";$EMD/../../lib" */
@@ -293,17 +289,20 @@ win32_get_sitelib(char *pl)
 
 
 static BOOL
-has_redirection(char *ptr)
+has_shell_metachars(char *ptr)
 {
     int inquote = 0;
     char quote = '\0';
 
     /*
      * Scan string looking for redirection (< or >) or pipe
-     * characters (|) that are not in a quoted string
+     * characters (|) that are not in a quoted string.
+     * Shell variable interpolation (%VAR%) can also happen inside strings.
      */
     while (*ptr) {
        switch(*ptr) {
+       case '%':
+           return TRUE;
        case '\'':
        case '\"':
            if (inquote) {
@@ -474,7 +473,7 @@ do_aspawn(void *vreally, void **vmark, void **vsp)
     }
 
     while (++mark <= sp) {
-       if (*mark && (str = SvPV(*mark, na)))
+       if (*mark && (str = SvPV(*mark, PL_na)))
            argv[index++] = str;
        else
            argv[index++] = "";
@@ -482,7 +481,7 @@ do_aspawn(void *vreally, void **vmark, void **vsp)
     argv[index++] = 0;
    
     status = win32_spawnvp(flag,
-                          (const char*)(really ? SvPV(really,na) : argv[0]),
+                          (const char*)(really ? SvPV(really,PL_na) : argv[0]),
                           (const char* const*)argv);
 
     if (status < 0 && errno == ENOEXEC) {
@@ -495,7 +494,7 @@ do_aspawn(void *vreally, void **vmark, void **vsp)
            argv[sh_items] = w32_perlshell_vec[sh_items];
    
        status = win32_spawnvp(flag,
-                              (const char*)(really ? SvPV(really,na) : argv[0]),
+                              (const char*)(really ? SvPV(really,PL_na) : argv[0]),
                               (const char* const*)argv);
     }
 
@@ -525,7 +524,7 @@ do_spawn2(char *cmd, int exectype)
 
     /* Save an extra exec if possible. See if there are shell
      * metacharacters in it */
-    if (!has_redirection(cmd)) {
+    if (!has_shell_metachars(cmd)) {
        New(1301,argv, strlen(cmd) / 2 + 2, char*);
        New(1302,cmd2, strlen(cmd) + 1, char);
        strcpy(cmd2, cmd);
@@ -640,12 +639,8 @@ win32_opendir(char *filename)
        return NULL;
 
     /* check to see if filename is a directory */
-    if (win32_stat(filename, &sbuf) < 0 || (sbuf.st_mode & S_IFDIR) == 0) {
-       /* CRT is buggy on sharenames, so make sure it really isn't */
-       DWORD r = GetFileAttributes(filename);
-       if (r == 0xffffffff || !(r & FILE_ATTRIBUTE_DIRECTORY))
-           return NULL;
-    }
+    if (win32_stat(filename, &sbuf) < 0 || !S_ISDIR(sbuf.st_mode))
+       return NULL;
 
     /* Get us a DIR structure */
     Newz(1303, p, 1, DIR);
@@ -885,7 +880,7 @@ win32_sleep(unsigned int t)
 DllExport int
 win32_stat(const char *path, struct stat *buffer)
 {
-    char               t[MAX_PATH+1]; 
+    char       t[MAX_PATH+1]; 
     const char *p = path;
     int                l = strlen(path);
     int                res;
@@ -902,8 +897,22 @@ win32_stat(const char *path, struct stat *buffer)
        }
     }
     res = stat(p,buffer);
+    if (res < 0) {
+       /* CRT is buggy on sharenames, so make sure it really isn't.
+        * XXX using GetFileAttributesEx() will enable us to set
+        * buffer->st_*time (but note that's not available on the
+        * Windows of 1995) */
+       DWORD r = GetFileAttributes(p);
+       if (r != 0xffffffff && (r & FILE_ATTRIBUTE_DIRECTORY)) {
+           buffer->st_mode |= S_IFDIR | S_IREAD;
+           errno = 0;
+           if (!(r & FILE_ATTRIBUTE_READONLY))
+               buffer->st_mode |= S_IWRITE | S_IEXEC;
+           return 0;
+       }
+    }
 #ifdef __BORLANDC__
-    if (res == 0) {
+    else {
        if (S_ISDIR(buffer->st_mode))
            buffer->st_mode |= S_IWRITE | S_IEXEC;
        else if (S_ISREG(buffer->st_mode)) {
@@ -930,11 +939,13 @@ win32_stat(const char *path, struct stat *buffer)
 DllExport char *
 win32_getenv(const char *name)
 {
-    static char *curitem = Nullch;
-    static DWORD curlen = 512;
+    static char *curitem = Nullch;     /* XXX threadead */
+    static DWORD curlen = 0;           /* XXX threadead */
     DWORD needlen;
-    if (!curitem)
+    if (!curitem) {
+       curlen = 512;
        New(1305,curitem,curlen,char);
+    }
 
     needlen = GetEnvironmentVariable(name,curitem,curlen);
     if (needlen != 0) {
@@ -944,23 +955,22 @@ win32_getenv(const char *name)
            needlen = GetEnvironmentVariable(name,curitem,curlen);
        }
     }
-    else
-    {
-       /* allow any environment variables that begin with 'PERL5'
-          to be stored in the registry
-       */
-       if(curitem != NULL)
+    else {
+       /* allow any environment variables that begin with 'PERL'
+          to be stored in the registry */
+       if (curitem)
            *curitem = '\0';
 
-       if (strncmp(name, "PERL5", 5) == 0) {
-           if (curitem != NULL) {
+       if (strncmp(name, "PERL", 4) == 0) {
+           if (curitem) {
                Safefree(curitem);
-               curitem = NULL;
+               curitem = Nullch;
+               curlen = 0;
            }
            curitem = GetRegStr(name, &curitem, &curlen);
        }
     }
-    if(curitem != NULL && *curitem == '\0')
+    if (curitem && *curitem == '\0')
        return Nullch;
 
     return curitem;
@@ -1166,14 +1176,21 @@ win32_alarm(unsigned int sec)
     return 0;
 }
 
+#if defined(HAVE_DES_FCRYPT) || defined(PERL_OBJECT)
 #ifdef HAVE_DES_FCRYPT
-extern char *  des_fcrypt(char *cbuf, const char *txt, const char *salt);
+extern char *  des_fcrypt(const char *txt, const char *salt, char *cbuf);
+#endif
 
 DllExport char *
 win32_crypt(const char *txt, const char *salt)
 {
+#ifdef HAVE_DES_FCRYPT
     dTHR;
-    return des_fcrypt(crypt_buffer, txt, salt);
+    return des_fcrypt(txt, salt, crypt_buffer);
+#else
+    die("The crypt() function is unimplemented due to excessive paranoia.");
+    return Nullch;
+#endif
 }
 #endif
 
@@ -2122,7 +2139,7 @@ XS(w32_SetCwd)
     dXSARGS;
     if (items != 1)
        croak("usage: Win32::SetCurrentDirectory($cwd)");
-    if (SetCurrentDirectory(SvPV(ST(0),na)))
+    if (SetCurrentDirectory(SvPV(ST(0),PL_na)))
        XSRETURN_YES;
 
     XSRETURN_NO;
@@ -2194,7 +2211,7 @@ XS(w32_DomainName)
        char dname[256];
        DWORD dnamelen = sizeof(dname);
        SID_NAME_USE snu;
-       if (LookupAccountName(NULL, name, &sid, &sidlen,
+       if (LookupAccountName(NULL, name, (PSID)&sid, &sidlen,
                              dname, &dnamelen, &snu)) {
            XSRETURN_PV(dname);         /* all that for this */
        }
@@ -2305,8 +2322,8 @@ XS(w32_Spawn)
     if (items != 3)
        croak("usage: Win32::Spawn($cmdName, $args, $PID)");
 
-    cmd = SvPV(ST(0),na);
-    args = SvPV(ST(1), na);
+    cmd = SvPV(ST(0),PL_na);
+    args = SvPV(ST(1), PL_na);
 
     memset(&stStartInfo, 0, sizeof(stStartInfo));   /* Clear the block */
     stStartInfo.cb = sizeof(stStartInfo);          /* Set the structure size */
@@ -2362,7 +2379,7 @@ XS(w32_GetShortPathName)
        ST(0) = shortpath;
     }
     else
-       ST(0) = &sv_undef;
+       ST(0) = &PL_sv_undef;
     XSRETURN(1);
 }