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