|
|
/********************************************************************/ /** 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}, { "/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}, { "/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}, { "/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; } }
|