/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* 
* http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

#include "winutils.h"
#include <errno.h>

enum CHMOD_WHO
{
  CHMOD_WHO_NONE  =    0,
  CHMOD_WHO_OTHER =   07,
  CHMOD_WHO_GROUP =  070,
  CHMOD_WHO_USER  = 0700,
  CHMOD_WHO_ALL   = CHMOD_WHO_OTHER | CHMOD_WHO_GROUP | CHMOD_WHO_USER
};

enum CHMOD_OP
{
  CHMOD_OP_INVALID,
  CHMOD_OP_PLUS,
  CHMOD_OP_MINUS,
  CHMOD_OP_EQUAL,
};

enum CHMOD_PERM
{
  CHMOD_PERM_NA =  00,
  CHMOD_PERM_R  =  01,
  CHMOD_PERM_W  =  02,
  CHMOD_PERM_X  =  04,
  CHMOD_PERM_LX = 010,
};

/*
 * We use the following struct to build a linked list of mode change actions.
 * The mode is described by the following grammar:
 *  mode         ::= clause [, clause ...]
 *  clause       ::= [who ...] [action ...]
 *  action       ::= op [perm ...] | op [ref]
 *  who          ::= a | u | g | o
 *  op           ::= + | - | =
 *  perm         ::= r | w | x | X
 *  ref          ::= u | g | o
 */
typedef struct _MODE_CHANGE_ACTION
{
  USHORT who;
  USHORT op;
  USHORT perm;
  USHORT ref;
  struct _MODE_CHANGE_ACTION *next_action;
} MODE_CHANGE_ACTION, *PMODE_CHANGE_ACTION;

const MODE_CHANGE_ACTION INIT_MODE_CHANGE_ACTION = {
  CHMOD_WHO_NONE, CHMOD_OP_INVALID, CHMOD_PERM_NA, CHMOD_WHO_NONE, NULL
};

static BOOL ParseOctalMode(LPCWSTR tsMask, INT *uMask);

static BOOL ParseMode(LPCWSTR modeString, PMODE_CHANGE_ACTION *actions);

static BOOL FreeActions(PMODE_CHANGE_ACTION actions);

static BOOL ParseCommandLineArguments(
  __in int argc,
  __in_ecount(argc) wchar_t *argv[],
  __out BOOL *rec,
  __out_opt INT *mask,
  __out_opt PMODE_CHANGE_ACTION *actions,
  __out LPCWSTR *path);

static BOOL ChangeFileModeByActions(__in LPCWSTR path,
  MODE_CHANGE_ACTION const *actions);

static BOOL ChangeFileMode(__in LPCWSTR path, __in_opt INT mode,
  __in_opt MODE_CHANGE_ACTION const *actions);

static BOOL ChangeFileModeRecursively(__in LPCWSTR path, __in_opt INT mode,
  __in_opt MODE_CHANGE_ACTION const *actions);


//----------------------------------------------------------------------------
// Function: Chmod
//
// Description:
//  The main method for chmod command
//
// Returns:
//  0: on success
//
// Notes:
//
int Chmod(__in int argc, __in_ecount(argc) wchar_t *argv[])
{
  LPCWSTR pathName = NULL;
  LPWSTR longPathName = NULL;

  BOOL recursive = FALSE;

  PMODE_CHANGE_ACTION actions = NULL;

  INT unixAccessMask = 0;

  DWORD dwRtnCode = 0;

  int ret = EXIT_FAILURE;

  // Parsing chmod arguments
  //
  if (!ParseCommandLineArguments(argc, argv,
    &recursive, &unixAccessMask, &actions, &pathName))
  {
    fwprintf(stderr, L"Incorrect command line arguments.\n\n");
    ChmodUsage(argv[0]);
    return EXIT_FAILURE;
  }

  // Convert the path to the long path
  //
  dwRtnCode = ConvertToLongPath(pathName, &longPathName);
  if (dwRtnCode != ERROR_SUCCESS)
  {
    ReportErrorCode(L"ConvertToLongPath", dwRtnCode);
    goto ChmodEnd;
  }

  if (!recursive)
  {
    if (ChangeFileMode(longPathName, unixAccessMask, actions))
    {
      ret = EXIT_SUCCESS;
    }
  }
  else
  {
    if (ChangeFileModeRecursively(longPathName, unixAccessMask, actions))
    {
      ret = EXIT_SUCCESS;
    }
  }

ChmodEnd:
  FreeActions(actions);
  LocalFree(longPathName);

  return ret;
}

//----------------------------------------------------------------------------
// Function: ChangeFileMode
//
// Description:
//  Wrapper function for change file mode. Choose either change by action or by
//  access mask.
//
// Returns:
//  TRUE: on success
//  FALSE: otherwise
//
// Notes:
//
static BOOL ChangeFileMode(__in LPCWSTR path, __in_opt INT unixAccessMask,
  __in_opt MODE_CHANGE_ACTION const *actions)
{
  if (actions != NULL)
    return ChangeFileModeByActions(path, actions);
  else
  {
    DWORD dwRtnCode = ChangeFileModeByMask(path, unixAccessMask);
    if (dwRtnCode != ERROR_SUCCESS)
    {
      ReportErrorCode(L"ChangeFileModeByMask", dwRtnCode);
      return FALSE;
    }
    return TRUE;
  }
}

//----------------------------------------------------------------------------
// Function: ChangeFileModeRecursively
//
// Description:
//  Travel the directory recursively to change the permissions.
//
// Returns:
//  TRUE: on success
//  FALSE: otherwise
//
// Notes:
//  The recursion works in the following way:
//    - If the path is not a directory, change its mode and return.
//      Symbolic links and junction points are not considered as directories.
//    - Otherwise, call the method on all its children, then change its mode.
//
static BOOL ChangeFileModeRecursively(__in LPCWSTR path, __in_opt INT mode,
  __in_opt MODE_CHANGE_ACTION const *actions)
{
  BOOL isDir = FALSE;
  BOOL isSymlink = FALSE;
  LPWSTR dir = NULL;

  size_t pathSize = 0;
  size_t dirSize = 0;

  HANDLE hFind = INVALID_HANDLE_VALUE;
  WIN32_FIND_DATA ffd;
  DWORD dwRtnCode = ERROR_SUCCESS;
  BOOL ret = FALSE;

  if ((dwRtnCode = DirectoryCheck(path, &isDir)) != ERROR_SUCCESS)
  {
    ReportErrorCode(L"IsDirectory", dwRtnCode);
    return FALSE;
  }
  if ((dwRtnCode = SymbolicLinkCheck(path, &isSymlink)) != ERROR_SUCCESS)
  {
    ReportErrorCode(L"IsSymbolicLink", dwRtnCode);
    return FALSE;
  }

  if (isSymlink || !isDir)
  {
     if (ChangeFileMode(path, mode, actions))
       return TRUE;
     else
       return FALSE;
  }

  if (FAILED(StringCchLengthW(path, STRSAFE_MAX_CCH - 3, &pathSize)))
  {
    return FALSE;
  }
  dirSize = pathSize + 3;
  dir = (LPWSTR)LocalAlloc(LPTR, dirSize * sizeof(WCHAR));
  if (dir == NULL)
  {
    ReportErrorCode(L"LocalAlloc", GetLastError());
    goto ChangeFileModeRecursivelyEnd;
  }

  if (FAILED(StringCchCopyW(dir, dirSize, path)) ||
    FAILED(StringCchCatW(dir, dirSize, L"\\*")))
  {
    goto ChangeFileModeRecursivelyEnd;
  }

  hFind = FindFirstFile(dir, &ffd);
  if (hFind == INVALID_HANDLE_VALUE)
  {
    ReportErrorCode(L"FindFirstFile", GetLastError());
    goto ChangeFileModeRecursivelyEnd;
  }

  do
  {
    LPWSTR filename = NULL;
    LPWSTR longFilename = NULL;
    size_t filenameSize = 0;

    if (wcscmp(ffd.cFileName, L".") == 0 ||
      wcscmp(ffd.cFileName, L"..") == 0)
      continue;

    filenameSize = pathSize + wcslen(ffd.cFileName) + 2;
    filename = (LPWSTR)LocalAlloc(LPTR, filenameSize * sizeof(WCHAR));
    if (filename == NULL)
    {
      ReportErrorCode(L"LocalAlloc", GetLastError());
      goto ChangeFileModeRecursivelyEnd;
    }

    if (FAILED(StringCchCopyW(filename, filenameSize, path)) ||
      FAILED(StringCchCatW(filename, filenameSize, L"\\")) ||
      FAILED(StringCchCatW(filename, filenameSize, ffd.cFileName)))
    {
      LocalFree(filename);
      goto ChangeFileModeRecursivelyEnd;
    }
     
    // The child fileanme is not prepended with long path prefix.
    // Convert the filename to long path format.
    //
    dwRtnCode = ConvertToLongPath(filename, &longFilename);
    LocalFree(filename);
    if (dwRtnCode != ERROR_SUCCESS)
    {
      ReportErrorCode(L"ConvertToLongPath", dwRtnCode);
      LocalFree(longFilename);
      goto ChangeFileModeRecursivelyEnd;
    }

    if(!ChangeFileModeRecursively(longFilename, mode, actions))
    {
      LocalFree(longFilename);
      goto ChangeFileModeRecursivelyEnd;
    }

    LocalFree(longFilename);

  } while (FindNextFileW(hFind, &ffd));

  if (!ChangeFileMode(path, mode, actions))
  {
    goto ChangeFileModeRecursivelyEnd;
  }

  ret = TRUE;

ChangeFileModeRecursivelyEnd:
  LocalFree(dir);

  return ret;
}

//----------------------------------------------------------------------------
// Function: ParseCommandLineArguments
//
// Description:
//  Parse command line arguments for chmod.
//
// Returns:
//  TRUE: on success
//  FALSE: otherwise
//
// Notes:
//	1. Recursive is only set on directories
//  2. 'actions' is NULL if the mode is octal
//
static BOOL ParseCommandLineArguments(
  __in int argc,
  __in_ecount(argc) wchar_t *argv[],
  __out BOOL *rec,
  __out_opt INT *mask,
  __out_opt PMODE_CHANGE_ACTION *actions,
  __out LPCWSTR *path)
{
  LPCWSTR maskString;
  BY_HANDLE_FILE_INFORMATION fileInfo;
  DWORD dwRtnCode = ERROR_SUCCESS;

  assert(path != NULL);

  if (argc != 3 && argc != 4)
    return FALSE;

  *rec = FALSE;
  if (argc == 4)
  {
    maskString = argv[2];
    *path = argv[3];

    if (wcscmp(argv[1], L"-R") == 0)
    {
      // Check if the given path name is a file or directory
      // Only set recursive flag if the given path is a directory
      //
      dwRtnCode = GetFileInformationByName(*path, FALSE, &fileInfo);
      if (dwRtnCode != ERROR_SUCCESS)
      {
        ReportErrorCode(L"GetFileInformationByName", dwRtnCode);
        return FALSE;
      }

      if (IsDirFileInfo(&fileInfo))
      {
        *rec = TRUE;
      }
    }
    else
      return FALSE;
  }
  else
  {
    maskString = argv[1];
    *path = argv[2];
  }

  if (ParseOctalMode(maskString, mask))
  {
    return TRUE;
  }
  else if (ParseMode(maskString, actions))
  {
    return TRUE;
  }

  return FALSE;
}

//----------------------------------------------------------------------------
// Function: FreeActions
//
// Description:
//  Free a linked list of mode change actions given the head node.
//
// Returns:
//  TRUE: on success
//  FALSE: otherwise
//
// Notes:
//  none
//
static BOOL FreeActions(PMODE_CHANGE_ACTION actions)
{
  PMODE_CHANGE_ACTION curr = NULL;
  PMODE_CHANGE_ACTION next = NULL;
  
  // Nothing to free if NULL is passed in
  //
  if (actions == NULL)
  {
    return TRUE;
  }

  curr = actions;
  while (curr != NULL)
  {
    next = curr->next_action;
    LocalFree(curr);
    curr = next;
  }
  actions = NULL;

  return TRUE;
}

//----------------------------------------------------------------------------
// Function: ComputeNewMode
//
// Description:
//  Compute a new mode based on the old mode and a mode change action.
//
// Returns:
//  The newly computed mode
//
// Notes:
//  Apply 'rwx' permission mask or reference permission mode according to the
//  '+', '-', or '=' operator.
//
static INT ComputeNewMode(__in INT oldMode,
  __in USHORT who, __in USHORT op,
  __in USHORT perm, __in USHORT ref)
{
  static const INT readMask  = 0444;
  static const INT writeMask = 0222;
  static const INT exeMask   = 0111;

  INT mask = 0;
  INT mode = 0;

  // Operations are exclusive, and cannot be invalid
  //
  assert(op == CHMOD_OP_EQUAL || op == CHMOD_OP_PLUS || op == CHMOD_OP_MINUS);

  // Nothing needs to be changed if there is not permission or reference
  //
  if(perm == CHMOD_PERM_NA && ref == CHMOD_WHO_NONE)
  {
    return oldMode;
  }

  // We should have only permissions or a reference target, not both.
  //
  assert((perm != CHMOD_PERM_NA && ref == CHMOD_WHO_NONE) ||
    (perm == CHMOD_PERM_NA && ref != CHMOD_WHO_NONE));

  if (perm != CHMOD_PERM_NA)
  {
    if ((perm & CHMOD_PERM_R) == CHMOD_PERM_R)
      mask |= readMask;
    if ((perm & CHMOD_PERM_W) == CHMOD_PERM_W)
      mask |= writeMask;
    if ((perm & CHMOD_PERM_X) == CHMOD_PERM_X)
      mask |= exeMask;
    if (((perm & CHMOD_PERM_LX) == CHMOD_PERM_LX))
    {
      // It applies execute permissions to directories regardless of their
      // current permissions and applies execute permissions to a file which
      // already has at least 1 execute permission bit already set (either user,
      // group or other). It is only really useful when used with '+' and
      // usually in combination with the -R option for giving group or other
      // access to a big directory tree without setting execute permission on
      // normal files (such as text files), which would normally happen if you
      // just used "chmod -R a+rx .", whereas with 'X' you can do
      // "chmod -R a+rX ." instead (Source: Wikipedia)
      //
      if ((oldMode & UX_DIRECTORY) == UX_DIRECTORY || (oldMode & exeMask))
        mask |= exeMask;
    }
  }
  else if (ref != CHMOD_WHO_NONE)
  {
    mask |= oldMode & ref;
    switch(ref)
    {
    case CHMOD_WHO_GROUP:
      mask |= mask >> 3;
      mask |= mask << 3;
      break;
    case CHMOD_WHO_OTHER:
      mask |= mask << 3;
      mask |= mask << 6;
      break;
    case CHMOD_WHO_USER:
      mask |= mask >> 3;
      mask |= mask >> 6;
      break;
    default:
      // Reference modes can only be U/G/O and are exclusive
      assert(FALSE);
    }
  }

  mask &= who;

  if (op == CHMOD_OP_EQUAL)
  {
    mode = (oldMode & (~who)) | mask;
  }
  else if (op == CHMOD_OP_MINUS)
  {
    mode = oldMode & (~mask);
  }
  else if (op == CHMOD_OP_PLUS)
  {
    mode = oldMode | mask;
  }

  return mode;
}

//----------------------------------------------------------------------------
// Function: ConvertActionsToMask
//
// Description:
//  Convert a linked list of mode change actions to the Unix permission mask
//  given the head node.
//
// Returns:
//  TRUE: on success
//  FALSE: otherwise
//
// Notes:
//  none
//
static BOOL ConvertActionsToMask(__in LPCWSTR path,
  __in MODE_CHANGE_ACTION const *actions, __out PINT puMask)
{
  MODE_CHANGE_ACTION const *curr = NULL;

  DWORD dwErrorCode = ERROR_SUCCESS;

  INT mode = 0;

  dwErrorCode = FindFileOwnerAndPermission(path, FALSE, NULL, NULL, &mode);
  if (dwErrorCode != ERROR_SUCCESS)
  {
    ReportErrorCode(L"FindFileOwnerAndPermission", dwErrorCode);
    return FALSE;
  }
  *puMask = mode;

  // Nothing to change if NULL is passed in
  //
  if (actions == NULL)
  {
    return TRUE;
  }

  for (curr = actions; curr != NULL; curr = curr->next_action)
  {
    mode = ComputeNewMode(mode, curr->who, curr->op, curr->perm, curr->ref);
  }

  *puMask = mode;
  return TRUE;
}

//----------------------------------------------------------------------------
// Function: ChangeFileModeByActions
//
// Description:
//  Change a file mode through a list of actions.
//
// Returns:
//  TRUE: on success
//  FALSE: otherwise
//
// Notes:
//  none
//
static BOOL ChangeFileModeByActions(__in LPCWSTR path,
  MODE_CHANGE_ACTION const *actions)
{
  INT mask = 0;

  if (ConvertActionsToMask(path, actions, &mask))
  {
    DWORD dwRtnCode = ChangeFileModeByMask(path, mask);
    if (dwRtnCode != ERROR_SUCCESS)
    {
      ReportErrorCode(L"ChangeFileModeByMask", dwRtnCode);
      return FALSE;
    }
    return TRUE;
  }
  else
    return FALSE;
}

//----------------------------------------------------------------------------
// Function: ParseMode
//
// Description:
//  Convert a mode string into a linked list of actions
//
// Returns:
//  TRUE: on success
//  FALSE: otherwise
//
// Notes:
//  Take a state machine approach to parse the mode. Each mode change action
//  will be a node in the output linked list. The state machine has five state,
//  and each will only transit to the next; the end state can transit back to
//  the first state, and thus form a circle. In each state, if we see a
//  a character not belongs to the state, we will move to next state. WHO, PERM,
//  and REF states are optional; OP and END states are required; and errors
//  will only be reported at the latter two states.
//
static BOOL ParseMode(LPCWSTR modeString, PMODE_CHANGE_ACTION *pActions)
{
  enum __PARSE_MODE_ACTION_STATE
  {
    PARSE_MODE_ACTION_WHO_STATE,
    PARSE_MODE_ACTION_OP_STATE,
    PARSE_MODE_ACTION_PERM_STATE,
    PARSE_MODE_ACTION_REF_STATE,
    PARSE_MODE_ACTION_END_STATE
  } state = PARSE_MODE_ACTION_WHO_STATE;

  MODE_CHANGE_ACTION action = INIT_MODE_CHANGE_ACTION;
  PMODE_CHANGE_ACTION actionsEnd = NULL;
  PMODE_CHANGE_ACTION actionsLast = NULL;
  USHORT lastWho;
  WCHAR c = 0;
  size_t len = 0;
  size_t i = 0;

  assert(modeString != NULL && pActions != NULL);

  if (FAILED(StringCchLengthW(modeString, STRSAFE_MAX_CCH, &len)))
  {
    return FALSE;
  }

  actionsEnd = *pActions;
  while(i <= len)
  {
    c = modeString[i];
    if (state == PARSE_MODE_ACTION_WHO_STATE)
    {
      switch (c)
      {
      case L'a':
        action.who |= CHMOD_WHO_ALL;
        i++;
        break;
      case L'u':
        action.who |= CHMOD_WHO_USER;
        i++;
        break;
      case L'g':
        action.who |= CHMOD_WHO_GROUP;
        i++;
        break;
      case L'o':
        action.who |= CHMOD_WHO_OTHER;
        i++;
        break;
      default:
        state = PARSE_MODE_ACTION_OP_STATE;
      } // WHO switch
    }
    else if (state == PARSE_MODE_ACTION_OP_STATE)
    {
      switch (c)
      {
      case L'+':
        action.op = CHMOD_OP_PLUS;
        break;
      case L'-':
        action.op = CHMOD_OP_MINUS;
        break;
      case L'=':
        action.op = CHMOD_OP_EQUAL;
        break;
      default:
        fwprintf(stderr, L"Invalid mode: '%s'\n", modeString);
        FreeActions(*pActions);
        return FALSE;
      } // OP switch
      i++;
      state = PARSE_MODE_ACTION_PERM_STATE;
    }
    else if (state == PARSE_MODE_ACTION_PERM_STATE)
    {
      switch (c)
      {
      case L'r':
        action.perm |= CHMOD_PERM_R;
        i++;
        break;
      case L'w':
        action.perm |= CHMOD_PERM_W;
        i++;
        break;
      case L'x':
        action.perm |= CHMOD_PERM_X;
        i++;
        break;
      case L'X':
        action.perm |= CHMOD_PERM_LX;
        i++;
        break;
      default:
        state = PARSE_MODE_ACTION_REF_STATE;
      } // PERM switch
    }
    else if (state == PARSE_MODE_ACTION_REF_STATE)
    {
      switch (c)
      {
      case L'u':
        action.ref = CHMOD_WHO_USER;
        i++;
        break;
      case L'g':
        action.ref = CHMOD_WHO_GROUP;
        i++;
        break;
      case L'o':
        action.ref = CHMOD_WHO_OTHER;
        i++;
        break;
      default:
        state = PARSE_MODE_ACTION_END_STATE;
      } // REF switch
    }
    else if (state == PARSE_MODE_ACTION_END_STATE)
    {
      switch (c)
      {
      case L'\0':
        __fallthrough;
      case L',':
        i++;
        __fallthrough;
      case L'+':
        __fallthrough;
      case L'-':
        __fallthrough;
      case L'=':
        state = PARSE_MODE_ACTION_WHO_STATE;

        // Append the current action to the end of the linked list
        //
        assert(actionsEnd == NULL);
        // Allocate memory
        actionsEnd = (PMODE_CHANGE_ACTION) LocalAlloc(LPTR,
          sizeof(MODE_CHANGE_ACTION));
        if (actionsEnd == NULL)
        {
          ReportErrorCode(L"LocalAlloc", GetLastError());
          FreeActions(*pActions);
          return FALSE;
        }
        if (action.who == CHMOD_WHO_NONE) action.who = CHMOD_WHO_ALL;
        // Copy the action to the new node
        *actionsEnd = action;
        // Append to the last node in the linked list
        if (actionsLast != NULL) actionsLast->next_action = actionsEnd;
        // pActions should point to the head of the linked list
        if (*pActions == NULL) *pActions = actionsEnd;
        // Update the two pointers to point to the last node and the tail
        actionsLast = actionsEnd;
        actionsEnd = actionsLast->next_action;

        // Reset action
        //
        lastWho = action.who;
        action = INIT_MODE_CHANGE_ACTION;
        if (c != L',')
        {
          action.who = lastWho;
        }

        break;
      default:
        fwprintf(stderr, L"Invalid mode: '%s'\n", modeString);
        FreeActions(*pActions);
        return FALSE;
      } // END switch
    }
  } // while
  return TRUE;
}

//----------------------------------------------------------------------------
// Function: ParseOctalMode
//
// Description:
//  Convert the 3 or 4 digits Unix mask string into the binary representation
//  of the Unix access mask, i.e. 9 bits each an indicator of the permission
//  of 'rwxrwxrwx', i.e. user's, group's, and owner's read, write, and
//  execute/search permissions.
//
// Returns:
//  TRUE: on success
//  FALSE: otherwise
//
// Notes:
//	none
//
static BOOL ParseOctalMode(LPCWSTR tsMask, INT *uMask)
{
  size_t tsMaskLen = 0;
  DWORD i;
  LONG l;
  WCHAR *end;

  if (uMask == NULL)
    return FALSE;

  if (FAILED(StringCchLengthW(tsMask, STRSAFE_MAX_CCH, &tsMaskLen)))
    return FALSE;

  if (tsMaskLen == 0 || tsMaskLen > 4)
  {
    return FALSE;
  }

  for (i = 0; i < tsMaskLen; i++)
  {
    if (!(tsMask[tsMaskLen - i - 1] >= L'0' &&
      tsMask[tsMaskLen - i - 1] <= L'7'))
      return FALSE;
  }

  errno = 0;
  if (tsMaskLen == 4)
    // Windows does not have any equivalent of setuid/setgid and sticky bit.
    // So the first bit is omitted for the 4 digit octal mode case.
    //
    l = wcstol(tsMask + 1, &end, 8);
  else
    l = wcstol(tsMask, &end, 8);

  if (errno || l > 0x0777 || l < 0 || *end != 0)
  {
    return FALSE;
  }

  *uMask = (INT) l;

  return TRUE;
}

void ChmodUsage(LPCWSTR program)
{
  fwprintf(stdout, L"\
Usage: %s [OPTION] OCTAL-MODE [FILE]\n\
   or: %s [OPTION] MODE [FILE]\n\
Change the mode of the FILE to MODE.\n\
\n\
   -R: change files and directories recursively\n\
\n\
Each MODE is of the form '[ugoa]*([-+=]([rwxX]*|[ugo]))+'.\n",
program, program);
}
