windows-nt/Source/XPSP1/NT/net/sfm/afp/ui/cmdline/parse.c
2020-09-26 16:20:57 +08:00

509 lines
13 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/********************************************************************/
/** Microsoft LAN Manager **/
/** Copyright(c) Microsoft Corp., 1990-1991 **/
/********************************************************************/
//***
//
// Filename: Parse.c
//
// Description:
// This module contains the entry point of DIAL.EXE.
// This module will parse the command line. It will validate the syntax
// and the arguments on the command line. On any error, the exit
// module will be invoked with the appropriate error code.
// If any default values are required, they will be supplied by
// this module.
//
// History:
// September 1, 1990 Narendra Gidwani Created original version
//
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef DBCS
#include <locale.h>
#endif /* DBCS */
#include "cmd.h"
//** Global data structures and variables used. **
//* These variables are pointers to ASCIIZ which will be set to
// point to switch values of the command line by GetSwitchValue.
// These pointers are global within this module.
CHAR * gblEntity = NULL;
CHAR * gblCommand = NULL;
CHAR * gblServer = NULL;
CHAR * gblName = NULL;
CHAR * gblPath = NULL;
CHAR * gblPassword = NULL;
CHAR * gblReadOnly = NULL;
CHAR * gblMaxUses = NULL;
CHAR * gblOwnerName = NULL;
CHAR * gblGroupName = NULL;
CHAR * gblPermissions = NULL;
CHAR * gblLoginMessage = NULL;
CHAR * gblMaxSessions = NULL;
CHAR * gblGuestsAllowed = NULL;
CHAR * gblMacServerName = NULL;
CHAR * gblUAMRequired = NULL;
CHAR * gblAllowSavedPasswords = NULL;
CHAR * gblType = NULL;
CHAR * gblCreator = NULL;
CHAR * gblDataFork = NULL;
CHAR * gblResourceFork = NULL;
CHAR * gblTargetFile = NULL;
CHAR * gblHelp = NULL;
// Non translatable text
//
CHAR * pszVolume = "Volume";
CHAR * pszAdd = "/Add";
CHAR * pszDelete = "/Remove";
CHAR * pszSet = "/Set";
CHAR * pszDirectory = "Directory";
CHAR * pszServer = "Server";
CHAR * pszForkize = "Forkize";
CMD_FMT DelVolArgFmt[] = {
{ "/Server", (CHAR *)&gblServer, 0},
{ "/Name", (CHAR *)&gblName, 0},
{ "/Help", (CHAR *)&gblHelp, 0},
{ "/?", (CHAR *)&gblHelp, 0},
{ NULL, (CHAR *)NULL, 0}
};
CMD_FMT AddVolArgFmt[] = {
{ "/Server", (CHAR *)&gblServer, 0},
{ "/Name", (CHAR *)&gblName, 0},
{ "/Path", (CHAR *)&gblPath, 0},
{ "/Password", (CHAR *)&gblPassword, 0},
{ "/ReadOnly", (CHAR *)&gblReadOnly, 0},
{ "/GuestsAllowed", (CHAR *)&gblGuestsAllowed, 0},
{ "/MaxUsers", (CHAR *)&gblMaxUses, 0},
{ "/Help", (CHAR *)&gblHelp, 0},
{ "/?", (CHAR *)&gblHelp, 0},
{ NULL, (CHAR *)NULL, 0}
};
CMD_FMT SetVolArgFmt[] = {
{ "/Server", (CHAR *)&gblServer, 0},
{ "/Name", (CHAR *)&gblName, 0},
{ "/Password", (CHAR *)&gblPassword, 0},
{ "/ReadOnly", (CHAR *)&gblReadOnly, 0},
{ "/GuestsAllowed", (CHAR *)&gblGuestsAllowed, 0},
{ "/MaxUsers", (CHAR *)&gblMaxUses, 0},
{ "/Help", (CHAR *)&gblHelp, 0},
{ "/?", (CHAR *)&gblHelp, 0},
{ NULL, (CHAR *)NULL, 0}
};
CMD_FMT DirArgFmt[] = {
{ "/Server", (CHAR *)&gblServer, 0},
{ "/Path", (CHAR *)&gblPath, 0},
{ "/Owner", (CHAR *)&gblOwnerName, 0},
{ "/Group", (CHAR *)&gblGroupName, 0},
{ "/Permissions", (CHAR *)&gblPermissions, 0},
{ "/Help", (CHAR *)&gblHelp, 0},
{ "/?", (CHAR *)&gblHelp, 0},
{ NULL, (CHAR *)NULL, 0}
};
CMD_FMT ServerArgFmt[] = {
{ "/Server", (CHAR *)&gblServer, 0},
{ "/MaxSessions", (CHAR *)&gblMaxSessions, 0},
{ "/LoginMessage", (CHAR *)&gblLoginMessage, 0},
{ "/GuestsAllowed", (CHAR *)&gblGuestsAllowed, 0},
{ "/UAMRequired", (CHAR *)&gblUAMRequired, 0},
{ "/AllowSavedPasswords",(CHAR *)&gblAllowSavedPasswords,0},
{ "/MacServerName", (CHAR *)&gblMacServerName, 0},
{ "/Help", (CHAR *)&gblHelp, 0},
{ "/?", (CHAR *)&gblHelp, 0},
{ NULL, (CHAR *)NULL, 0}
};
CMD_FMT ForkizeArgFmt[] = {
{ "/Server", (CHAR *)&gblServer, 0},
{ "/Type", (CHAR *)&gblType, 0},
{ "/Creator", (CHAR *)&gblCreator, 0},
{ "/DataFork", (CHAR *)&gblDataFork, 0},
{ "/ResourceFork", (CHAR *)&gblResourceFork, 0},
{ "/TargetFile", (CHAR *)&gblTargetFile, 0},
{ "/Help", (CHAR *)&gblHelp, 0},
{ "/?", (CHAR *)&gblHelp, 0},
{ NULL, (CHAR *)NULL, 0}
};
//**
//
// Call: main
//
// Entry: int argc; - Number of command line arguments
// char *argv[]; - Array of pointers to ASCIIZ command line
// arguments.
//
// Exit: none.
//
// Returns: none.
//
// Description: Calls the command line parser with the command line
// arguments.
//
VOID _cdecl
main( INT argc, CHAR * argv[] )
{
#ifdef DBCS
setlocale( LC_ALL, "" );
#endif /* DBCS */
// This will act like xacc or yacc. It will parse the command line
// and call the appropriate function to carry out an action.
// Thus this procedure will never return.
ParseCmdArgList( argc, argv );
}
//**
//
// Call: ParseCmdArgList
//
// Entry: int argc; - Number of command line arguments.
// char *argv[]; - Array of pointers to ASCIIZ command line
// arguments.
//
// Exit: none.
//
// Returns: none.
//
// Description:
// Will parse command line for any errors and determine
// from the syntax what the user wishes to do. Command
// line arguments will be validated.
//
VOID
ParseCmdArgList(
INT argc,
CHAR * argv[]
)
{
DWORD ArgCount = 0;
if ( argc == 1 )
PrintMessageAndExit( IDS_GENERAL_SYNTAX, NULL );
//
// What is the entity being operated on ?
//
gblEntity = argv[++ArgCount];
if ( _strnicmp( pszVolume, gblEntity, strlen( gblEntity ) ) == 0 )
{
if ( argc == 2 )
PrintMessageAndExit( IDS_VOLUME_SYNTAX, NULL );
gblCommand = argv[++ArgCount];
if ( _strnicmp( pszAdd, gblCommand, strlen( gblCommand ) ) == 0 )
{
GetArguments( AddVolArgFmt, argv, argc, ArgCount );
if ( gblHelp != (CHAR*)NULL )
PrintMessageAndExit( IDS_VOLUME_SYNTAX, NULL );
DoVolumeAdd( gblServer, gblName, gblPath, gblPassword, gblReadOnly,
gblGuestsAllowed, gblMaxUses );
}
else if ( _strnicmp( pszDelete, gblCommand, strlen( gblCommand ) ) == 0 )
{
GetArguments( DelVolArgFmt, argv, argc, ArgCount );
if ( gblHelp != (CHAR*)NULL )
PrintMessageAndExit( IDS_VOLUME_SYNTAX, NULL );
DoVolumeDelete( gblServer, gblName );
}
else if ( _strnicmp( pszSet, gblCommand, strlen( gblCommand ) ) == 0 )
{
GetArguments( SetVolArgFmt, argv, argc, ArgCount );
if ( gblHelp != (CHAR*)NULL )
PrintMessageAndExit( IDS_VOLUME_SYNTAX, NULL );
DoVolumeSet( gblServer, gblName, gblPassword, gblReadOnly,
gblGuestsAllowed, gblMaxUses );
}
else
PrintMessageAndExit( IDS_VOLUME_SYNTAX, NULL );
}
else if ( _strnicmp( pszDirectory, gblEntity, strlen( gblEntity ) ) == 0 )
{
if ( argc == 2 )
PrintMessageAndExit( IDS_DIRECTORY_SYNTAX, NULL );
GetArguments( DirArgFmt, argv, argc, ArgCount );
if ( gblHelp != (CHAR*)NULL )
PrintMessageAndExit( IDS_DIRECTORY_SYNTAX, NULL );
DoDirectorySetInfo( gblServer, gblPath, gblOwnerName, gblGroupName,
gblPermissions );
}
else if ( _strnicmp( pszServer, gblEntity, strlen( gblEntity ) ) == 0 )
{
if ( argc == 2 )
PrintMessageAndExit( IDS_SERVER_SYNTAX, NULL );
GetArguments( ServerArgFmt, argv, argc, ArgCount );
if ( gblHelp != (CHAR*)NULL )
PrintMessageAndExit( IDS_SERVER_SYNTAX, NULL );
DoServerSetInfo( gblServer, gblMaxSessions, gblLoginMessage,
gblGuestsAllowed, gblUAMRequired,
gblAllowSavedPasswords, gblMacServerName );
}
else if ( _strnicmp( pszForkize, gblEntity, strlen( gblEntity ) ) == 0 )
{
GetArguments( ForkizeArgFmt, argv, argc, ArgCount );
if ( gblHelp != (CHAR*)NULL )
PrintMessageAndExit( IDS_FORKIZE_SYNTAX, NULL );
DoForkize( gblServer, gblType, gblCreator, gblDataFork,
gblResourceFork, gblTargetFile );
}
else
PrintMessageAndExit( IDS_GENERAL_SYNTAX, NULL );
}
VOID
GetArguments(
CMD_FMT * pArgFmt,
CHAR * argv[],
DWORD argc,
DWORD ArgCount
)
{
//
// To determine by the syntax what the user wishes to do we first
// run through the arguments and get switch values.
//
while ( ++ArgCount < argc )
{
//
// If it is a switch, get its value.
//
if ( argv[ArgCount][0] == '/' )
GetSwitchValue( pArgFmt, argv[ArgCount] );
else
PrintMessageAndExit( IDS_GENERAL_SYNTAX, NULL );
}
}
//**
//
// Call: GetSwitchValue
//
// Entry: CHAR * SwitchPtr; - Pointer to ASCIIZ containing a command
// line argument.
// ex. - /phoneb:c:\subdir
//
// CHAR ** LastArg; - Nothing.
//
// Exit: CHAR * SwitchPtr; - same as entry.
//
// CHAR ** LastArg; - Pointer to a pointer to ASCIIZ containig
// the text of the first bad switch if
// there were any.
//
// Returns: 0 - Success.
// AMBIGIOUS_SWITCH_ERRROR - failure.
// UNKNOWN_SWITCH_ERROR - failure.
// MEM_ALLOC_ERROR - failure.
// MULTIPLE_SWITCH_ERROR - failure.
//
// Description: This procedure will run through all the valid switches
// in the cmdfmt structure and retrieve the value of the
// the switch. The value of the switch will be inserted into the
// cmdfmt structure. It will expand abbreviated switches. If
// the switch had no value, it will insert a null character
// as the value. If the switch did not appear, the value
// pointer of the switch (in the cmdfmt structure)
// will remain unchanged ( should be initialized to NULL ).
// This procedure uses the same data structure as GetCmdArgs5,
// hence some fields may be ignored. This is done to make the
// functionality of this procedure extendable.
//
//
VOID
GetSwitchValue(
CMD_FMT * pArgFmt,
IN CHAR * pchSwitchPtr
)
{
INT intFound = -1;
DWORD dwIndex;
DWORD dwSwitchLen;
CHAR * pchSeparatorPtr;
//
// Get length of the switch part of the argument.
//
if ( ( pchSeparatorPtr = strchr( pchSwitchPtr, ':' )) != NULL )
dwSwitchLen = (DWORD)(pchSeparatorPtr - pchSwitchPtr);
else
//
// If the switch had no value.
//
dwSwitchLen = strlen( pchSwitchPtr );
//
// Run through all switches.
//
for ( dwIndex = 0; pArgFmt[dwIndex].cf_parmstr != NULL; dwIndex++ )
{
//
// If this switch matches (partly or completely) one of the
// valid switches.
//
if ( !_strnicmp( pArgFmt[dwIndex].cf_parmstr,
pchSwitchPtr,
dwSwitchLen ) )
{
if ( intFound < 0 )
intFound = dwIndex;
else
{
//
// If this argument has matched another switch also.
//
if ( pchSeparatorPtr )
*pchSeparatorPtr = '\0';
PrintMessageAndExit( IDS_AMBIGIOUS_SWITCH_ERROR, pchSwitchPtr );
}
}
}
//
// If we could not find a match for this switch.
//
if ( intFound < 0 )
{
if ( pchSeparatorPtr )
*pchSeparatorPtr = '\0';
PrintMessageAndExit( IDS_UNKNOWN_SWITCH_ERROR, pchSwitchPtr );
}
//
// If this switch is appearing for the second time.
//
if ( pArgFmt[intFound].cf_usecount > 0 )
{
if ( pchSeparatorPtr )
*pchSeparatorPtr = '\0';
PrintMessageAndExit( IDS_DUPLICATE_SWITCH_ERROR, pchSwitchPtr );
}
else
pArgFmt[intFound].cf_usecount++;
//
// Get the switch value if there is one.
//
if ( ( pchSeparatorPtr ) && ((CHAR *)(pchSeparatorPtr + 1)) )
{
*(CHAR **)pArgFmt[intFound].cf_ptr = ++pchSeparatorPtr;
}
else
{
*(CHAR **)pArgFmt[intFound].cf_ptr = (CHAR *)"";
}
}
/*******************************************************************
NAME: IsDriveGreaterThan2Gig
SYNOPSIS: Determines if the disk is bigger than 2Gig. If it, return
TRUE so that a warning can be displayed to the user
RETURNS: TRUE if disk is larger than 2Gig
FALSE otherwise
HISTORY:
NarenG 11/18/92 Modified for AFPMGR
********************************************************************/
BOOL IsDriveGreaterThan2Gig( LPSTR lpDrivePath )
{
DWORD SectorsPerCluster;
DWORD BytesPerSector;
DWORD NumberOfFreeClusters;
DWORD TotalNumberOfClusters;
DWORDLONG DriveSize;
DWORDLONG TwoGig = MAXLONG;
//
// If this drive volume is greater than 2G then we print warning
//
if ( !GetDiskFreeSpace( lpDrivePath,
&SectorsPerCluster,
&BytesPerSector,
&NumberOfFreeClusters,
&TotalNumberOfClusters
))
{
// some error: can't do much, so just assume this drive is smaller than 2GB. That's
// probably better than alarming the customer by putting the warning?
return FALSE;
}
DriveSize = UInt32x32To64( SectorsPerCluster * BytesPerSector,
TotalNumberOfClusters ) ;
if ( DriveSize > TwoGig )
{
return TRUE;
}
else
{
return FALSE;
}
}