~burner/xsb/debianized-xsb

« back to all changes in this revision

Viewing changes to examples/XSB_calling_c/file_expand.c

  • Committer: Michael R. Head
  • Date: 2006-09-06 22:11:55 UTC
  • Revision ID: burner@n23-20060906221155-7e398d23438a7ee4
Add the files from the 3.0.1 release package

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <string.h>
 
3
#include <alloca.h>
 
4
#include <pwd.h>
 
5
#include "cinterf.h"
 
6
 
 
7
#define TRUE 1
 
8
/* 
 
9
 * Expands the initial ~ of a Unix filename and returns the absolute 
 
10
 * file name.  Otherwise it returns the file name unchanged.
 
11
 */
 
12
 
 
13
DllExport int call_conv expand_file()
 
14
{
 
15
   unsigned char *file_name;
 
16
   unsigned char *expanded_file_name;
 
17
 
 
18
   int tlen, lose;
 
19
   struct passwd *pw;
 
20
   register unsigned char *new_dir, *p, *user_name;
 
21
 
 
22
   file_name = (unsigned char *)ptoc_string(1);
 
23
 
 
24
   /* If file_name is absolute, flush ...// and detect /./ and /../.
 
25
      If no /./ or /../ we can return right away. */
 
26
 
 
27
   if (file_name[0] == '/')
 
28
   {
 
29
        p = file_name; lose = 0;
 
30
        while (*p)
 
31
        {
 
32
            if (p[0] == '/' && p[1] == '/')
 
33
                file_name = p + 1;
 
34
            if (p[0] == '/' && p[1] == '~')
 
35
                file_name = p + 1, lose = 1;
 
36
            if (p[0] == '/' && p[1] == '.'
 
37
                && (p[2] == '/' || p[2] == 0
 
38
                    || (p[2] == '.' && (p[3] == '/' || p[3] == 0))))
 
39
                lose = 1;
 
40
            p++;
 
41
        }
 
42
        if (!lose)
 
43
        {
 
44
            ctop_string(2, file_name);
 
45
            return TRUE;
 
46
        }
 
47
   }
 
48
 
 
49
   /* Now determine directory to start with and put it in new_dir */
 
50
 
 
51
   new_dir = 0;
 
52
 
 
53
   if (file_name[0] == '~' && file_name[1] == '/')      /* prefix  ~/ */
 
54
   {
 
55
        if (!(new_dir = (unsigned char *) getenv("HOME")))
 
56
            new_dir = (unsigned char *) "";
 
57
        file_name++;
 
58
   }
 
59
   else         /* prefix  ~username/ */
 
60
   {
 
61
        for (p = file_name; *p && (*p != '/'); p++);
 
62
             user_name = (unsigned char *) alloca(p - file_name + 1);
 
63
        bcopy ((char *) file_name, user_name, p - file_name);
 
64
        user_name[p - file_name] = 0;
 
65
 
 
66
        pw = (struct passwd *) getpwnam(user_name + 1);
 
67
        if (!pw)
 
68
        {
 
69
            fprintf(stderr, "++Error: \"%s\" is not a registered user\n", user_name + 1);
 
70
            ctop_string(2, file_name); /* return the input file name unchanged */
 
71
            return TRUE;
 
72
        }
 
73
 
 
74
        file_name = p;
 
75
        new_dir = (unsigned char *) pw -> pw_dir;
 
76
   }
 
77
 
 
78
   /* Now concatenate the directory and name to new space in the stack frame */
 
79
 
 
80
   tlen = (new_dir ? strlen(new_dir) + 1 : 0) + strlen(file_name) + 1;
 
81
   expanded_file_name = (unsigned char *) alloca(tlen);
 
82
   if (new_dir) strcpy(expanded_file_name, new_dir);
 
83
   strcat(expanded_file_name, file_name);
 
84
 
 
85
 
 
86
   /* Make sure you insert the newly created symbol into the symbol table. */
 
87
 
 
88
   ctop_string(2, (unsigned char *) string_find(expanded_file_name, 1));
 
89
 
 
90
   return TRUE;
 
91
}
 
92
 
 
93
 
 
94
 
 
95