TestLib.c

/*------------------------------------------------------------------------------
#
#   TestLib.c : MPW tool to test  3 librairies : ZIP - ATP - AFP
#
#   Zone names are displayed
#   Enter a zone name if any and validate your answer by the Enter key
#   Server names are displayed
#   Enter a server name and validate your answer by the Enter key
#   Logging as guest or with username/password is completed
#   Server time as well as volume names are displayed
#   Enter a volume name and validate your answer by the Enter key
#   Volume access rights are displayed in guest mode
#   For each directory accessible, access rights are displayed
#
#   Versions:   1.0                 10/91
#   Built with MPW 3.2
#
#   C.Buttin - Apple Computer Europe            
#
------------------------------------------------------------------------------*/
 
#include <Memory.h>
#include <Types.h>
#include <stdIO.h>
#include <String.h>
#include <Strings.h>
#include <errors.h>
#include <OSUtils.h>
#include <AppleTalk.h>
 
#define buffSize    5000
#define maxServers  40
 
/* structures  used by ExtractDirInfo */
typedef struct InfoDir {
    short   UAM;                /* access right for this directory */
    long    dirID;              
    Str32   dirName;
}InfoDir;
 
typedef InfoDir *InfoDirPtr;
 
 
/* functions */
short   DisplayZones(Ptr buffer);
short   DisplayServers(Ptr zoneName,Ptr buffer);
Boolean GetServerAddress(Ptr theServer,AddrBlock* serverAddress,short numEntities,Ptr buffer);
short   LogOnServer(AddrBlock* serverAddress,Ptr SCBBlock,Ptr buffer);
void    DisplayVolumes(Ptr buffer,short numVol);
void    DisplayDirectories(short sessionNum,short volumeID,long dirID);
void    getAnswer(Ptr theString);
void    DisplayAccessRights(short accessRights);
void    padWithBlanks(Str32 theStr);
 
/* ZIP */
extern pascal short      GetZones(Ptr buffer,short bufsize);
extern pascal void       GetZoneName(char* buffer,short zoneNumber,char* zoneName);
/* NBP */
extern pascal short      NBPGetList(Ptr buffer,
                               short bufSize,
                               EntityPtr entity,
                               short maxEntities);
extern pascal Boolean    NBPGetAddress(Ptr buffer,
                                  short tuplenum,
                                  short numEntities,
                                  EntityPtr entity,
                                  AddrBlock *address);
/* AFP */
extern pascal OSErr     GetServerInfo(AddrBlock *serverAddress,Ptr replyBuffer,short buffLength);
extern pascal short     LogOnwithName(AddrBlock *serverAddress,Ptr theName,Ptr thePassword,Ptr SCBBlock);
extern pascal short     LogOnAsGuest(AddrBlock *serverAddress,Ptr SCBBlock);
extern pascal OSErr     GetServerParams(short sessNum,Ptr replyBuffer,short buffLength);
extern pascal unsigned long GetServerTime(Ptr replyBuffer);
extern pascal short     GetNumberVolumes(Ptr replyBuffer);
extern pascal Boolean   ExtractVolumeName(Ptr replyBuffer,short volumeNumber,Str255 theVol);
extern pascal short     OpenVolume(short sessNum,Ptr volumeName,short* volID);
extern pascal void      CloseVolume(short sessNum,short volumeID);
extern pascal short     GetVolumePrivileges(short sessionNum,short volumeID);
extern pascal OSErr     GetDirectories(short sessNum,short volID,long dirID,
                                   Ptr buffer,short buffLength,short reqCount);
extern pascal short     GetNumberDirs(Ptr replyBuffer);
extern pascal Boolean   ExtractDirInfo(Ptr replyBuffer,short dirNumber,InfoDirPtr theDir);
extern pascal OSErr     LogOut(short sessNum,Ptr SCBBlock);
extern pascal Boolean   CheckUAM(const Str32 theMethod,Ptr replyBuffer);
 
 
main()
{
    short       sessionNum,numVol,numEntities;
    short       volumeID,result;
    Ptr         buffer;
    Str32       zoneName,theServer,theVol;
    AddrBlock   serverAddress;
    char        SCBBlock[scbMemSize];   /* used by AFP to manage a session */
    OSErr       error;
    short       accessRights;
    DateTimeRec theDate;
    
    /* allocate a buffer to retrieve info */
    if (!(buffer = NewPtr(buffSize))) {
        printf("buffer too small");
        return;
        }
    /* Display list of zones */
    if ((result = DisplayZones(buffer)) < 0)  { /* an error occured */
        DisposePtr(buffer);
        return;
        }
    else 
        if (result >0) {
            /* get selected zone */
            printf("\n\nselect a zone : \n");
            getAnswer(zoneName);
            if (*zoneName == 0)                 /* no zone selected */
                return;
            }
        else                                    /* no zone available */
            sprintf(zoneName,"\p*");
        
    /* get AppleShare servers in that zone */
    if ((numEntities = DisplayServers(c2pstr(zoneName), buffer)) == 0)  { /* an error occured */
        DisposePtr(buffer);
        return;
        }
        
    /* Get selected server and look for its address */
    printf("\nGive the server name :\n");
    getAnswer(theServer);
    if (!GetServerAddress(theServer,&serverAddress,numEntities,buffer)) {   /* an error occured */
        DisposePtr(buffer);
        return;
        }
        
    /* Connect to server */
    if ((sessionNum = LogOnServer(&serverAddress,&SCBBlock,buffer)) <= 0)   {       /* an error occured */
        DisposePtr(buffer);
        return;
        }
        
    /* get server information and volume list */
    if ((error = GetServerParams(sessionNum,buffer,buffSize)) != noErr)
            printf("Error in getting server params : %d\n",error);
    else {
        Secs2Date(GetServerTime(buffer),&theDate);
        printf("Server Time : %d/%d/%d \t%d:%d:%d\n", theDate.day,theDate.month,theDate.year,
                theDate.hour,theDate.minute,theDate.second);
                
        numVol = GetNumberVolumes(buffer);
        if (numVol > 0) {
            DisplayVolumes(buffer,numVol);
            /* Get a volume name and open it */
            printf("\nGive the volume name :\n");
            getAnswer(theVol);
            if (*theVol == 0)                   /* no volume selected */
                return;
            if ((error = OpenVolume(sessionNum,c2pstr(theVol),&volumeID)) == noErr) {
                    accessRights = GetVolumePrivileges(sessionNum,volumeID);
                    printf("\nVolume : %s ",p2cstr(theVol));
                    DisplayAccessRights(accessRights);
                    DisplayDirectories(sessionNum,volumeID,2);      /* dirID of the root is 2 */
                CloseVolume(sessionNum,volumeID);
                }
            else
                printf("Can't open volume:%d",error);
            }
        }
    
    LogOut(sessionNum,&SCBBlock);
    DisposePtr(buffer);
}
 
/* DisplayZones : display all the zone names.
   return : -1 an error occured
             0 no zone available
             1 list of zones */
             
short DisplayZones(Ptr buffer)
{
    short       i,numZones;
    Str32       zoneName;
    
    /* get zone list */
    if ((numZones = GetZones(buffer,buffSize)) < 0) {
        printf("Error in getting zones : %d\n",numZones);
        return -1;
        }
    else    {
        if (numZones == 0) {
            printf("\nNo Zone available");
            return 0;
            }
        else    {
            for (i = 1; i <= numZones;i++) {
                GetZoneName(buffer,i,zoneName);
                padWithBlanks(p2cstr(zoneName));            
                printf("\t\t%s",zoneName);
                if (i % 3 == 0)
                    printf("\n");
                }
            return 1;
            }
        }
} /* DisplayZones */
 
short DisplayServers(Ptr zoneName,Ptr buffer)
{
    short       i,numEntities;
    AddrBlock   serverAddress;
    EntityName  entity;
 
 
    /* prepare the entities we are looking for */
    NBPSetEntity((Ptr)&entity,"\p=","\pAFPServer",zoneName);
    if ((numEntities = NBPGetList(buffer,buffSize,&entity,maxServers)) <= 0)    {
        printf("Error in getting entities :%d",numEntities);
        return 0;
        }
    
    /* list AppleShare servers */
    printf("\n");
    for (i = 1; i <= numEntities ; i++) 
        if (NBPGetAddress(buffer,i,numEntities,&entity,&serverAddress)) {
            /* pad server name with blanks to display nicely */
            padWithBlanks(p2cstr(entity.objStr));
            printf("Server :\t%s\t\tZone : \t%s\n",entity.objStr,
                    p2cstr(entity.zoneStr));
                }
    return numEntities;
}   /* DisplayServers */
 
Boolean GetServerAddress(Ptr theServer,AddrBlock* serverAddress,short numEntities,Ptr buffer)
{
    short       i;
    EntityName  entity;
 
    for (i = 1; i <= numEntities ; i++) {
        NBPGetAddress(buffer,i,numEntities,&entity,serverAddress);
        if (strcmp(p2cstr(entity.objStr),theServer) == 0)
            break;
        }
    if (i > numEntities) {
        printf("Server not found\n");
        return false;
        }
    printf("Address : \tNet : %ld\tNode : %d\tSocket : %d\n",serverAddress->aNet,
            serverAddress->aNode,
            serverAddress->aSocket);
    return true;
}   /* GetServerAddress */  
 
/* establish a connection to the server */
short LogOnServer(AddrBlock* serverAddress,Ptr SCBBlock,Ptr buffer)
{
    short   sessionNum;
    OSErr   error;
    Str32   theName,temp;
    char    thePassword[8];
    Boolean connectAsGuest;
    
    connectAsGuest = true;  
    /* look to connect with a username password by checking the UAMs */
    if ((error = GetServerInfo(serverAddress,buffer,buffSize)) != noErr)    {
        printf("Error in getting server Information : %d\n",error);
        return 0;
        }
    
    /* verify access methods */
    connectAsGuest = true;
    if (CheckUAM("\pCleartxt passwrd",buffer))  {
        /* ask user if he wants to connect with user name password */
        printf("Do you want to connect to the server as guest : 1 yes, 0 no ?\n");
        getAnswer(temp);
        if (strcmp(temp,"0") == 0)  {
        connectAsGuest = false;
        /* get username and password and log on */
            printf("UserName :\n");
            getAnswer(theName);
            printf("Password :\n");
            getAnswer(thePassword);
            sessionNum = LogOnwithName(serverAddress,c2pstr(theName),c2pstr(thePassword),SCBBlock);
            if (sessionNum > 0)
                printf("\n%s : Logging on server completed\n",p2cstr(theName));
            }
        }
    if (connectAsGuest) {
        /* connect to server as guest, if possible */
        if (CheckUAM("\pNo User Authent",buffer))   {
            sessionNum = LogOnAsGuest(serverAddress,SCBBlock);
            if (sessionNum > 0)
                printf("\nLogging on server as guest completed\n");
            }
        else    {
            printf("\nLogging on server as guest impossible\n");
            sessionNum = 0;
            }
        }
 
    if (sessionNum < 0)
        printf("Error in loging to server : %d\n",sessionNum);
 
    return sessionNum;
} /* LogOnServer */
 
 
void DisplayVolumes(Ptr buffer,short numVol)
{
    short       i;
    Str32       theVol;
    
    printf("\nNumber of volumes : %d\n",numVol);
    printf("Volumes :\n");
    for (i = 1; i <= numVol;i++)
        if (ExtractVolumeName(buffer,i,theVol))
            printf("\t%s\n",p2cstr(theVol));
}   /* DisplayVolumes */
    
 
void DisplayDirectories(short sessionNum,short volumeID,long dirID)
{
    OSErr       error;
    short       i,j,numDir;
    InfoDir     theDir;
    static short theTab = -1;
    Ptr         buffer;
    
    /* allocate a buffer to receive the information */
    if (!(buffer = NewPtr(buffSize))) {
        printf("DisplayDirectories buffer too small\n");
        return;
        }
    /* retrieve directory info */
    if ((error = GetDirectories(sessionNum,volumeID,dirID,buffer,buffSize,20)) != noErr)    
        if (error == afpObjectNotFound) {   /* we have browse a whole branch */
            DisposPtr(buffer);
            return;
            }
                
    /* get number of directories */
    if ((numDir = GetNumberDirs(buffer)) <= 0)
        return;
    
    if (theTab < 0) {
        printf("\nDirectories and access rights :\n");
        theTab = 0;
        }
        
    /* retrieve info about each directory, display it and go on recursively if we have access
       rights */
     for (i = 1; i <= numDir;i++)   {
        /* extract info and print it */
        if (ExtractDirInfo(buffer,i,&theDir)) {
            for (j = 0; j < theTab;j++)
                printf("\t");
            /* pad with Blanks to get a nice display */
            padWithBlanks(p2cstr(theDir.dirName));
            printf("%s  ",theDir.dirName);
            DisplayAccessRights(theDir.UAM);
 
            /* look for subdirectories if possible */
            if (theDir.UAM & 0xF1)      {
                theTab++;
                DisplayDirectories(sessionNum,volumeID,theDir.dirID);
                theTab--;
                }
            }
        }       
    DisposPtr(buffer);
}   /* DisplayDirectories */
 
/* get from user a C string */
void getAnswer(Ptr theString)
{
    short i;
    
    i = 0;
    do  {
        scanf("%c",theString+i);    /* a zone name can contains white spaces */
        i++;                        /* so we get it char by char */
        }
    while (*(theString+i-1) != '\n');
    *(theString+i-1) = '\0';
}   /* getAnswer */
 
void    DisplayAccessRights(short accessRights)
{
    Str255      theStr;
 
    *theStr = 0;
    if (accessRights == 0)      /* no access to guest */
        printf("No access for guest\n");
    else {
        if (accessRights & 0xF4)
            strcat(theStr,"Make Changes ");
        if (accessRights & 0xF2)
            strcat(theStr,"See Files ");
        if (accessRights & 0xF1)
            strcat(theStr,"See Folders");
        
        printf("%s\n",theStr);
        }
 
}   /* DisplayAccessRights */
 
/* pad text with blanks to display nicely */
void padWithBlanks(Str32 theStr)
{
    short i;
    
    for (i = strlen(theStr); i < 31;theStr[i] = ' ',i++);
    theStr[31] = '\0';
} /* padWithBlanks */