OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [userland/] [sash/] [utils.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * Copyright (c) 1993 by David I. Bell
3
 * Permission is granted to use, distribute, or modify this source,
4
 * provided that this copyright notice remains intact.
5
 *
6
 * Utility routines.
7
 */
8
 
9
#include "sash.h"
10
 
11
#include <sys/types.h>
12
#include <sys/stat.h>
13
#include <dirent.h>
14
#include <time.h>
15
#include <utime.h>
16
#include <fcntl.h>
17
 
18
#ifdef L_intflag
19
 
20
int intflag;
21
 
22
#endif
23
 
24
#ifdef L_modestring
25
 
26
/*
27
 * Return the standard ls-like mode string from a file mode.
28
 * This is static and so is overwritten on each call.
29
 */
30
char *
31
modestring(mode)
32
{
33
        static  char    buf[12];
34
 
35
        strcpy(buf, "----------");
36
 
37
        /*
38
         * Fill in the file type.
39
         */
40
        if (S_ISDIR(mode))
41
                buf[0] = 'd';
42
        if (S_ISCHR(mode))
43
                buf[0] = 'c';
44
        if (S_ISBLK(mode))
45
                buf[0] = 'b';
46
        if (S_ISFIFO(mode))
47
                buf[0] = 'p';
48
#ifdef  S_ISLNK
49
        if (S_ISLNK(mode))
50
                buf[0] = 'l';
51
#endif
52
#ifdef  S_ISSOCK
53
        if (S_ISSOCK(mode))
54
                buf[0] = 's';
55
#endif
56
 
57
        /*
58
         * Now fill in the normal file permissions.
59
         */
60
        if (mode & S_IRUSR)
61
                buf[1] = 'r';
62
        if (mode & S_IWUSR)
63
                buf[2] = 'w';
64
        if (mode & S_IXUSR)
65
                buf[3] = 'x';
66
        if (mode & S_IRGRP)
67
                buf[4] = 'r';
68
        if (mode & S_IWGRP)
69
                buf[5] = 'w';
70
        if (mode & S_IXGRP)
71
                buf[6] = 'x';
72
        if (mode & S_IROTH)
73
                buf[7] = 'r';
74
        if (mode & S_IWOTH)
75
                buf[8] = 'w';
76
        if (mode & S_IXOTH)
77
                buf[9] = 'x';
78
 
79
        /*
80
         * Finally fill in magic stuff like suid and sticky text.
81
         */
82
        if (mode & S_ISUID)
83
                buf[3] = ((mode & S_IXUSR) ? 's' : 'S');
84
        if (mode & S_ISGID)
85
                buf[6] = ((mode & S_IXGRP) ? 's' : 'S');
86
        if (mode & S_ISVTX)
87
                buf[9] = ((mode & S_IXOTH) ? 't' : 'T');
88
 
89
        return buf;
90
}
91
 
92
#endif
93
 
94
#ifdef L_timestring
95
 
96
/*
97
 * Get the time to be used for a file.
98
 * This is down to the minute for new files, but only the date for old files.
99
 * The string is returned from a static buffer, and so is overwritten for
100
 * each call.
101
 */
102
char *
103
timestring(t)
104
        long    t;
105
{
106
        long            now;
107
        char            *str;
108
        static  char    buf[26];
109
 
110
        time(&now);
111
 
112
        str = ctime(&t);
113
 
114
        strcpy(buf, &str[4]);
115
        buf[12] = '\0';
116
 
117
        if ((t > now) || (t < now - 365*24*60*60L)) {
118
                strcpy(&buf[7], &str[20]);
119
                buf[11] = '\0';
120
        }
121
 
122
        return buf;
123
}
124
 
125
#endif
126
 
127
#ifdef L_isadir
128
 
129
/*
130
 * Return TRUE if a filename is a directory.
131
 * Nonexistant files return FALSE.
132
 */
133
BOOL
134
isadir(name)
135
        char    *name;
136
{
137
        struct  stat    statbuf;
138
 
139
        if (stat(name, &statbuf) < 0)
140
                return FALSE;
141
 
142
        return S_ISDIR(statbuf.st_mode);
143
}
144
 
145
#endif
146
 
147
#ifdef L_copyfile
148
 
149
/*
150
 * Copy one file to another, while possibly preserving its modes, times,
151
 * and modes.  Returns TRUE if successful, or FALSE on a failure with an
152
 * error message output.  (Failure is not indicted if the attributes cannot
153
 * be set.)
154
 */
155
BOOL
156
copyfile(srcname, destname, setmodes)
157
        char    *srcname;
158
        char    *destname;
159
        BOOL    setmodes;
160
{
161
        int             rfd;
162
        int             wfd;
163
        int             rcc;
164
        int             wcc;
165
        char            *bp;
166
        struct  stat    statbuf1;
167
        struct  stat    statbuf2;
168
        struct  utimbuf times;
169
        int len = 8192-16;
170
        char * buf = 0;
171
 
172
        if (stat(srcname, &statbuf1) < 0) {
173
                perror(srcname);
174
                return FALSE;
175
        }
176
 
177
        if (stat(destname, &statbuf2) < 0) {
178
                statbuf2.st_ino = -1;
179
                statbuf2.st_dev = -1;
180
        }
181
 
182
        if ((statbuf1.st_dev == statbuf2.st_dev) &&
183
                (statbuf1.st_ino == statbuf2.st_ino))
184
        {
185
                fprintf(stderr, "Copying file \"%s\" to itself\n", srcname);
186
                return FALSE;
187
        }
188
 
189
        rfd = open(srcname, 0);
190
        if (rfd < 0) {
191
                perror(srcname);
192
                return FALSE;
193
        }
194
 
195
        wfd = open(destname, O_WRONLY|O_CREAT|O_TRUNC, statbuf1.st_mode);
196
        if (wfd < 0) {
197
                perror(destname);
198
                close(rfd);
199
                return FALSE;
200
        }
201
 
202
        buf = malloc(len);
203
        if (!buf) {
204
                fprintf(stderr,"Unable to allocate buffer of %d bytes\n", len);
205
                return FALSE;
206
        }
207
 
208
        while ((rcc = read(rfd, buf, len)) > 0) {
209
                if (intflag) {
210
                        close(rfd);
211
                        close(wfd);
212
                        free(buf);
213
                        return FALSE;
214
                }
215
 
216
                bp = buf;
217
                while (rcc > 0) {
218
                        wcc = write(wfd, bp, rcc);
219
                        if (wcc < 0) {
220
                                perror(destname);
221
                                free(buf);
222
                                goto error_exit;
223
                        }
224
                        bp += wcc;
225
                        rcc -= wcc;
226
                }
227
        }
228
 
229
        free(buf);
230
 
231
        if (rcc < 0) {
232
                perror(srcname);
233
                goto error_exit;
234
        }
235
 
236
        close(rfd);
237
        if (close(wfd) < 0) {
238
                perror(destname);
239
                return FALSE;
240
        }
241
 
242
        if (setmodes) {
243
                (void) chmod(destname, statbuf1.st_mode);
244
 
245
                (void) chown(destname, statbuf1.st_uid, statbuf1.st_gid);
246
 
247
                times.actime = statbuf1.st_atime;
248
                times.modtime = statbuf1.st_mtime;
249
 
250
                (void) utime(destname, &times);
251
        }
252
 
253
        return TRUE;
254
 
255
 
256
error_exit:
257
        close(rfd);
258
        close(wfd);
259
 
260
        return FALSE;
261
}
262
 
263
#endif
264
 
265
#ifdef L_buildname
266
 
267
/*
268
 * Build a path name from the specified directory name and file name.
269
 * If the directory name is NULL, then the original filename is returned.
270
 * The built path is in a static area, and is overwritten for each call.
271
 */
272
char *
273
buildname(dirname, filename)
274
        char    *dirname;
275
        char    *filename;
276
{
277
        char            *cp;
278
        static  char    buf[PATHLEN];
279
 
280
        if ((dirname == NULL) || (*dirname == '\0'))
281
                return filename;
282
 
283
        cp = strrchr(filename, '/');
284
        if (cp)
285
                filename = cp + 1;
286
 
287
        strcpy(buf, dirname);
288
        strcat(buf, "/");
289
        strcat(buf, filename);
290
 
291
        return buf;
292
}
293
 
294
#endif
295
 
296
#ifdef L_expandwildcards
297
 
298
/*
299
 * Expand the wildcards in a filename, if any.
300
 * Returns an argument list with matching filenames in sorted order.
301
 * The expanded names are stored in memory chunks which can later all
302
 * be freed at once.  Returns zero if the name is not a wildcard, or
303
 * returns the count of matched files if the name is a wildcard and
304
 * there was at least one match, or returns -1 if either no filenames
305
 * matched or too many filenames matched (with an error output).
306
 */
307
int
308
expandwildcards(name, maxargc, retargv)
309
        char    *name;
310
        int     maxargc;
311
        char    *retargv[];
312
{
313
        char    *last;
314
        char    *cp1, *cp2, *cp3;
315
        DIR     *dirp;
316
        struct  dirent  *dp;
317
        int     dirlen;
318
        int     matches;
319
        char    dirname[PATHLEN];
320
 
321
        last = strrchr(name, '/');
322
        if (last)
323
                last++;
324
        else
325
                last = name;
326
 
327
        cp1 = strchr(name, '*');
328
        cp2 = strchr(name, '?');
329
        cp3 = strchr(name, '[');
330
 
331
        if ((cp1 == NULL) && (cp2 == NULL) && (cp3 == NULL))
332
                return 0;
333
 
334
        if ((cp1 && (cp1 < last)) || (cp2 && (cp2 < last)) ||
335
                (cp3 && (cp3 < last)))
336
        {
337
                fprintf(stderr, "Wildcards only implemented for last filename component\n");
338
                return -1;
339
        }
340
 
341
        dirname[0] = '.';
342
        dirname[1] = '\0';
343
 
344
        if (last != name) {
345
                memcpy(dirname, name, last - name);
346
                dirname[last - name - 1] = '\0';
347
                if (dirname[0] == '\0') {
348
                        dirname[0] = '/';
349
                        dirname[1] = '\0';
350
                }
351
        }
352
 
353
        dirp = opendir(dirname);
354
        if (dirp == NULL) {
355
                perror(dirname);
356
                return -1;
357
        }
358
 
359
        dirlen = strlen(dirname);
360
        if (last == name) {
361
                dirlen = 0;
362
                dirname[0] = '\0';
363
        } else if (dirname[dirlen - 1] != '/') {
364
                dirname[dirlen++] = '/';
365
                dirname[dirlen] = '\0';
366
        }
367
 
368
        matches = 0;
369
 
370
        while ((dp = readdir(dirp)) != NULL) {
371
                if ((strcmp(dp->d_name, ".") == 0) ||
372
                        (strcmp(dp->d_name, "..") == 0))
373
                                continue;
374
 
375
                if (!match(dp->d_name, last))
376
                        continue;
377
 
378
                if (matches >= maxargc) {
379
                        fprintf(stderr, "Too many filename matches\n");
380
                        closedir(dirp);
381
                        return -1;
382
                }
383
 
384
                cp1 = getchunk(dirlen + strlen(dp->d_name) + 1);
385
                if (cp1 == NULL) {
386
                        fprintf(stderr, "No memory for filename\n");
387
                        closedir(dirp);
388
                        return -1;
389
                }
390
 
391
                if (dirlen)
392
                        memcpy(cp1, dirname, dirlen);
393
                strcpy(cp1 + dirlen, dp->d_name);
394
 
395
                retargv[matches++] = cp1;
396
        }
397
 
398
        closedir(dirp);
399
 
400
        if (matches == 0) {
401
                fprintf(stderr, "No matches\n");
402
                return -1;
403
        }
404
 
405
        qsort((char *) retargv, matches, sizeof(char *), namesort);
406
 
407
        return matches;
408
}
409
 
410
#endif
411
 
412
#ifdef L_namesort
413
 
414
/*
415
 * Sort routine for list of filenames.
416
 */
417
int
418
namesort(p1, p2)
419
        char    **p1;
420
        char    **p2;
421
{
422
        return strcmp(*p1, *p2);
423
}
424
 
425
#endif
426
 
427
#ifdef L_match
428
 
429
/*
430
 * Routine to see if a text string is matched by a wildcard pattern.
431
 * Returns TRUE if the text is matched, or FALSE if it is not matched
432
 * or if the pattern is invalid.
433
 *  *           matches zero or more characters
434
 *  ?           matches a single character
435
 *  [abc]       matches 'a', 'b' or 'c'
436
 *  \c          quotes character c
437
 *  Adapted from code written by Ingo Wilken.
438
 */
439
BOOL
440
match(text, pattern)
441
        char    *text;
442
        char    *pattern;
443
{
444
        char    *retrypat;
445
        char    *retrytxt;
446
        int     ch;
447
        BOOL    found;
448
 
449
        retrypat = NULL;
450
        retrytxt = NULL;
451
 
452
        while (*text || *pattern) {
453
                ch = *pattern++;
454
 
455
                switch (ch) {
456
                        case '*':
457
                                retrypat = pattern;
458
                                retrytxt = text;
459
                                break;
460
 
461
                        case '[':
462
                                found = FALSE;
463
                                while ((ch = *pattern++) != ']') {
464
                                        if (ch == '\\')
465
                                                ch = *pattern++;
466
                                        if (ch == '\0')
467
                                                return FALSE;
468
                                        if (*text == ch)
469
                                                found = TRUE;
470
                                }
471
                                if (!found) {
472
                                        pattern = retrypat;
473
                                        text = ++retrytxt;
474
                                }
475
                                /* fall into next case */
476
 
477
                        case '?':
478
                                if (*text++ == '\0')
479
                                        return FALSE;
480
                                break;
481
 
482
                        case '\\':
483
                                ch = *pattern++;
484
                                if (ch == '\0')
485
                                        return FALSE;
486
                                /* fall into next case */
487
 
488
                        default:
489
                                if (*text == ch) {
490
                                        if (*text)
491
                                                text++;
492
                                        break;
493
                                }
494
                                if (*text) {
495
                                        pattern = retrypat;
496
                                        text = ++retrytxt;
497
                                        break;
498
                                }
499
                                return FALSE;
500
                }
501
 
502
                if (pattern == NULL)
503
                        return FALSE;
504
        }
505
        return TRUE;
506
}
507
 
508
#endif
509
 
510
#ifdef L_makeargs
511
 
512
/*
513
 * Take a command string, and break it up into an argc, argv list.
514
 * The returned argument list and strings are in static memory, and so
515
 * are overwritten on each call.  The argument array is ended with an
516
 * extra NULL pointer for convenience.  Returns TRUE if successful,
517
 * or FALSE on an error with a message already output.
518
 */
519
BOOL
520
makeargs(cmd, argcptr, argvptr)
521
        char    *cmd;
522
        int     *argcptr;
523
        char    ***argvptr;
524
{
525
        char            *cp;
526
        int             argc;
527
        static char     strings[CMDLEN+1];
528
        static char     *argtable[MAXARGS+1];
529
 
530
        /*
531
         * Copy the command string and then break it apart
532
         * into separate arguments.
533
         */
534
        strcpy(strings, cmd);
535
        argc = 0;
536
        cp = strings;
537
 
538
        while (*cp) {
539
                if (argc >= MAXARGS) {
540
                        fprintf(stderr, "Too many arguments\n");
541
                        return FALSE;
542
                }
543
 
544
                argtable[argc++] = cp;
545
 
546
                while (*cp && !isblank(*cp)) {
547
                        if (*cp == '"' || *cp == '\'') {
548
                                char *sp = cp++;
549
 
550
                                while (*cp && *cp != *sp)
551
                                        cp++;
552
 
553
                                if (*cp == *sp) {
554
                                        /* need bcopy for the overlapping regions */
555
                                        bcopy(sp + 1, sp, (cp - sp) - 1);
556
                                        bcopy(cp + 1, cp - 1, strlen(cp + 1) + 1);
557
                                        cp--;
558
                                }
559
                        } else
560
                                cp++;
561
                }
562
 
563
                while (isblank(*cp))
564
                        *cp++ = '\0';
565
        }
566
 
567
        argtable[argc] = NULL;
568
 
569
        *argcptr = argc;
570
        *argvptr = argtable;
571
 
572
        return TRUE;
573
}
574
 
575
#endif
576
 
577
#ifdef L_makestring
578
 
579
/*
580
 * Make a NULL-terminated string out of an argc, argv pair.
581
 * Returns TRUE if successful, or FALSE if the string is too long,
582
 * with an error message given.  This does not handle spaces within
583
 * arguments correctly.
584
 */
585
BOOL
586
makestring(argc, argv, buf, buflen)
587
        char    **argv;
588
        char    *buf;
589
{
590
        int     len;
591
 
592
        while (argc-- > 0) {
593
                len = strlen(*argv);
594
                if (len >= buflen) {
595
                        fprintf(stderr, "Argument string too long\n");
596
                        return FALSE;
597
                }
598
 
599
                strcpy(buf, *argv++);
600
 
601
                buf += len;
602
                buflen -= len;
603
 
604
                if (argc)
605
                        *buf++ = ' ';
606
                buflen--;
607
        }
608
 
609
        *buf = '\0';
610
 
611
        return TRUE;
612
}
613
 
614
#endif
615
 
616
#ifdef L_chunks
617
 
618
typedef struct  chunk   CHUNK;
619
#define CHUNKINITSIZE   4
620
struct  chunk   {
621
        CHUNK   *next;
622
        char    data[CHUNKINITSIZE];    /* actually of varying length */
623
};
624
 
625
 
626
static  CHUNK * chunklist;
627
 
628
 
629
/*
630
 * Allocate a chunk of memory (like malloc).
631
 * The difference, though, is that the memory allocated is put on a
632
 * list of chunks which can be freed all at one time.  You CAN NOT free
633
 * an individual chunk.
634
 */
635
char *
636
getchunk(size)
637
{
638
        CHUNK   *chunk;
639
 
640
        if (size < CHUNKINITSIZE)
641
                size = CHUNKINITSIZE;
642
 
643
        chunk = (CHUNK *) malloc(size + sizeof(CHUNK) - CHUNKINITSIZE);
644
        if (chunk == NULL)
645
                return NULL;
646
 
647
        chunk->next = chunklist;
648
        chunklist = chunk;
649
 
650
        return chunk->data;
651
}
652
 
653
 
654
/*
655
 * Free all chunks of memory that had been allocated since the last
656
 * call to this routine.
657
 */
658
void
659
freechunks()
660
{
661
        CHUNK   *chunk;
662
 
663
        while (chunklist) {
664
                chunk = chunklist;
665
                chunklist = chunk->next;
666
                free((char *) chunk);
667
        }
668
}
669
 
670
#endif
671
 
672
 
673
#ifdef L_expandenvvar
674
 
675
/* Expand environment variables
676
 * Variable names must use a-z, A-Z, 0-9, or _
677
 * Backslashes are also interpreted to preserve the literal value of the
678
 * next character.
679
 * Returns NULL if there is an error, otherwise returns a pointer
680
 * to a static buffer containing the expand command line.
681
 */
682
char *
683
expandenvvar(cmd)
684
        char    *cmd;
685
{
686
        static char newcmd[CMDLEN+1];
687
        char* newp = newcmd;
688
        int freelength = CMDLEN;        /* Don't include final terminator */
689
        char varname[CMDLEN+1];
690
        char* varp;
691
        char* value;
692
        int valuelength;
693
 
694
        if (cmd == NULL) {
695
                return NULL;
696
        }
697
 
698
        if (strlen(cmd) > freelength) {
699
                fprintf(stderr, "Variable expansion too long\n");
700
                return NULL;
701
        }
702
 
703
        while (*cmd) {
704
                switch (*cmd) {
705
                case '\\':
706
                        if (freelength < 1) {
707
                                fprintf(stderr, "Variable expansion too long\n");
708
                                return NULL;
709
                        }
710
                        cmd++;
711
                        *newp++ = *cmd++;
712
                        freelength--;
713
                        break;
714
 
715
                case '$':
716
                        cmd++;
717
                        varp = varname;
718
                        while (isalnum(*cmd) || (*cmd == '_')) {
719
                                *varp++ = *cmd++;
720
                        }
721
                        *varp = '\0';
722
                        if ((*varname) && (value = getenv(varname))) {
723
                                valuelength = strlen(value);
724
                                if (valuelength > freelength) {
725
                                        fprintf(stderr, "Variable expansion too long\n");
726
                                        return NULL;
727
                                }
728
                                strncpy(newp, value, valuelength);
729
                                newp += valuelength;
730
                                freelength -= valuelength;
731
                        }
732
                        break;
733
 
734
                default:
735
                        if (freelength < 1) {
736
                                fprintf(stderr, "Variable expansion too long\n");
737
                                return NULL;
738
                        }
739
                        *newp++ = *cmd++;
740
                        freelength--;
741
                        break;
742
                }
743
        }
744
 
745
        *newp = '\0';
746
 
747
        return newcmd;
748
}
749
 
750
#endif
751
 
752
 
753
/* END CODE */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.