1 /*
2 * Copyright (c) 1995 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 /*
23 * $Header: /n/picasso/project/mm/mpeg/mpeg_dist/mpeg_encode/RCS/file.c,v 1.2 1993/06/30 20:06:09 keving Exp $
24 * $Log: file.c,v $
25 * Revision 1.2 1993/06/30 20:06:09 keving
26 * nothing
27 *
28 * Revision 1.1 1993/06/03 21:08:08 keving
29 * nothing
30 *
31 */
32
33 #include "tk.h"
34
35 #include "all.h"
36
37 #include <sys/file.h>
38 #include <sys/stat.h>
39 #include <sys/param.h>
40 #include <time.h>
41 #include <string.h>
42 #include <dirent.h>
43 #include <strings.h>
44
45 #define MAX_FILES 1000
46 #define MAX_NAME_LEN 256
47 #define MAX_STRING_LEN MAX_NAME_LEN
48
49 typedef int boolean;
50 #define TRUE 1
51 #define FALSE 0
52
53 extern char currentPath[MAXPATHLEN];
54
55 char globString[1024];
56
57 static DIR *dfd;
58
59 void ResetPath(void);
60 int ListDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
61 char **argv);
62 int ChangeDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
63 char **argv);
64 void SortFiles(int numStrings, char strings[MAX_FILES][MAX_NAME_LEN],
65 boolean *dirList, int permute[]);
66
67 static void UpdatePath(Tcl_Interp *interp, char *directory);
68 static boolean MatchesGlob(char *string, char *glob);
69
70
71
ResetPath()72 void ResetPath()
73 {
74 if ( getwd(currentPath) == 0 )
75 {
76 fprintf(stderr, "Error getting pathname!!!\n");
77 exit(1);
78 }
79
80 strcpy(¤tPath[strlen(currentPath)], "/");
81
82 dfd = opendir(currentPath);
83 if ( dfd == NULL )
84 {
85 fprintf(stderr, "can't open '%s'\n", currentPath);
86 exit(1);
87 }
88 }
89
90
UpdatePath(Tcl_Interp * interp,char * directory)91 static void UpdatePath(Tcl_Interp *interp, char *directory)
92 {
93 int length;
94 char *charPtr;
95
96 length = strlen(currentPath);
97
98 if ( strcmp(directory, "./") == 0 )
99 return /* nothing */ ;
100 else if ( strcmp(directory, "../") == 0 )
101 {
102 /* delete backwards up to '/' */
103
104 if ( length < 2 )
105 {
106 fprintf(stderr, "Error: backing up from root directory!!!\n");
107 exit(1);
108 }
109
110 charPtr = ¤tPath[length-2];
111 while ( (charPtr != currentPath) && (*charPtr != '/') )
112 charPtr--;
113 charPtr++; /* leave the '/' */
114 *charPtr = '\0';
115 }
116 else
117 {
118 strcpy(¤tPath[length], directory);
119 }
120 }
121
122
ChangeDirectory(ClientData nulldata,Tcl_Interp * interp,int argc,char ** argv)123 int ChangeDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
124 char **argv)
125 {
126 char *directory = argv[1];
127
128 UpdatePath(interp, directory);
129
130 fprintf(stdout, "Opening directory: '%s'\n", currentPath);
131
132 dfd = opendir(currentPath);
133 if ( dfd == NULL )
134 {
135 fprintf(stderr, "can't open '%s'\n", currentPath);
136 return TCL_OK; /* shouldn't, really */
137 }
138
139 return TCL_OK;
140 }
141
142
ListDirectory(ClientData nulldata,Tcl_Interp * interp,int argc,char ** argv)143 int ListDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
144 char **argv)
145 {
146 struct dirent *dp;
147 struct stat stbuf;
148 char command[256];
149 char fileName[MAX_FILES][MAX_NAME_LEN];
150 boolean dirList[MAX_FILES];
151 int permute[MAX_FILES];
152 int fileCount = 0;
153 register int index;
154 char fullName[MAXPATHLEN];
155 char *restPtr;
156
157 sprintf(command, "ShowCurrentDirectory %s", currentPath);
158 Tcl_Eval(interp, command, 0, (char **) NULL);
159
160 if ( dfd == NULL )
161 {
162 fprintf(stderr, "TRIED TO LIST NULL DIRECTORY\n");
163
164 return TCL_OK;
165 }
166
167 /* check if root directory */
168 if ( strlen(currentPath) != 1 )
169 {
170 sprintf(fileName[fileCount], "../");
171 dirList[fileCount] = TRUE;
172 fileCount++;
173 }
174
175 strcpy(fullName, currentPath);
176 restPtr = &fullName[strlen(fullName)];
177
178 while ( (dp = readdir(dfd)) != NULL )
179 {
180 strcpy(restPtr, dp->d_name);
181 stat(fullName, &stbuf);
182
183 if ( dp->d_name[0] != '.' )
184 {
185 if ( S_ISDIR(stbuf.st_mode) )
186 {
187 sprintf(fileName[fileCount], "%s/", dp->d_name);
188 dirList[fileCount] = TRUE;
189 fileCount++;
190 }
191 else
192 {
193 if ( MatchesGlob(dp->d_name, globString) )
194 {
195 strcpy(fileName[fileCount], dp->d_name);
196 dirList[fileCount] = FALSE;
197 fileCount++;
198 }
199 }
200 }
201 }
202
203 SortFiles(fileCount, fileName, dirList, permute);
204
205 for ( index = 0; index < fileCount; index++ )
206 {
207 sprintf(command, "AddBrowseFile %s", fileName[permute[index]]);
208 Tcl_Eval(interp, command, 0, (char **) NULL);
209 }
210
211 closedir(dfd);
212
213 return TCL_OK;
214 }
215
216
SortFiles(int numStrings,char strings[MAX_FILES][MAX_NAME_LEN],boolean * dirList,int permute[])217 void SortFiles(int numStrings, char strings[MAX_FILES][MAX_NAME_LEN],
218 boolean *dirList, int permute[])
219 {
220 register int i, j;
221 int temp;
222 int numDirs;
223 int ptr;
224
225 for ( i = 0; i < numStrings; i++ )
226 permute[i] = i;
227
228 /* put all directories at front */
229 numDirs = 0;
230 ptr = numStrings-1;
231 while ( numDirs != ptr )
232 {
233 /* go past dirs */
234 while ( (numDirs < ptr) && (dirList[permute[numDirs]]) )
235 numDirs++;
236
237 /* go past non-dirs */
238 while ( (numDirs < ptr) && (! dirList[permute[ptr]]) )
239 ptr--;
240
241 if ( numDirs != ptr )
242 {
243 temp = permute[numDirs];
244 permute[numDirs] = ptr;
245 permute[ptr] = temp;
246 }
247 }
248
249 if ( dirList[permute[numDirs]] )
250 numDirs++;
251
252 for ( i = 0; i < numDirs; i++ )
253 for ( j = i+1; j < numDirs; j++ )
254 {
255 if ( strcmp(&strings[permute[j]][0], &strings[permute[i]][0]) < 0 )
256 {
257 temp = permute[j];
258 permute[j] = permute[i];
259 permute[i] = temp;
260 }
261 }
262
263 for ( i = numDirs; i < numStrings; i++ )
264 for ( j = i+1; j < numStrings; j++ )
265 {
266 if ( strcmp(&strings[permute[j]][0], &strings[permute[i]][0]) < 0 )
267 {
268 temp = permute[j];
269 permute[j] = permute[i];
270 permute[i] = temp;
271 }
272 }
273 }
274
275
SetBrowseGlob(ClientData nulldata,Tcl_Interp * interp,int argc,char ** argv)276 int SetBrowseGlob (ClientData nulldata, Tcl_Interp *interp,
277 int argc, char **argv)
278 {
279 if (argc == 2 )
280 {
281 strcpy(globString, argv[1]);
282
283 fprintf(stdout, "GLOB: %s\n", globString);
284
285 return TCL_OK;
286 }
287
288 Tcl_AppendResult (interp,
289 "wrong args: should be \"", argv[0]," string\"", (char *) NULL);
290 return TCL_ERROR;
291 }
292
293
MatchesGlob(char * string,char * glob)294 static boolean MatchesGlob(char *string, char *glob)
295 {
296 char *stringRight, *globRight;
297
298 while ( (*glob != '\0') && (*glob != '*') ) /* match left side */
299 {
300 if ( (*string == '\0') || (*string != *glob) )
301 return FALSE;
302 string++;
303 glob++;
304 }
305
306 if ( *glob == '\0' ) /* no star */
307 return TRUE;
308
309 /* now match right side */
310 stringRight = &string[strlen(string)-1];
311 globRight = &glob[strlen(glob)-1];
312
313 while ( *globRight != '*' )
314 {
315 if ( (stringRight < string) || (*stringRight != *globRight) )
316 return FALSE;
317 globRight--;
318 stringRight--;
319 }
320
321 return TRUE;
322 }
323