509 lines
13 KiB
C
509 lines
13 KiB
C
/********************************************************************/
|
||
/** 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;
|
||
}
|
||
}
|