[NET] Fix some 'net help' and 'net user' issues.
[reactos.git] / base / applications / network / net / cmdUser.c
index d093ffc..0cb5dac 100644 (file)
@@ -488,6 +488,130 @@ BuildWorkstationsList(
 }
 
 
+static
+BOOL
+ReadNumber(
+    PWSTR *s,
+    PWORD pwValue)
+{
+    if (!iswdigit(**s))
+        return FALSE;
+
+    while (iswdigit(**s))
+    {
+        *pwValue = *pwValue * 10 + **s - L'0';
+        (*s)++;
+    }
+
+    return TRUE;
+}
+
+
+static
+BOOL
+ReadSeparator(
+    PWSTR *s)
+{
+    if (**s == L'/' || **s == L'.')
+    {
+        (*s)++;
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+
+static
+BOOL
+ParseDate(
+    PWSTR s,
+    PULONG pSeconds)
+{
+    SYSTEMTIME SystemTime = {0};
+    FILETIME LocalFileTime, FileTime;
+    LARGE_INTEGER Time;
+    INT nDateFormat = 0;
+    PWSTR p = s;
+
+    if (!*s)
+        return FALSE;
+
+    GetLocaleInfoW(LOCALE_USER_DEFAULT,
+                   LOCALE_IDATE,
+                   (PWSTR)&nDateFormat,
+                   sizeof(INT));
+
+    switch (nDateFormat)
+    {
+        case 0: /* mmddyy */
+        default:
+            if (!ReadNumber(&p, &SystemTime.wMonth))
+                return FALSE;
+            if (!ReadSeparator(&p))
+                return FALSE;
+            if (!ReadNumber(&p, &SystemTime.wDay))
+                return FALSE;
+            if (!ReadSeparator(&p))
+                return FALSE;
+            if (!ReadNumber(&p, &SystemTime.wYear))
+                return FALSE;
+            break;
+
+        case 1: /* ddmmyy */
+            if (!ReadNumber(&p, &SystemTime.wDay))
+                return FALSE;
+            if (!ReadSeparator(&p))
+                return FALSE;
+            if (!ReadNumber(&p, &SystemTime.wMonth))
+                return FALSE;
+            if (!ReadSeparator(&p))
+                return FALSE;
+            if (!ReadNumber(&p, &SystemTime.wYear))
+                return FALSE;
+            break;
+
+        case 2: /* yymmdd */
+            if (!ReadNumber(&p, &SystemTime.wYear))
+                return FALSE;
+            if (!ReadSeparator(&p))
+                return FALSE;
+            if (!ReadNumber(&p, &SystemTime.wMonth))
+                return FALSE;
+            if (!ReadSeparator(&p))
+                return FALSE;
+            if (!ReadNumber(&p, &SystemTime.wDay))
+                return FALSE;
+            break;
+    }
+
+    /* if only entered two digits: */
+    /*   assume 2000's if value less than 80 */
+    /*   assume 1900's if value greater or equal 80 */
+    if (SystemTime.wYear <= 99)
+    {
+        if (SystemTime.wYear >= 80)
+            SystemTime.wYear += 1900;
+        else
+            SystemTime.wYear += 2000;
+    }
+
+    if (!SystemTimeToFileTime(&SystemTime, &LocalFileTime))
+        return FALSE;
+
+    if (!LocalFileTimeToFileTime(&LocalFileTime, &FileTime))
+        return FALSE;
+
+    Time.u.LowPart = FileTime.dwLowDateTime;
+    Time.u.HighPart = FileTime.dwHighDateTime;
+
+    if (!RtlTimeToSecondsSince1970(&Time, pSeconds))
+        return FALSE;
+
+    return TRUE;
+}
+
+
 INT
 cmdUser(
     INT argc,
@@ -512,28 +636,15 @@ cmdUser(
     BOOL bPasswordAllocated = FALSE;
     NET_API_STATUS Status;
 
-    if (argc == 2)
-    {
-        Status = EnumerateUsers();
-        ConPrintf(StdOut, L"Status: %lu\n", Status);
-        return 0;
-    }
-    else if (argc == 3)
-    {
-        Status = DisplayUser(argv[2]);
-        ConPrintf(StdOut, L"Status: %lu\n", Status);
-        return 0;
-    }
-
     i = 2;
-    if (argv[i][0] != L'/')
+    if ((i < argc) && (argv[i][0] != L'/'))
     {
         lpUserName = argv[i];
 //        ConPrintf(StdOut, L"User: %s\n", lpUserName);
         i++;
     }
 
-    if (argv[i][0] != L'/')
+    if ((i < argc) && (argv[i][0] != L'/'))
     {
         lpPassword = argv[i];
 //        ConPrintf(StdOut, L"Password: %s\n", lpPassword);
@@ -544,7 +655,7 @@ cmdUser(
     {
         if (_wcsicmp(argv[j], L"/help") == 0)
         {
-            ConResPuts(StdOut, IDS_USER_HELP);
+            PrintNetMessage(MSG_USER_HELP);
             return 0;
         }
         else if (_wcsicmp(argv[j], L"/add") == 0)
@@ -570,6 +681,19 @@ cmdUser(
         }
     }
 
+    if (lpUserName == NULL && lpPassword == NULL)
+    {
+        Status = EnumerateUsers();
+        ConPrintf(StdOut, L"Status: %lu\n", Status);
+        return 0;
+    }
+    else if (lpUserName != NULL && lpPassword == NULL)
+    {
+        Status = DisplayUser(lpUserName);
+        ConPrintf(StdOut, L"Status: %lu\n", Status);
+        return 0;
+    }
+
     if (bAdd && bDelete)
     {
         result = 1;
@@ -605,6 +729,8 @@ cmdUser(
         UserInfo.usri4_name = lpUserName;
         UserInfo.usri4_password = lpPassword;
         UserInfo.usri4_flags = UF_SCRIPT | UF_NORMAL_ACCOUNT;
+        UserInfo.usri4_acct_expires = TIMEQ_FOREVER;
+        UserInfo.usri4_primary_group_id = DOMAIN_GROUP_RID_USERS;
 
         pUserInfo = &UserInfo;
     }
@@ -655,10 +781,14 @@ cmdUser(
             {
                 pUserInfo->usri4_acct_expires = TIMEQ_FOREVER;
             }
-            else
+            else if (!ParseDate(p, &pUserInfo->usri4_acct_expires))
             {
+                ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"/EXPIRES");
+                result = 1;
+                goto done;
+
                 /* FIXME: Parse the date */
-                ConResPrintf(StdErr, IDS_ERROR_OPTION_NOT_SUPPORTED, L"/EXPIRES");
+//                ConResPrintf(StdErr, IDS_ERROR_OPTION_NOT_SUPPORTED, L"/EXPIRES");
             }
         }
         else if (_wcsnicmp(argv[j], L"/fullname:", 10) == 0)
@@ -793,7 +923,7 @@ done:
     if (result != 0)
     {
         ConResPuts(StdOut, IDS_GENERIC_SYNTAX);
-        ConResPuts(StdOut, IDS_USER_SYNTAX);
+        PrintNetMessage(MSG_USER_SYNTAX);
     }
 
     return result;