home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 9 / CD_ASCQ_09_1193.iso / news / 4441 / mpegcode / misc / file.c < prev    next >
C/C++ Source or Header  |  1993-01-01  |  7KB  |  311 lines

  1. /*
  2.  * Copyright (c) 1993 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  *
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  *
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21.  
  22. #include "tk.h"
  23.  
  24. #include "all.h"
  25.  
  26. #include <sys/file.h>
  27. #include <sys/stat.h>
  28. #include <sys/param.h>
  29. #include <time.h>
  30. #include <string.h>
  31. #include <dirent.h>
  32. #include <strings.h>
  33.  
  34. #define MAX_FILES   1000
  35. #define MAX_NAME_LEN    256
  36. #define MAX_STRING_LEN    MAX_NAME_LEN
  37.  
  38. extern char currentPath[MAXPATHLEN];
  39.  
  40. char    globString[1024];
  41.  
  42. static DIR *dfd;
  43.  
  44. void    ResetPath(void);
  45. int ListDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
  46.           char **argv);
  47. int ChangeDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
  48.           char **argv);
  49. void    SortFiles(int numStrings, char strings[MAX_FILES][MAX_NAME_LEN],
  50.           boolean *dirList, int permute[]);
  51.  
  52. static void    UpdatePath(Tcl_Interp *interp, char *directory);
  53. static boolean    MatchesGlob(char *string, char *glob);
  54.  
  55.  
  56.  
  57. void    ResetPath()
  58. {
  59.     if ( getwd(currentPath) == 0 )
  60.     {
  61.     fprintf(stderr, "Error getting pathname!!!\n");
  62.     exit(1);
  63.     }
  64.  
  65.     strcpy(¤tPath[strlen(currentPath)], "/");
  66.  
  67.     dfd = opendir(currentPath);
  68.     if ( dfd == NULL )
  69.     {
  70.     fprintf(stderr, "can't open '%s'\n", currentPath);
  71.     exit(1);
  72.     }
  73. }
  74.  
  75.  
  76. static void    UpdatePath(Tcl_Interp *interp, char *directory)
  77. {
  78.     int length;
  79.     char *charPtr;
  80.  
  81.     length = strlen(currentPath);
  82.  
  83.     if ( strcmp(directory, "./") == 0 )
  84.     return /* nothing */ ;
  85.     else if ( strcmp(directory, "../") == 0 )
  86.     {
  87.     /* delete backwards up to '/' */
  88.  
  89.     if ( length < 2 )
  90.     {
  91.         fprintf(stderr, "Error:  backing up from root directory!!!\n");
  92.         exit(1);
  93.     }
  94.  
  95.     charPtr = ¤tPath[length-2];
  96.     while ( (charPtr != currentPath) && (*charPtr != '/') )
  97.         charPtr--;
  98.     charPtr++;    /* leave the '/' */
  99.     *charPtr = '\0';
  100.     }
  101.     else
  102.     {
  103.     strcpy(¤tPath[length], directory);
  104.     }
  105. }
  106.  
  107.  
  108. int ChangeDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
  109.           char **argv)
  110. {
  111.     char *directory = argv[1];
  112.  
  113.     UpdatePath(interp, directory);
  114.  
  115.     dfd = opendir(currentPath);
  116.     if ( dfd == NULL )
  117.     {
  118.     fprintf(stderr, "can't open '%s'\n", currentPath);
  119.     return TCL_OK;    /* shouldn't, really */
  120.     }
  121.  
  122.     return TCL_OK;
  123. }
  124.  
  125.  
  126. int ListDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
  127.           char **argv)
  128. {
  129.     struct dirent *dp;
  130.     struct stat stbuf;
  131.     char command[256];
  132.     char fileName[MAX_FILES][MAX_NAME_LEN];
  133.     boolean dirList[MAX_FILES];
  134.     int permute[MAX_FILES];
  135.     int    fileCount = 0;
  136.     register int index;
  137.     char fullName[MAXPATHLEN];
  138.     char    *restPtr;
  139.     static boolean first = TRUE;
  140.  
  141.     if ( first )
  142.     {
  143.     sprintf(globString, "*.ppm");
  144.     first = FALSE;
  145.     }
  146.  
  147.     sprintf(command, "ShowCurrentDirectory %s", currentPath);
  148.     Tcl_Eval(interp, command, 0, (char **) NULL);
  149.  
  150.     if ( dfd == NULL )
  151.     {
  152.     fprintf(stderr, "TRIED TO LIST NULL DIRECTORY\n");
  153.  
  154.     return TCL_OK;
  155.     }
  156.  
  157. /* check if root directory */
  158.     if ( strlen(currentPath) != 1 )
  159.     {
  160.     sprintf(fileName[fileCount], "../");
  161.     dirList[fileCount] = TRUE;
  162.     fileCount++;
  163.     }
  164.  
  165.     strcpy(fullName, currentPath);
  166.     restPtr = &fullName[strlen(fullName)];
  167.  
  168.     while ( (dp = readdir(dfd)) != NULL )
  169.     {
  170.     strcpy(restPtr, dp->d_name);
  171.     stat(fullName, &stbuf);
  172.  
  173.     if ( dp->d_name[0] != '.' )
  174.     {
  175.         if ( S_ISDIR(stbuf.st_mode) )
  176.         {
  177.         sprintf(fileName[fileCount], "%s/", dp->d_name);
  178.         dirList[fileCount] = TRUE;
  179.         fileCount++;
  180.         }
  181.         else
  182.         {
  183.         if ( MatchesGlob(dp->d_name, globString) )
  184.         {
  185.             strcpy(fileName[fileCount], dp->d_name);
  186.             dirList[fileCount] = FALSE;
  187.             fileCount++;
  188.         }
  189.         }
  190.     }
  191.     }
  192.  
  193.     SortFiles(fileCount, fileName, dirList, permute);
  194.  
  195.     for ( index = 0; index < fileCount; index++ )
  196.     {
  197.     sprintf(command, "AddBrowseFile %s", fileName[permute[index]]);
  198.     Tcl_Eval(interp, command, 0, (char **) NULL);
  199.     }
  200.  
  201.     closedir(dfd);
  202.  
  203.     return TCL_OK;
  204. }
  205.  
  206.  
  207. void    SortFiles(int numStrings, char strings[MAX_FILES][MAX_NAME_LEN],
  208.           boolean *dirList, int permute[])
  209. {
  210.     register int i, j;
  211.     int temp;
  212.     int    numDirs;
  213.     int    ptr;
  214.  
  215.     for ( i = 0; i < numStrings; i++ )
  216.     permute[i] = i;
  217.  
  218.     /* put all directories at front */
  219.     numDirs = 0;
  220.     ptr = numStrings-1;
  221.     while ( numDirs != ptr )
  222.     {
  223.     /* go past dirs */
  224.     while ( (numDirs < ptr) && (dirList[permute[numDirs]]) )
  225.         numDirs++;
  226.  
  227.     /* go past non-dirs */
  228.     while ( (numDirs < ptr) && (! dirList[permute[ptr]]) )
  229.         ptr--;
  230.  
  231.     if ( numDirs != ptr )
  232.     {
  233.         temp = permute[numDirs];
  234.         permute[numDirs] = ptr;
  235.         permute[ptr] = temp;
  236.     }
  237.     }
  238.  
  239.     if ( dirList[permute[numDirs]] )
  240.     numDirs++;
  241.  
  242.     for ( i = 0; i < numDirs; i++ )
  243.     for ( j = i+1; j < numDirs; j++ )
  244.     {
  245.         if ( strcmp(&strings[permute[j]][0], &strings[permute[i]][0]) < 0 )
  246.         {
  247.         temp = permute[j];
  248.         permute[j] = permute[i];
  249.         permute[i] = temp;
  250.         }
  251.     }
  252.  
  253.     for ( i = numDirs; i < numStrings; i++ )
  254.     for ( j = i+1; j < numStrings; j++ )
  255.     {
  256.         if ( strcmp(&strings[permute[j]][0], &strings[permute[i]][0]) < 0 )
  257.         {
  258.         temp = permute[j];
  259.         permute[j] = permute[i];
  260.         permute[i] = temp;
  261.         }
  262.     }
  263. }
  264.  
  265.  
  266. int SetBrowseGlob (ClientData nulldata, Tcl_Interp *interp,
  267.            int argc, char **argv)
  268. {
  269.     if (argc == 2 )
  270.     {
  271.     strcpy(globString, argv[1]);
  272.  
  273.     return TCL_OK;
  274.     }
  275.  
  276.     Tcl_AppendResult (interp, 
  277.             "wrong args: should be \"", argv[0]," string\"", (char *) NULL);
  278.     return TCL_ERROR;
  279. }
  280.  
  281.  
  282. static boolean    MatchesGlob(char *string, char *glob)
  283. {
  284.     char    *stringRight, *globRight;
  285.  
  286.     while ( (*glob != '\0') && (*glob != '*') )        /* match left side */
  287.     {
  288.     if ( (*string == '\0') || (*string != *glob) )
  289.         return FALSE;
  290.     string++;
  291.     glob++;
  292.     }
  293.  
  294.     if ( *glob == '\0' )    /* no star */
  295.     return TRUE;
  296.  
  297.     /* now match right side */
  298.     stringRight = &string[strlen(string)-1];
  299.     globRight = &glob[strlen(glob)-1];
  300.  
  301.     while ( *globRight != '*' )
  302.     {
  303.     if ( (stringRight < string) || (*stringRight != *globRight) )
  304.         return FALSE;
  305.     globRight--;
  306.     stringRight--;
  307.     }
  308.  
  309.     return TRUE;
  310. }
  311.