/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* |_o_o|\\ Copyright (c) 1987, 1988 The Software Distillery. All Rights */ /* |. o.| || Reserved. This program may not be distributed without the */ /* | . | || permission of the authors: BBS: */ /* | o | || John Toebes Doug Walker Dave Baker */ /* | . |// */ /* ====== */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Directory Manipulation */ /* ActCreateDir ActExamine ActExNext ActParent */ #include "handler.h" void ActCreateDir(global,pkt) GLOBAL global; struct DosPacket *pkt; /* a pointer to the dos packet sent */ /* Arg1 - Lock */ /* Arg2 - name */ /* Arg3 (optional) Attributes */ { struct FileLock *flock; NETPTR nlock; BUG(("ActCreateDir\n")); if((!(flock=(struct FileLock *)pkt->dp_Arg1) || !(nlock=(NETPTR)flock->fl_Key)->RDevice)) { /* The idiot is trying to create a directory in NET: */ BUG(("ActCreateDir: Can't create dir in NET:, giving up\n")) pkt->dp_Res1 = NULL; pkt->dp_Res2 = ERROR_WRITE_PROTECTED; return; } global->RP.Type = pkt->dp_Type; global->RP.Arg1 = (LONG)nlock->RPtr; MBSTR(pkt->dp_Arg2, global->RP.Data); global->RP.Arg3 = pkt->dp_Arg3; global->RP.DLen = BSTRLEN(global->RP.Data)+1; if(global->RP.DLen == 1) global->RP.DLen = 0; if(!RemotePacket(global, nlock) && pkt->dp_Res1) { pkt->dp_Res1 = MKBADDR(CreateLock(global, nlock, (RPTR)pkt->dp_Res1, ACCESS_READ)); } } /*-------------------------------------------------------------------------*/ /* Structure of the FileInfoBlock */ /* struct FileInfoBlock { */ /* LONG fib_DiskKey; Location on disk of entry */ /* LONG fib_DirEntryType; <0 plain file, >0 a directory */ /* char fib_FileName[108]; Null terminated name of file */ /* LONG fib_Protection; Protection bits for the file */ /* LONG fib_EntryType; Internal for Dos use */ /* LONG fib_Size; Length of file in bytes */ /* LONG fib_NumBlocks; Length of file in blocks */ /* struct DateStamp fib_Date; File creation date */ /* char fib_Comment[116]; Comment associated with file */ /* }; */ /*-------------------------------------------------------------------------*/ static void PNum U_ARGS((char *, int)); #define UPSPOT 17 #define TOTSPOT 24 static char status[] = "\53Network status: xxx of xxx nodes responding"; static void PNum(string, num) char *string; int num; { static char *digits = " 123456789"; /* Format a number into 3 character positions of a string */ /* Number must be between 1 and 999 inclusive */ num %= 1000; string[0] = digits[num/100]; num %= 100; string[1] = digits[num/10]; num %= 10; string[2] = (num ? digits[num] : '0'); } void ExDotInfo U_ARGS((GLOBAL, struct FileInfoBlock *)); void ExDotInfo(global, info) GLOBAL global; struct FileInfoBlock *info; { BUGBSTR("ExDotInfo for ", info->fib_FileName); strcpy(info->fib_FileName+(info->fib_FileName[0]+1), ".info"); info->fib_FileName[0] += 5; info->fib_EntryType = info->fib_DirEntryType = -3; info->fib_Protection = 0L; info->fib_Size = 974; info->fib_NumBlocks = 2; info->fib_Comment[0] = '\0'; global->pkt->dp_Res1 = DOS_TRUE; } static void ExRoot U_ARGS((GLOBAL, struct FileInfoBlock *)); static void ExRoot(global, info) GLOBAL global; struct FileInfoBlock *info; { BUG(("ExRoot\n")) /* Examine on the root of NET: */ info->fib_DiskKey = (LONG)&global->netchain; info->fib_DirEntryType = info->fib_EntryType = 2; MBSTR(global->netchain.name, info->fib_FileName); info->fib_Protection = 0; info->fib_NumBlocks = global->numnodes; info->fib_Size = 0; info->fib_Date.ds_Days = 3000; /* Pick a number */ info->fib_Date.ds_Minute = info->fib_Date.ds_Tick = 0L; strcpy(info->fib_Comment, status); PNum(info->fib_Comment+UPSPOT, global->upnodes); PNum(info->fib_Comment+TOTSPOT, global->numnodes); global->pkt->dp_Res1 = DOS_TRUE; } static void ExRootNext U_ARGS((GLOBAL, struct FileInfoBlock *)); static void ExRootNext(global, info) GLOBAL global; struct FileInfoBlock *info; { struct NetNode *node; /* Examine next in the root of NET: */ BUG(("ExRootNext\n")) node = (struct NetNode *)info->fib_DiskKey; /* If the node name is the same length as the filename, we haven't */ /* returned the exnext of the .info file yet; do so */ if(node != &global->netchain && info->fib_FileName[0] > 0 && node->name[0] == info->fib_FileName[0]) { ExDotInfo(global, info); return; } #if 0 for(node=node->next; node && node->status != NODE_UP; node=node->next); #else node = node->next; #endif if(!node) { global->pkt->dp_Res1 = DOS_FALSE; global->pkt->dp_Res2 = ERROR_NO_MORE_ENTRIES; BUG(("Returning ERROR_NO_MORE_ENTRIES\n")); return; } info->fib_DiskKey = (LONG)node; info->fib_DirEntryType = info->fib_EntryType = 2; MBSTR(node->name, info->fib_FileName); BUGBSTR("ExNext: Filename is ", info->fib_FileName); info->fib_Protection = 0L; info->fib_NumBlocks = 1; info->fib_Size = 0; info->fib_Date.ds_Days = 3000; info->fib_Date.ds_Minute = info->fib_Date.ds_Tick = 0L; info->fib_Comment[0] = '\0'; global->pkt->dp_Res1 = DOS_TRUE; } void ActExamine(global, pkt) GLOBAL global; struct DosPacket *pkt; /* a pointer to the dos packet sent */ /* Arg1: Lock of object to examine */ /* Arg2: FileInfoBlock to fill in */ { NETPTR nlock; struct FileLock *flock; struct FileInfoBlock *info; BUG(("ActExamine/ActExNext\n")); info = (struct FileInfoBlock *)pkt->dp_Arg2; if((!(flock=(struct FileLock *)pkt->dp_Arg1) || !(nlock=(NETPTR)flock->fl_Key)->RDevice)) { if(pkt->dp_Type == ACTION_EXAMINE_OBJECT) ExRoot(global, info); else ExRootNext(global, info); return; } BUG(("ActEx: Lock %lx on node %s\n",nlock->RPtr,nlock->NetNode->name+1)); global->RP.Type = pkt->dp_Type; global->RP.Arg1 = (LONG)nlock->RPtr; MQ(info, global->RP.Data, sizeof(struct FileInfoBlock)); BUGBSTR("ActEx: filename ", info->fib_FileName); global->RP.DLen = sizeof(struct FileInfoBlock); if(!RemotePacket(global, nlock)) { MQ(global->RP.Data, info, sizeof(struct FileInfoBlock)); BUGBSTR("ActEx: Returned filename ", info->fib_FileName); } } void ActParent(global,pkt) GLOBAL global; struct DosPacket *pkt; /* a pointer to the dos packet sent */ /* Arg1 - Lock */ { struct FileLock *flock; NETPTR nlock; BUG(("ActParent\n")); /* If this is the root of NET:, return NULL */ if((!(flock=(struct FileLock *)pkt->dp_Arg1) || !(nlock=(NETPTR)flock->fl_Key)->RDevice)) { pkt->dp_Res1 = NULL; return; } global->RP.Type = pkt->dp_Type; global->RP.Arg1 = (LONG)nlock->RPtr; global->RP.DLen = 0; if(RemotePacket(global, nlock)) return; if(pkt->dp_Res1 == NULL) { if(pkt->dp_Res2) return; /* Error on other side */ /* Null lock from other side, return a lock on our root */ nlock = &global->netchain.RootLock; } pkt->dp_Res1 = MKBADDR(CreateLock(global, nlock, (RPTR)pkt->dp_Res1, ACCESS_READ)); }