home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / S12442.ZIP / DI.BAK < prev    next >
Text File  |  1989-10-27  |  12KB  |  397 lines

  1. /* di.c RHS 7/15/89
  2.  *
  3.  */
  4.  
  5.  
  6. #define    INCL_DOS
  7. #define    INCL_ERRORS
  8.  
  9. #include<os2.h>
  10. #include<mt\stdio.h>
  11. #include<mt\string.h>
  12. #include<mt\stdlib.h>
  13. #include<mt\ctype.h>
  14. #include"errexit.h"
  15.  
  16. #define DICODE
  17. #include"di.h"
  18.  
  19. #define    lastchar(str)        (str[strlen(str)-1])
  20.  
  21. void   diInit(PID *qowner, HQUEUE *qhandle);
  22. void   adddriveletter(PCH *filespecs,USHORT driveno);
  23. void      makefpath(char *org,char*result,char*currentpath,                               USHORT currentdrive);
  24. void      getdriveinfo(USHORT*currentdrive,char*currentpath,                                USHORT *psize);
  25. USHORT diallocseg(USHORT size,SEL*oursel,PID other,SEL*othersel):
  26. void    convertptr(VOID **ptr,SEL newsel);
  27.  
  28.     /* DiMakeRequest
  29.     This function creates or adds to an existing directory information
  30.     request. A new request is created if the pointer (hptr) is set to         NULL. Note that this is the pointer whose address is passed to the         function.    The filespec is a full path and file specification with         optional wildcards. The attribute parameter will control the files         that are found. */
  31.  
  32. void DiMakeRequest(PREQUESTHEADER *hptr, PCH filespec, USHORT att)
  33.     {
  34.     PREQUESTHEADER    header;
  35.     PDIRINFORESULT    resultstru;
  36.     SEL                hselector,serversel;
  37.     void far            *results;
  38.     USHORT            retval,size,psize = 0,setdir = FALSE;
  39.     HQUEUE            qhandle;
  40.     PID                qowner;
  41.     PCH                requestspec;
  42.     char                resultbuf[_MAX_DIR],*resultfspec;
  43.     char                currentpath[_MAX_PATH];
  44.     USHORT            currentdrive;
  45.  
  46.      if(!(header = *hptr))
  47.      DiInit(&qowner, &qhandle);
  48.  
  49.     /* Now gather the information to prepare the header:
  50.      o    Get the current disk drive
  51.      o    Get the length of the current directory path
  52.      o    Get the size of the request arguments (the requestspec)
  53.      o    Allocate the header segment
  54.      o    Make it giveable to the server process */
  55.  
  56.     getdriveinfo(¤tdrive,currentpath,&psize);
  57.  
  58.     if(!header)                      /* If no header is  alloc'd */
  59.       {
  60.                                   /* Allocate header segment */
  61.     if(retval = diallocseg(size = sizeof(REQUESTHEADER),&hselector,
  62.                        qowner,&serversel))
  63.       error_exit(retval,"diallocseg");
  64.  
  65.       header = MAKEP(hselector,0);      /* Make header pointer */
  66.       *hptr = header;
  67.       header->serverhsel = serversel;    /* Allocate work segment */
  68.     if(retval = diallocseg(MAXSEGSIZE,&header->rselector,qowner,
  69.                         &serversel))
  70.       error_exit(retval,"diallocseg");
  71.  
  72.      results = MAKEP(header->rselector,0); /* Make pointer */
  73.     
  74.      header->RAMsem = 0L;              /* Initialize semaphore */
  75.      header->resultptr = MAKEP(serversel,0); /* Set pointer to work area */
  76.      header->serverwsel = serversel;        /* Selector to work area    */
  77.      header->numRequests = 0;            /* Set number of requests */
  78.  
  79.     requestspec = (PCH)results;            /* Set to work area */
  80.      header->currentdir = requestspec;        /* Set pointer to it */
  81.      *requestspec++ = (char)(currentdrive + 'A' - 1);
  82.                                     /* Add drive letter    */
  83.       strcpy(requestspec,":\\");            /* And ':\'*/
  84.       requestspec += 2;                 /* Move pointer past them */
  85.  
  86.     DosQCurDir(currentdrive,requestspec,&psize);
  87.                                     /* Add current directory */
  88.       requestspec += (strlen(requestspec)+1);   /* Move pointer past dir*/
  89.        header->qowner = qowner;
  90.        header->qhandle = qhandle;
  91.         }
  92.     
  93.        else
  94.         {
  95.        requestspec = header->requestspec;
  96.        qowner = header->qowner;
  97.        qhandle = header->qhandle;
  98.  
  99.        size = header->size + sizeof(DIRINFORESULT);
  100.        hselector = SELECTOROF(header);
  101.  
  102.        if(retval = DosReallocSeg(size,hselector)) /* Resize segment */
  103.         error_exit(retval,"DosReallocSeg");
  104.         }
  105.  
  106.          /* Resultstru always points to the next available structure */
  107.     resultstru = &header->resultArray[header->numRequests];
  108.        strupr(filespec);                 /* Set arg to upper case */
  109.     memset(resultstru,0,sizeof(DIRINFORESULT)); /* Clear structure */
  110.        resultstru->attributes = att;         /* Set attributes */
  111.                                     /* Get full path filespec */
  112.     makefpath(filespec,resultbuf,currentpath,currentdrive);
  113.      resultfspec = strrchr(resultbuf,'\\');  /* Find last backslash */
  114.     
  115.     if(strcmp(resultbuf,header->currentdir))  /* If not in currentdir */
  116.        {
  117.       strcpy(requestspec,resultbuf);         /* Copy path */
  118.      resultstru->currentdir = requestspec;     /* Set pointer */
  119.      requestspec += (strlen(requestspec)+1);    
  120.                                    /* Set pointer to next spot */
  121.        }
  122.      else                             /* Use default directory */
  123.       resultstru->currentdir = header->currentdir; /* Set pointer */
  124.  
  125.     strcpy((char *)requestspec,resultfspec);  /* Copy the filespec */
  126.     resultstru->filespec = requestspec;      /* Set a pointer to it */
  127.     requestspec += (strlen(requestspec)+1);      /* set to next position */
  128.  
  129.     header->size = size;
  130.     header->numRequests++;
  131.     header->requestspec = requestspec;
  132.      }
  133.  
  134.  
  135. void DiSendRequest(PREQUESTHEADER hdr)
  136.      {
  137.     PCH *resptr,*newptr;
  138.     USHORT    offset,retval,i;
  139.     SEL    newsel,serverwsel = SELECTOROF(hdr->resultptr);
  140.     PBYTE sheader = MAKEP(hdr->serverhsel,0);   /* Make pointer */
  141.         
  142.           /* Adjust resultptr to point to available space    */
  143.     resptr = MAKEP(hdr->rselector,0);           /* Create ptr to result */
  144.     offset = (hdr->requestspec - (PCH)resptr);    /* Get offset to use */
  145.     hdr->resultptr = MAKEP(serverwsel,offset);    /* Reset pointer */
  146.  
  147.           /* Write request to the queue */
  148.     if(retval = DosWriteQueue(hdr->qhandle,0,hdr->size,(PBYTE)sheader,0))
  149.       error_exit(retval,"DosWriteQueue");  /* Wait for server to finish */
  150.  
  151.     DosSemSetWait(&hdr->RAMsem,SEM_INDEFINITE_WAIT); /* Get new segment */
  152.     if(retval = DosAllocSeg(hdr->resultsize,&newsel,SEG_NONSHARED))
  153.       error_exit(retval,"DosAllocSeg");
  154.  
  155.      newptr = MAKEP(newsel,0);            /* Make pointer to segment */
  156.     memmove(newptr,resptr,hdr->resultsize);       /* Copy from old segment */
  157.     convertptr(&hdr->currentdir,newsel);     /* Convert pointers */
  158.       convertptr(&hdr->requestspec,newsel);
  159.  
  160.     for( i = 0; i < hdr->numRequests; i++)
  161.        {
  162.     convertptr(&hdr->resultArray[i].filespec,newsel);
  163.     if(SELECTOROF(hdr->resultArray[i].currentdir) == hdr->rselector) 
  164.     convertptr(&hdr->resultArray[i].currentdir,newsel);
  165.     convertptr(&hdr->resultArray[i].firstfile,newsel);
  166.     convertptr(&hdr->resultArray[i].nextfile,newsel);
  167.        }
  168.  
  169.     DosFreeSeg(hdr->rselector);        /* Free the old segment */
  170.     hdr->rselector = newsel;            /* Set for new selector */
  171.      }
  172.  
  173. void DiGetNumResults(PREQUESTHEADER header,USHORT *numresults,
  174.                 USHORT *numrequests)
  175.      {
  176.      *numresults = header->totalresults;
  177.      *numrequests = header->numRequests;
  178.      }
  179.  
  180. void DiDestroyRequest(PREQUESTHEADER *header)
  181.      {
  182.     USHORT retval;
  183.     PREQUESTHEADER hdr = *header;
  184.  
  185.     if(retval = DosFreeSeg(hdr->rselector))         /* Free work segment */
  186.       error_exit(retval,"DosFreeSeg");
  187.     if(retval = DosFreeSeg(SELECTOROF(hdr)))    /* Free header segment */
  188.       error_exit(retval,"DosFreeSeg");
  189.  
  190.     *header = NULL;                        /* Set pointer to NULL *\
  191.      }
  192.  
  193. char *DiGetResultFspec(PDIRINFORESULT result)
  194.     {
  195.     static char *p = "*.*";
  196.  
  197.     if(result->errorval == DIREXPANDED)
  198.         return p;
  199.     return result->currentdir;
  200.     return result->filespec;
  201.     }
  202.  
  203. char *DiGetResultDir(PDIRINFORESULT result)
  204.     {
  205.     static char dirbuf[80];
  206.     
  207.     if(result->errorval == DIREXPANDED)
  208.         {
  209.      strcpy(dirbuf,result->currentdir);
  210.       strcat(dirbuf,"\\");
  211.      strcat(dirbuf,result->filespec);
  212.      return dirbuf;
  213.         }
  214.  
  215.     return result->currentdir;
  216.     }
  217.  
  218. void DiGetResultHdl(PREQUESTHEADER header,USHORT requestnum,USHORT *num, PDIRINFORESULT *resulthdl)
  219.     {
  220.    *resulthdl = &header->resultArray[requestnum];
  221.    *num = (*resulthdl)->numfound;
  222.     }
  223.  
  224. void DiGetFirstResult(PDIRINFORESULT result, char *buffer)
  225.     {
  226.    result->nextfile = result->firstfile;
  227.    DiGetNextResult(result,buffer);
  228.     }
  229.  
  230. void DiGetNextResult(PDIRINFORESULT result, char *buffer)
  231.     {
  232.    if(!result->nextfile)
  233.       {    
  234.      *buffer = '\0';
  235.      return;
  236.       }
  237.  
  238.    strcpy(buffer,result->nextfile->achName);
  239.    result->nextfile = 
  240.    (PFILEFINDBUF)(&(result->nextfile->cchName)+
  241.                 result->nextfile->cchName+2);
  242.     }
  243.  
  244. void DiGetFirstResultPtr(PDIRINFORESULT result, PFILEFINDBUF *ptr)
  245.     {
  246.     result->nextfile = result->firstfile;
  247.     DiGetNextResultPtr(result,ptr);
  248.     }
  249.  
  250. void DiGetNextResultPtr(PDIRINFORESULT result, PFILEFINDBUF *ptr)
  251.     {
  252.     if(!result->nextfile)
  253.        {    
  254.       *ptr = NULL;
  255.       return;
  256.        }
  257.  
  258.     *ptr = result->nextfile;
  259.     result->nextfile = 
  260.     (PFILEFINDBUF)(&(result->nextfile->cchName)+
  261.                   result->nextfile->cchName+2);
  262.     }
  263.  
  264. void DiBuildResultTbl(PREQUESTHEADER header, PFILEFINDBUF **table)
  265.     {
  266.     SEL tablesel;
  267.     USHORT retval, i;
  268.     PFILEFINDBUF f,*temp;
  269.  
  270.    if (retval = DosAllocSeg((header->totalresults*sizeof(PFILEFINDBUF)),
  271.                         &tablesel, SEG_NONSHARED))
  272.      error_exit(retval,"DosAllocSeg");
  273.  
  274.      temp = MAKEP(tablesel,0);
  275.      f = header->resultArray[0].firstfile;
  276.  
  277.      for( i = 0; i < header->totalresults; i++)
  278.         {
  279.         temp[i] = f;
  280.           f = (PFILEFINDBUF) (&(f->cchName)+f->cchName+2);
  281.         }
  282.     
  283.     *table = temp;
  284.     }
  285.  
  286. void diInit(PID *qowner, HQUEUE *qhandle)
  287.     {
  288.     USHORT    retval;
  289.  
  290. /* Try to open the queue to the directory server    */
  291.    if(!(retval = DosOpenQueue(qowner,qhandle,DIRINFOQNAME)))
  292.      return;
  293.    if(retval != ERROR_QUE_NAME_NOT_EXIST)
  294.      error_exit(retval,"DosOpenQueue");
  295.      else
  296.      error_exit(retval,
  297.               "DosOpenQueue - Server probably hasn't opened queue");
  298.        }
  299.  
  300. void convertptr(VOID**ptr,SEL newsel)
  301.     {
  302.    USHORT offset = OFFSETOF(*ptr);
  303.    *ptr = MAKEP(newsel,offset);
  304.     }
  305.             
  306. /* Assumes that the globals, currentpath and currentdrive are properly
  307.    initialized */
  308. void makefpath(char *org,char *result,char *currentpath,
  309.             USHORT currentdrive)
  310.     {
  311.    char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME],                          ext[_MAX_EXT];
  312.    char currdir[_MAX_DIR], *backup, *outdir;
  313.    USHORT driveno,cdirsize = _MAX_DIR-1, retval;
  314.    strupr(org);                /* uppercase the path */
  315.    _splitpath(org,drive,dir,fname,ext);    /* get path components */
  316.  
  317.    /* If we have a full path from the user at this point, we don't have          to do anything more-whatever they ask for, they get. If we don't have      a full path, we will need to get the fullpath to the current              directory of that drive, and then reconcile the working directory or 
  318.      parent directory to end up with the "real" path to the file. However,
  319.      if the path is on the same drive, we can use currentdir and save the         the time of a DosQCurDir call. */
  320.  
  321.      if(!(*drive))                    /* If no drive letter */
  322.        {
  323.       driveno = currentdrive;
  324.       *drive = (char)(currentdrive+'A'-1);
  325.       strcpy(&drive[1],":");
  326.        }
  327.     else
  328.       driveno = (*drive-'A'+1);
  329.  
  330.     if(*dir != '\\')                /* If not a full path */
  331.        {
  332.       if(driveno != currentdrive)
  333.         {
  334.         *currdir = '\\';
  335.       if(retval = DosQCurDir(driveno,&currdir[1],&cdirsize))
  336.         error_exit(retval,
  337.                 "DosQCurDir - probably invalid drive or directory");
  338.          }
  339.  
  340.       else
  341.         strcpy(currdir,¤tpath[2]);
  342.         
  343.     if(lastchar(currdir) != '\\')
  344.        strcat(currdir,"\\");
  345.  
  346.     strcat(currdir,dir);
  347.     strcpy(dir,currdir);
  348.         }
  349.  
  350.      /* dir now has full path to the filespec, reconcile and restore */
  351.     while(backup = strstr(dir,"\\..\\"))    /* Remove any "\..\" */
  352.       {
  353.      for(outdir = backup-1; (*outdir != '\\') && (outdir > dir); 
  354.         outdir--);
  355.                                     /* Now outdir is '\' dest */
  356.      backup += 3;     /* now backup is on the source '\'    */
  357.      strcpy(outdir,backup);
  358.       }
  359.     
  360.     while(backup = strstr(dir,"\\.\\"))        /* Remove any "\.\" */
  361.       {
  362.      outdir = backup;
  363.      backup += 2;
  364.      strcpy(outdir,backup);
  365.       }
  366.  
  367.     _makepath(result,drive,dir,fname,ext);    /* Put it all back together */
  368.      }        
  369.  
  370. void getdriveinfo(USHORT *currentdrive,char *currentpath,USHORT *psize)
  371.     {
  372.     ULONG    drivemap;
  373.     USHORT    retval;
  374.  
  375.     DosQCurDisk(currentdrive,&drivemap);      /* Get current drive number */
  376.     *currentpath = (char)(*currentdrive+'A'-1);
  377.     strcpy(¤tpath[1],":\\");
  378.  
  379.     *psize = _MAX_PATH;
  380.     if(retval = DosQCurDir(*currentdrive,¤tpath[3],psize))
  381.       error_exit(retval,"DosQCurDir");
  382.  
  383.     DosQCurDisk(currentdrive,&drivemap);    /* Get current drive number */
  384.     *psize = 0;
  385.     DosQCurDir(*currentdrive,NULL,psize);    /* Get size of currdir path */
  386.     }
  387.  
  388. USHORT diallocseg(USHORT size, SEL *oursel,PID other,SEL *othersel)
  389.     {
  390.     USHORT retval = 0;
  391.                                     /* And shareable by server */
  392.     if(!(retval = DosAllocSeg(size,oursel,SEG_GIVEABLE)))
  393.      retval = DosGiveSeg(*oursel,other,othersel);
  394.  
  395.     return retval;
  396.     }
  397.