file_expand.c

00001 #include <stdio.h>
00002 #include <string.h>
00003 #include <alloca.h>
00004 #include <pwd.h>
00005 #include "cinterf.h"
00006 
00007 #define TRUE 1
00008 /* 
00009  * Expands the initial ~ of a Unix filename and returns the absolute 
00010  * file name.  Otherwise it returns the file name unchanged.
00011  */
00012 
00013 DllExport int call_conv expand_file()
00014 {
00015    unsigned char *file_name;
00016    unsigned char *expanded_file_name;
00017 
00018    int tlen, lose;
00019    struct passwd *pw;
00020    register unsigned char *new_dir, *p, *user_name;
00021 
00022    file_name = (unsigned char *)ptoc_string(1);
00023 
00024    /* If file_name is absolute, flush ...// and detect /./ and /../.
00025       If no /./ or /../ we can return right away. */
00026 
00027    if (file_name[0] == '/')
00028    {
00029         p = file_name; lose = 0;
00030         while (*p)
00031         {
00032             if (p[0] == '/' && p[1] == '/')
00033                 file_name = p + 1;
00034             if (p[0] == '/' && p[1] == '~')
00035                 file_name = p + 1, lose = 1;
00036             if (p[0] == '/' && p[1] == '.'
00037                 && (p[2] == '/' || p[2] == 0
00038                     || (p[2] == '.' && (p[3] == '/' || p[3] == 0))))
00039                 lose = 1;
00040             p++;
00041         }
00042         if (!lose)
00043         {
00044             ctop_string(2, file_name);
00045             return TRUE;
00046         }
00047    }
00048 
00049    /* Now determine directory to start with and put it in new_dir */
00050 
00051    new_dir = 0;
00052 
00053    if (file_name[0] == '~' && file_name[1] == '/')      /* prefix  ~/ */
00054    {
00055         if (!(new_dir = (unsigned char *) getenv("HOME")))
00056             new_dir = (unsigned char *) "";
00057         file_name++;
00058    }
00059    else         /* prefix  ~username/ */
00060    {
00061         for (p = file_name; *p && (*p != '/'); p++);
00062              user_name = (unsigned char *) alloca(p - file_name + 1);
00063         bcopy ((char *) file_name, user_name, p - file_name);
00064         user_name[p - file_name] = 0;
00065 
00066         pw = (struct passwd *) getpwnam(user_name + 1);
00067         if (!pw)
00068         {
00069             fprintf(stderr, "++Error: \"%s\" is not a registered user\n", user_name + 1);
00070             ctop_string(2, file_name); /* return the input file name unchanged */
00071             return TRUE;
00072         }
00073  
00074         file_name = p;
00075         new_dir = (unsigned char *) pw -> pw_dir;
00076    }
00077 
00078    /* Now concatenate the directory and name to new space in the stack frame */
00079 
00080    tlen = (new_dir ? strlen(new_dir) + 1 : 0) + strlen(file_name) + 1;
00081    expanded_file_name = (unsigned char *) alloca(tlen);
00082    if (new_dir) strcpy(expanded_file_name, new_dir);
00083    strcat(expanded_file_name, file_name);
00084 
00085 
00086    /* Make sure you insert the newly created symbol into the symbol table. */
00087 
00088    ctop_string(2, (unsigned char *) string_find(expanded_file_name, 1));
00089 
00090    return TRUE;
00091 }
00092 
00093 
00094 
00095 

Generated on Wed Jul 26 13:30:43 2006 for XSB by  doxygen 1.4.5