home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / os2 / less / filename.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-27  |  7.0 KB  |  380 lines

  1. /*
  2.  * Routines to mess around with filenames (and files).
  3.  * Much of this is very OS dependent.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include "less.h"
  8.  
  9. extern char *getenv();
  10.  
  11. extern int force_open;
  12. extern IFILE curr_ifile;
  13. extern IFILE old_ifile;
  14.  
  15. /*
  16.  * Return the full pathname of the given file in the "home directory".
  17.  */
  18.     public char *
  19. homefile(filename)
  20.     char *filename;
  21. {
  22.     register char *pathname;
  23.     register char *homedir;
  24.  
  25.     homedir = getenv("HOME");
  26. #if __MSDOS__
  27.     /*
  28.      * Most MSDOS users do not have $HOME defined,
  29.      * so if no $HOME then look for "_less" anywhere
  30.      * on search path (always begins at current directory).
  31.      */
  32.     if (homedir == NULL)
  33.     {
  34.         extern char *searchpath();
  35.         pathname = searchpath(filename);
  36.         if (pathname == NULL)
  37.             return (NULL);
  38.         pathname = save(pathname);
  39.     } else
  40.     {
  41.         pathname = (char *) calloc(strlen(homedir)+strlen(filename)+2,
  42.                     sizeof(char));
  43.         if (pathname == NULL)
  44.             return (NULL);
  45.         sprintf(pathname, "%s\\%s", homedir, filename);
  46.     }
  47. #else
  48. #ifdef OS2
  49.         pathname = (char *) calloc(256, sizeof(char));
  50.     if (pathname == NULL)
  51.         return NULL;
  52.         _searchenv(filename, "INIT", pathname);
  53.         if ( pathname[0] == 0 )
  54.           _searchenv(filename, "PATH", pathname);
  55.         if ( pathname[0] == 0 )
  56.         {
  57.           free(pathname);
  58.           return NULL;
  59.         }
  60. #else
  61.     if (homedir == NULL)
  62.         return (NULL);
  63.     pathname = (char *) calloc(strlen(homedir)+strlen(filename)+2,
  64.                 sizeof(char));
  65.     if (pathname == NULL)
  66.         return (NULL);
  67.     sprintf(pathname, "%s/%s", homedir, filename);
  68. #endif
  69. #endif
  70.     return (pathname);
  71. }
  72.  
  73. /*
  74.  * Find out where the help file is.
  75.  */
  76.     public char *
  77. find_helpfile()
  78. {
  79.     register char *helpfile;
  80. #if __MSDOS__
  81.     extern char *searchpath();
  82.  
  83.     /*
  84.      * Look in current directory.
  85.      */
  86.     if (access(HELPFILE,0) == 0)
  87.             return (save(HELPFILE));
  88.     /*
  89.      * Find the basename of HELPFILE,
  90.      * and look for it in each directory in the search path.
  91.      */
  92.     if ((helpfile = strrchr(HELPFILE, '\\')) == NULL)
  93.         helpfile = HELPFILE;
  94.     else
  95.         helpfile++;
  96.     return (save(searchpath(helpfile)));
  97. #else
  98.     if ((helpfile = getenv("LESSHELP")) != NULL)
  99.         return (save(helpfile));
  100. #ifdef OS2
  101.     return (homefile(HELPFILE));
  102. #else
  103.     return (save(HELPFILE));
  104. #endif
  105. #endif
  106. }
  107.  
  108. /*
  109.  * Expand a string, substituting any "%" with the current filename,
  110.  * and any "#" with the previous filename.
  111.  */
  112.     public char *
  113. fexpand(s)
  114.     char *s;
  115. {
  116.     register char *fr, *to;
  117.     register int n;
  118.     register char *e;
  119.  
  120.     /*
  121.      * Make one pass to see how big a buffer we
  122.      * need to allocate for the expanded string.
  123.      */
  124.     n = 0;
  125.     for (fr = s;  *fr != '\0';  fr++)
  126.     {
  127.         switch (*fr)
  128.         {
  129.         case '%':
  130.             n += strlen(get_filename(curr_ifile));
  131.             break;
  132.         case '#':
  133.             if (old_ifile == NULL_IFILE)
  134.             {
  135.                 error("No previous file", NULL_PARG);
  136.                 return (NULL);
  137.             }
  138.             n += strlen(get_filename(old_ifile));
  139.             break;
  140.         default:
  141.             n++;
  142.             break;
  143.         }
  144.     }
  145.  
  146.     e = (char *) ecalloc(n+1, sizeof(char));
  147.  
  148.     /*
  149.      * Now copy the string, expanding any "%" or "#".
  150.      */
  151.     to = e;
  152.     for (fr = s;  *fr != '\0';  fr++)
  153.     {
  154.         switch (*fr)
  155.         {
  156.         case '%':
  157.             strcpy(to, get_filename(curr_ifile));
  158.             to += strlen(to);
  159.             break;
  160.         case '#':
  161.             strcpy(to, get_filename(old_ifile));
  162.             to += strlen(to);
  163.             break;
  164.         default:
  165.             *to++ = *fr;
  166.             break;
  167.         }
  168.     }
  169.     *to = '\0';
  170.     return (e);
  171. }
  172.  
  173. /*
  174.  * Try to determine if a file is "binary".
  175.  * This is just a guess, and we need not try too hard to make it accurate.
  176.  */
  177.     int
  178. bin_file(f)
  179.     int f;
  180. {
  181.     int i;
  182.     int n;
  183.     char data[64];
  184.  
  185.     n = read(f, data, sizeof(data));
  186.     for (i = 0;  i < n;  i++)
  187.         if (binary_char(data[i]))
  188.             return (1);
  189.     return (0);
  190. }
  191.  
  192. /*
  193.  * Try to determine the size of a file by seeking to the end.
  194.  */
  195.     static POSITION
  196. seek_filesize(f)
  197.     int f;
  198. {
  199.     offset_t spos;
  200.  
  201.     spos = lseek(f, (offset_t)0, 2);
  202.     if (spos == BAD_LSEEK)
  203.         return (NULL_POSITION);
  204.     return ((POSITION) spos);
  205. }
  206.  
  207. /*
  208.  * Expand a filename, substituting any environment variables, etc.
  209.  */
  210. #if GLOB
  211.  
  212. FILE *popen();
  213.  
  214.     public char *
  215. glob(filename)
  216.     char *filename;
  217. {
  218.     FILE *f;
  219.     char *p;
  220.     int ch;
  221.     int len;
  222.     char *cmd;
  223.     char *gfilename;
  224.  
  225.     filename = fexpand(filename);
  226.     if (filename == NULL)
  227.         return (NULL);
  228.  
  229.     /*
  230.      * We get the shell to expand the filename for us by passing
  231.      * an "echo" command to the shell and reading its output.
  232.      */
  233.     p = getenv("SHELL");
  234.     if (p == NULL || *p == '\0')
  235.     {
  236.         /*
  237.          * Read the output of <echo filename>.
  238.          */
  239.         cmd = (char *) ecalloc(strlen(filename)+6, sizeof(char));
  240.         sprintf(cmd, "echo %s", filename);
  241.     } else
  242.     {
  243.         /*
  244.          * Read the output of <$SHELL -c "echo filename">.
  245.          */
  246.         cmd = (char *) ecalloc(strlen(p)+strlen(filename)+12, sizeof(char));
  247.         sprintf(cmd, "%s -c \"echo %s\"", p, filename);
  248.     }
  249.  
  250.     f = popen(cmd, "r");
  251.     free(cmd);
  252.     if (f == NULL)
  253.         return (filename);
  254.     free(filename);
  255.  
  256.     len = 100;
  257.     gfilename = (char *) ecalloc(len, sizeof(char));
  258.     for (p = gfilename;  ;  p++)
  259.     {
  260.         if ((ch = getc(f)) == '\n' || ch == EOF)
  261.             break;
  262.         if (p - gfilename >= len-1)
  263.         {
  264.             len *= 2;
  265.             *p = '\0';
  266.             p = (char *) ecalloc(len, sizeof(char));
  267.             strcpy(p, gfilename);
  268.             free(gfilename);
  269.             gfilename = p;
  270.             p = gfilename + strlen(gfilename);
  271.         }
  272.         *p = ch;
  273.     }
  274.     *p = '\0';
  275.     pclose(f);
  276.     if (*gfilename == '\0')
  277.         return (NULL);
  278.     return (gfilename);
  279. }
  280.  
  281. #else
  282.  
  283.     public char *
  284. glob(filename)
  285.     char *filename;
  286. {
  287.     return (fexpand(filename));
  288. }
  289.  
  290. #endif
  291.  
  292.  
  293. #if STAT
  294.  
  295. #include <sys/types.h>
  296. #include <sys/stat.h>
  297.  
  298. /*
  299.  * Returns NULL if the file can be opened and
  300.  * is an ordinary file, otherwise an error message
  301.  * (if it cannot be opened or is a directory, etc.)
  302.  */
  303.     public char *
  304. bad_file(filename)
  305.     char *filename;
  306. {
  307.     register char *m;
  308.     struct stat statbuf;
  309.  
  310.     if (stat(filename, &statbuf) < 0)
  311.         return (errno_message(filename));
  312.  
  313.     if (force_open)
  314.         return (NULL);
  315.  
  316.     if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
  317.     {
  318.         static char is_dir[] = " is a directory";
  319.         m = (char *) ecalloc(strlen(filename) + sizeof(is_dir),
  320.             sizeof(char));
  321.         strcpy(m, filename);
  322.         strcat(m, is_dir);
  323.         return (m);
  324.     }
  325.     if ((statbuf.st_mode & S_IFMT) != S_IFREG)
  326.     {
  327.         static char not_reg[] = " is not a regular file";
  328.         m = (char *) ecalloc(strlen(filename) + sizeof(not_reg),
  329.             sizeof(char));
  330.         strcpy(m, filename);
  331.         strcat(m, not_reg);
  332.         return (m);
  333.     }
  334.  
  335.     return (NULL);
  336. }
  337.  
  338. /*
  339.  * Return the size of a file, as cheaply as possible.
  340.  * In Unix, we can stat the file.
  341.  */
  342.     public POSITION
  343. filesize(f)
  344.     int f;
  345. {
  346.     struct stat statbuf;
  347.  
  348.     if (fstat(f, &statbuf) < 0)
  349.         /*
  350.          * Can't stat; try seeking to the end.
  351.          */
  352.         return (seek_filesize(f));
  353.  
  354.     return ((POSITION) statbuf.st_size);
  355. }
  356.  
  357. #else
  358.  
  359. /*
  360.  * If we have no way to find out, just say the file is good.
  361.  */
  362.     public char *
  363. bad_file(filename)
  364.     char *filename;
  365. {
  366.     return (NULL);
  367. }
  368.  
  369. /*
  370.  * We can find the file size by seeking.
  371.  */
  372.     public POSITION
  373. filesize(f)
  374.     int f;
  375. {
  376.     return (seek_filesize(f));
  377. }
  378.  
  379. #endif
  380.