home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
msysjour
/
vol04
/
06
/
diserver.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-07-31
|
8KB
|
265 lines
/* diserver.c RHS 5/28/89
*
* directory information server
Run this program before running any programs (like DIPOP or LS) that
use the server. Run the program with:
DISERVER [/v]
The optional /v will turn on verbose mode, and status messages are printed.
*/
#define INCL_DOS
#define INCL_ERRORS
#include<os2.h>
#include<mt\stdio.h>
#include<mt\process.h>
#include<mt\string.h>
#include"errexit.h"
#define DICODE
#include"di.h"
#define THREADSTACK 1000
#define MAXTHREADS 20
#define lastchar(str) (str[strlen(str)-1])
typedef struct _serverthreads
{
ULONG threadSem;
SHORT threadID;
PREQUESTHEADER request;
SHORT threadnum;
UCHAR threadstack[THREADSTACK];
} SERVERTHREAD;
SERVERTHREAD SERVERTHREADS[MAXTHREADS];
USHORT verbose = FALSE;
void server_thread(SERVERTHREAD *threaddata);
void main(int argc, char **argv);
void main(int argc, char **argv)
{
USHORT retval, qcount = 0, nextthread = 0;
HQUEUE qhandle;
QUEUERESULT qresult;
USHORT ellength;
BYTE priority;
PREQUESTHEADER request;
if(argc > 1)
if(((*argv[1]=='-') || (*argv[1]=='/')) &&
(argv[1][1]=='v' || argv[1][1]=='V'))
verbose = TRUE;
else
printf("DiServer: ignoring unknown argument \"%s\"\n",argv[1]);
/* create the server queue for taking requests from clients
*/
if(retval = DosCreateQueue(&qhandle,QUE_FIFO,DIRINFOQNAME))
error_exit(retval,"DosCreateQueue");
if(verbose)
printf("DiServer: queue is open, awaiting requests...\n");
memset(SERVERTHREADS,0,sizeof(SERVERTHREADS));
while(TRUE)
{
/* read the queue to see if any requests have been made */
if(retval = DosReadQueue(qhandle,&qresult,&ellength,
(PVOID FAR *)&request,0x0000,DCWW_WAIT,&priority,0L))
if(retval != ERROR_QUE_EMPTY) /* if error was not from empty queue */
error_exit(retval,"DosReadQueue");
DosQueryQueue(qhandle,&qcount);
if(verbose)
printf("DiServer: request received from process %u (%u pending)\n",
qresult.pidProcess,qcount);
/* request has been made:
o find the next available server thread structure
o set its semaphore so it will wait until you've started it
o start the new server thread
o once it's successfully started, set the request pointer in
its data structure to the request that was received
o then tell the thread to go ahead by clearing the semaphore--
thus the thread can't go ahead without the request and without
having it's own thread ID installed in it's structure
o if the next thread structure isn't available, find one that is
o if it goes all the way around and doesn't find one, it will sleep
for a second before it tries again
*/
while(TRUE)
{
if(nextthread == MAXTHREADS)
{
nextthread = 0;
DosSleep(1000L);
}
if(!SERVERTHREADS[nextthread].threadID)
{
DosSemSet(&SERVERTHREADS[nextthread].threadSem);
if((SERVERTHREADS[nextthread].threadID = _beginthread(
server_thread, SERVERTHREADS[nextthread].threadstack,
THREADSTACK,(void *)&SERVERTHREADS[nextthread]))
== -1)
error_exit(-1,"_beginthread");
else
{
SERVERTHREADS[nextthread].request = request;
SERVERTHREADS[nextthread].threadnum = nextthread;
DosSemClear(&SERVERTHREADS[nextthread].threadSem);
nextthread++;
break;
}
}
while(++nextthread < MAXTHREADS)
if(!SERVERTHREADS[nextthread].threadID)
break;
}
}
DosCloseQueue(qhandle);
DosExit(EXIT_PROCESS,0); /* and exit */
}
void server_thread(SERVERTHREAD *threaddata)
{
PREQUESTHEADER request;
USHORT i, retval,found, bufsize, attributes,count;
PDIRINFORESULT results;
PFILEFINDBUF findbuf;
HDIR dirhandle;
char filespec[80],dircheck = FALSE;
char far *temp;
/* wait until main thread says to continue */
DosSemRequest(&threaddata->threadSem, SEM_INDEFINITE_WAIT);
request = threaddata->request;
if(verbose)
{
printf("Thread #%u:\n",threaddata->threadnum);
printf("\t%u filespec(s) in request\n",request->numRequests);
printf("\tClient's current directory is %s\n",request->currentdir);
}
findbuf = request->resultptr;
temp = MAKEP(request->serverwsel,0);
/* process each request:
o build the complete path and filespec from currentdir, and filespec
o get the attributes
o if there are attributes, include the directory bit so the dirs
will be found
else set the directory bit
o set bufsize to the max segment size minus the space already used
by results already found
*/
for(request->totalresults = i = 0, results = &request->resultArray[0];
i < request->numRequests; i++, results++)
{
if(verbose)
printf("\tFilespec %u: Attr:%4x Dirspec: %s Filespec: %s\n",
i,results->attributes,results->currentdir,results->filespec);
strcpy(filespec,results->currentdir);
if(lastchar(filespec) != '\\')
strcat(filespec,"\\");
strcat(filespec,results->filespec);
attributes = results->attributes;
if(attributes)
attributes |= FILE_DIRECTORY;
else
attributes = FILE_DIRECTORY;
expand_directory:
found = 0xffff;
dirhandle = HDIR_SYSTEM;
bufsize = MAXSEGSIZE-1;
bufsize -= ((char far *)findbuf-temp);
/* find the files:
o if an error occurred and it was not one of these listed, it's
very bad news
o otherwise the error is no files found
o if no error, and we're not yet expanding a directory and we only
found one file, and it has a directory attribute, try again
o otherwise, we found 1 or more files
*/
if(verbose)
printf("\tSearching for %s, buffersize=%u attributes=0x%04x\n",
filespec,bufsize,attributes);
if(retval = DosFindFirst(filespec, &dirhandle, attributes, findbuf,
bufsize, &found, 0L))
{
switch(retval)
{
case ERROR_FILE_NOT_FOUND:
case ERROR_NO_MORE_FILES:
case ERROR_PATH_NOT_FOUND:
results->errorval = retval;
break;
default:
error_exit(retval,"DosFindFirst");
}
results->firstfile = NULL;
results->numfound = 0;
}
else
{
if(verbose)
printf("\tFound %u files:\n",found);
if(!dircheck && (found == 1) && (findbuf->attrFile & FILE_DIRECTORY)
&& !strcmp(findbuf->achName,
&filespec[strlen(filespec)-strlen(findbuf->achName)]))
{
strcat(filespec,"\\*.*");
dircheck = TRUE;
DosSleep(32L);
goto expand_directory;
}
results->firstfile = findbuf;
results->numfound = found;
request->totalresults += found;
for( count = 0 ; found > 0; found--, count++)
{
if(verbose)
{
if(count == 5)
{
printf("\n");
count = 0;
}
printf( ((findbuf->attrFile & FILE_DIRECTORY) ?
"[%-12s] " : "%-15s"),findbuf->achName);
}
findbuf = (PFILEFINDBUF)(&(findbuf->cchName)+findbuf->cchName+2);
}
DosSleep(32L);
}
}
/* now resize the segment to include only the data */
request->resultsize = (USHORT)((char far *)findbuf-temp)+5;
if(verbose)
printf("\nThread #%u: Work area resized to %u bytes. Request complete.\n\n",
threaddata->threadnum,request->resultsize);
DosFreeSeg(request->serverwsel); /* free the results segment*/
DosSemClear(&request->RAMsem); /* tell client we're done */
threaddata->threadID = 0;
DosExit(EXIT_THREAD,0);
}