home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / amiga / vim46src.lha / vim-4.6 / src / archie.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-11  |  14.3 KB  |  825 lines

  1. /* vi:set ts=4 sw=4:
  2.  *
  3.  *
  4.  * VIM - Vi IMproved
  5.  *
  6.  * Code Contributions By:    Bram Moolenaar            mool@plex.nl
  7.  *                            Tim Thompson            twitch!tjt
  8.  *                            Tony Andrews            onecom!wldrdg!tony 
  9.  *                            G. R. (Fred) Walter        watmath!watcgl!grwalter 
  10.  */
  11. /*
  12.  * archie.c -- RISC OS + UnixLib specific code.
  13.  *
  14.  * A lot of this file was written by Juergen Weigert.
  15.  *
  16.  * It was then hacked to pieces by Alun Jones to work on the Acorn
  17.  * Archimedes!
  18.  */
  19.  
  20. #include "vim.h"
  21. #include "globals.h"
  22. #include "option.h"
  23. #include "proto.h"
  24.  
  25. #ifdef HAVE_FCNTL_H
  26. # include <fcntl.h>
  27. #endif
  28. #include <time.h>
  29. #include <unistd.h>
  30. #include <sys/types.h>
  31. #include <sys/os.h>
  32. #include <signal.h>
  33.  
  34. #include <termio.h>
  35.  
  36. static int    Read __ARGS((char *, long));
  37. static int    WaitForChar __ARGS((long));
  38. static int    RealWaitForChar __ARGS((long));
  39. static void fill_inbuf __ARGS((void));
  40. static int    have_wildcard __ARGS((int, char **));
  41.  
  42. static int do_resize = FALSE;
  43.  
  44. /* I'm sure this should be defined in UnixLib, but it ain't!
  45.  */
  46. short ospeed;
  47.  
  48.     void
  49. mch_write(s, len)
  50.     char    *s;
  51.     int        len;
  52. {
  53.     int i;
  54.     for (i=0; i<len; i++)
  55.     {
  56.         os_vdu(s[i]);
  57.     }
  58. }
  59.  
  60. /*
  61.  * mch_inchar(): low level input funcion.
  62.  * Get a characters from the keyboard.
  63.  * If time == 0 do not wait for characters.
  64.  * If time == n wait a short time for characters.
  65.  * If time == -1 wait forever for characters.
  66.  */
  67.     int
  68. mch_inchar(buf, maxlen, time)
  69.     char    *buf;
  70.     int        maxlen;
  71.     long    time;
  72. {
  73.     if (time >= 0)
  74.     {
  75.         if (WaitForChar(time) == 0)        /* no character available */
  76.             return 0;
  77.     }
  78.     else        /* time == -1 */
  79.     {
  80.     /*
  81.      * If there is no character available within 2 seconds (default)
  82.      * write the autoscript file to disk
  83.      */
  84.         if (WaitForChar(p_ut) == 0)
  85.             updatescript(0);
  86.     }
  87.  
  88.     WaitForChar(-1L);
  89.     return Read(buf, (long)maxlen);
  90. }
  91.  
  92.     void
  93. mch_delay(msec, ignoreinput)
  94.     long    msec;
  95.     int        ignoreinput;
  96. {
  97.     clock_t    now;
  98.  
  99.     if (ignoreinput)
  100.     {
  101.         now = clock();
  102.         while (clock() < now + (msec * CLOCKS_PER_SEC) / 1000)
  103.             ;
  104.     }
  105.     else
  106.         WaitForChar(msec);
  107. }
  108.  
  109. /*
  110.  * No job control. Fake it by starting a new shell.
  111.  */
  112.     void
  113. mch_suspend()
  114. {
  115.     MSG_OUTSTR("new shell started\n");
  116.     call_shell(NULL, SHELL_COOKED);
  117.     need_check_timestamps = TRUE;
  118. }
  119.  
  120.     void
  121. mch_windinit()
  122. {
  123.     Columns = 80;
  124.     Rows = 24;
  125.  
  126.     flushbuf();
  127.  
  128.     mch_get_winsize();
  129. }
  130.  
  131. /*
  132.  * mch_check_win checks whether we have an interactive window.
  133.  */
  134.     int
  135. mch_check_win(argc, argv)
  136.     int argc;
  137.     char **argv;
  138. {
  139.     if (isatty(1))
  140.         return OK;
  141.     return FAIL;
  142. }
  143.  
  144. /*
  145.  * Return OK if the input comes from a terminal, FAIL otherwise.
  146.  */
  147.     int
  148. mch_check_input()
  149. {
  150.     if (isatty(0))
  151.         return OK;
  152.     return FAIL;
  153. }
  154.  
  155. /*
  156.  * fname_case(): Set the case of the filename, if it already exists.
  157.  *                 This will cause the filename to remain exactly the same.
  158.  */
  159.     void
  160. fname_case(name)
  161.     char *name;
  162. {
  163. }
  164.  
  165.     void
  166. mch_settitle(str)
  167.     char *str;
  168. {
  169. }
  170.  
  171.     void
  172. mch_resettitle()
  173. {
  174. }
  175.  
  176.     int
  177. mch_can_restore_title()
  178. {
  179.     return FALSE;
  180. }
  181.  
  182.     int
  183. mch_can_restore_icon()
  184. {
  185.     return FALSE;
  186. }
  187.  
  188. /*
  189.  * Insert user name in s[len].
  190.  */
  191.     int
  192. mch_get_user_name(s, len)
  193.     char_u    *s;
  194.     int        len;
  195. {
  196.     *s = NUL;
  197.     return FAIL;
  198. }
  199.  
  200. /*
  201.  * Insert host name is s[len].
  202.  */
  203.     void
  204. mch_get_host_name(s, len)
  205.     char_u    *s;
  206.     int        len;
  207. {
  208.     STRNCPY(s, "Archimedes", len);
  209. }
  210.  
  211. /*
  212.  * return process ID
  213.  */
  214.     long
  215. mch_get_pid()
  216. {
  217.     return (long)0;
  218. }
  219.  
  220. /*
  221.  * Get name of current directory into buffer 'buf' of length 'len' bytes.
  222.  * Return non-zero for success.
  223.  */
  224.     int 
  225. mch_dirname(buf, len)
  226.     char *buf;
  227.     int len;
  228. {
  229.     extern int        errno;
  230.     extern char        *sys_errlist[];
  231.  
  232.     if (getcwd(buf,len) == NULL)
  233.     {
  234.         strcpy(buf, sys_errlist[errno]);
  235.         return 0;
  236.     }
  237.     return 1;
  238. }
  239.  
  240. /*
  241.  * get absolute filename into buffer 'buf' of length 'len' bytes
  242.  */
  243.     int 
  244. FullName(fname, buf, len, force)
  245.     char *fname, *buf;
  246.     int len;
  247.     int force;
  248. {
  249.     int        l;
  250.     char    olddir[MAXPATHL];
  251.     char    *p;
  252.     int        c;
  253.     int        retval = 1;
  254.  
  255.     if (fname == NULL)    /* always fail */
  256.         return 0;
  257.  
  258.     *buf = 0;
  259.     if (force || *fname != '/')
  260.     {
  261.         /*
  262.          * If the file name has a path, change to that directory for a moment,
  263.          * and then do the getwd() (and get back to where we were).
  264.          * This will get the correct path name with "../" things.
  265.          */
  266.         if ((p = vim_strrchr((char_u *)fname, '/')) != NULL)
  267.         {
  268.             if (getcwd(olddir, MAXPATHL) == NULL)
  269.             {
  270.                 p = NULL;        /* can't get current dir: don't chdir */
  271.                 retval = 0;
  272.             }
  273.             else
  274.             {
  275.                 c = *p;
  276.                 *p = NUL;
  277.                 vim_chdir("\\");        /* Try to maintain PSD */
  278.                 if (vim_chdir(fname))
  279.                     retval = 0;
  280.                 else
  281.                     fname = p + 1;
  282.                 *p = c;
  283.             }
  284.         }
  285.         if (getcwd(buf, len) == NULL)
  286.         {
  287.             retval = 0;
  288.             *buf = NUL;
  289.         }
  290.         l = strlen(buf);
  291.         if (l && buf[l - 1] != '/')
  292.             strcat(buf, "/");
  293.         if (p)
  294.         {
  295.             vim_chdir("\\");            /* Maintain PSD */
  296.             vim_chdir(olddir);
  297.         }
  298.     }
  299.     strcat(buf, fname);
  300.     return retval;
  301. }
  302.  
  303. /*
  304.  * get file permissions for 'name'
  305.  */
  306.     long 
  307. getperm(name)
  308.     char *name;
  309. {
  310.     struct stat statb;
  311.  
  312.     if (stat(name, &statb))
  313.         return -1;
  314.     return statb.st_mode;
  315. }
  316.  
  317. /*
  318.  * set file permission for 'name' to 'perm'
  319.  */
  320.     int
  321. setperm(name, perm)
  322.     char *name;
  323.     int perm;
  324. {
  325.     return chmod(name, perm);
  326. }
  327.  
  328. /*
  329.  * return FALSE if "name" is not a directory
  330.  * return TRUE if "name" is a directory.
  331.  * return FALSE for error.
  332.  */
  333.     int 
  334. mch_isdir(name)
  335.     char *name;
  336. {
  337.     struct stat statb;
  338.  
  339.     if (stat(name, &statb))
  340.         return FALSE;
  341.     return ((statb.st_mode & S_IFMT) == S_IFDIR) ? TRUE : FALSE;
  342. }
  343.  
  344.     void
  345. mch_windexit(r)
  346.     int r;
  347. {
  348.     settmode(0);
  349.     stoptermcap();
  350.     outchar('\r');
  351.     outchar('\n');
  352.     flushbuf();
  353.     ml_close_all(TRUE);             /* remove all memfiles */
  354.     exit(r);
  355. }
  356.  
  357.     void
  358. mch_settmode(raw)
  359.     int                raw;
  360. {
  361.     static    int old225, old226, old4;
  362.     int        retvals[3];
  363.     static struct termio told;
  364.            struct termio tnew;
  365.  
  366.     if (raw)
  367.     {
  368.         /* Make arrow keys act as function keys.
  369.          */
  370.         os_byte(4, 2, 0, retvals);
  371.         old4 = retvals[1];
  372.         /* Now make function keys return NULL followed by a character.
  373.          * Remember the old value for resetting.
  374.          */
  375.         os_byte(225, 0xC0, 0, retvals);
  376.         old225 = retvals[1];
  377.         os_byte(226, 0xD0, 0, retvals);
  378.         old226 = retvals[1];
  379.  
  380.         ioctl(0, TCGETA, &told);
  381.         tnew = told;
  382.         tnew.c_iflag &= ~(ICRNL | IXON);        /* ICRNL enables typing ^V^M */
  383.                                                 /* IXON enables typing ^S/^Q */
  384.         tnew.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOE);
  385.         tnew.c_cc[VMIN] = 1;            /* return after 1 char */
  386.         tnew.c_cc[VTIME] = 0;            /* don't wait */
  387.         ioctl(0, TCSETA, &tnew);
  388.     }
  389.     else
  390.     {
  391.         os_byte(4, old4, 0, retvals);
  392.         os_byte(225, old225, 0, retvals);
  393.         os_byte(226, old226, 0, retvals);
  394.         ioctl(0, TCSETA, &told);
  395.     }
  396. }
  397.  
  398. /*
  399.  * Try to get the current window size:
  400.  * 1. with an ioctl(), most accurate method
  401.  * 2. from the environment variables LINES and COLUMNS
  402.  * 3. from the termcap
  403.  * 4. keep using the old values
  404.  */
  405.     int
  406. mch_get_winsize()
  407. {
  408.     int            old_Rows = Rows;
  409.     int            old_Columns = Columns;
  410.     char        *p;
  411.  
  412.     Columns = 0;
  413.     Rows = 0;
  414.  
  415. /*
  416.  * 1. try using an ioctl. It is the most accurate method.
  417.  */
  418.     {
  419.         struct winsize    ws;
  420.  
  421.         if (ioctl(0, TIOCGWINSZ, &ws) == 0)
  422.         {
  423.             Columns = ws.ws_col;
  424.             Rows = ws.ws_row;
  425.         }
  426.     }
  427.  
  428. /*
  429.  * 2. get size from environment
  430.  */
  431.     if (Columns == 0 || Rows == 0)
  432.     {
  433.         if ((p = (char *)getenv("LINES")))
  434.             Rows = atoi(p);
  435.         if ((p = (char *)getenv("COLUMNS")))
  436.             Columns = atoi(p);
  437.     }
  438.  
  439. /*
  440.  * 3. try reading the termcap
  441.  */
  442.     if (Columns == 0 || Rows == 0)
  443.     {
  444.         extern void getlinecol();
  445.  
  446.         getlinecol();    /* get "co" and "li" entries from termcap */
  447.     }
  448.  
  449. /*
  450.  * 4. If everything fails, use the old values
  451.  */
  452.     if (Columns <= 0 || Rows <= 0)
  453.     {
  454.         Columns = old_Columns;
  455.         Rows = old_Rows;
  456.         return 1;
  457.     }
  458.     debug2("mch_get_winsize: %dx%d\n", (int)Columns, (int)Rows);
  459.  
  460.     Rows_max = Rows;                /* remember physical max height */
  461.  
  462.     check_winsize();
  463.     script_winsize();
  464.  
  465. /* if size changed: screenalloc will allocate new screen buffers */
  466.     return (0);
  467. }
  468.  
  469.     void
  470. mch_set_winsize()
  471. {
  472.     /* should try to set the window size to Rows and Columns */
  473. }
  474.  
  475.     int 
  476. call_shell(cmd, options)
  477.     char    *cmd;
  478.     int        options;        /* SHELL_FILTER if called by do_filter() */
  479.                             /* SHELL_COOKED if term needs cooked mode */
  480.                             /* SHELL_EXPAND if called by ExpandWildCards() */
  481. {
  482.     int        x;
  483.     char    newcmd[1024];
  484.  
  485.     flushbuf();
  486.  
  487.     if (options & SHELL_COOKED)
  488.         settmode(0);                 /* set to cooked mode */
  489.  
  490.     if (cmd == NULL)
  491.         x = system(p_sh);
  492.     else
  493.     {
  494.         sprintf(newcmd, "*%s", cmd);
  495.         x = system(newcmd);
  496.     }
  497.     if (x == 127)
  498.     {
  499.         emsg("Cannot execute shell sh");
  500.         msg_outchar('\n');
  501.     }
  502.     else if (x)
  503.     {
  504.         smsg("%d returned", x);
  505.         msg_outchar('\n');
  506.     }
  507.  
  508.     settmode(1);                         /* set to raw mode */
  509.     return (x ? FAIL : OK);
  510. }
  511.  
  512. /*
  513.  * The input characters are buffered to be able to check for a CTRL-C.
  514.  * This should be done with signals, but I don't know how to do that in
  515.  * a portable way for a tty in RAW mode.
  516.  */
  517.  
  518. #define INBUFLEN 50
  519. static unsigned char        inbuf[INBUFLEN];    /* internal typeahead buffer */
  520. static int                    inbufcount = 0;        /* number of chars in inbuf[] */
  521.  
  522.     static int
  523. Read(buf, maxlen)
  524.     char    *buf;
  525.     long    maxlen;
  526. {
  527.     if (inbufcount == 0)        /* if the buffer is empty, fill it */
  528.         fill_inbuf();
  529.     if (maxlen > inbufcount)
  530.         maxlen = inbufcount;
  531.     vim_memmove(buf, inbuf, (size_t)maxlen);
  532.     inbufcount -= maxlen;
  533.     if (inbufcount)
  534.         vim_memmove(inbuf, inbuf + maxlen, (size_t)inbufcount);
  535.     return (int)maxlen;
  536. }
  537.  
  538. /*
  539.  * check for CTRL-C typed by reading all available characters
  540.  */
  541.     void
  542. mch_breakcheck()
  543. {
  544.     if (RealWaitForChar(0L))        /* if characters available */
  545.         fill_inbuf();
  546. }
  547.  
  548.     static void
  549. fill_inbuf()
  550. {
  551.     int        len;
  552.  
  553.     if (inbufcount >= INBUFLEN)        /* buffer full */
  554.         return;
  555.  
  556.     for (len=0; len < INBUFLEN-inbufcount; len++)
  557.     {
  558.         int key;
  559.  
  560.         key = os_inkey(0);
  561.         if (key==-1)
  562.         {
  563.             break;
  564.         }
  565.         inbuf[inbufcount+len] = key;
  566.     }
  567.  
  568.     while (len-- > 0)
  569.     {
  570.         /*
  571.          * if a CTRL-C was typed, remove it from the buffer and set got_int
  572.          */
  573.         if (inbuf[inbufcount] == 3)
  574.         {
  575.             /* remove everything typed before the CTRL-C */
  576.             vim_memmove(inbuf, inbuf + inbufcount, (size_t)(len + 1));
  577.             inbufcount = 0;
  578.             got_int = TRUE;
  579.         }
  580.         ++inbufcount;
  581.     }
  582. }
  583.  
  584. /* 
  585.  * Wait "ticks" until a character is available from the keyboard or from inbuf[]
  586.  * ticks = -1 will block forever
  587.  */
  588.  
  589.     static int
  590. WaitForChar(ticks)
  591.     long ticks;
  592. {
  593.     if (inbufcount)        /* something in inbuf[] */
  594.         return 1;
  595.     return RealWaitForChar(ticks);
  596. }
  597.  
  598. /* 
  599.  * Wait "ticks" until a character is available from the keyboard
  600.  * ticks = -1 will block forever
  601.  */
  602.     static int
  603. RealWaitForChar(ticks)
  604.     long ticks;
  605. {
  606.     int    key;
  607.  
  608.     if (ticks == -1)
  609.     {
  610.         key = os_get();
  611.     }
  612.     else
  613.     {
  614.         key = os_inkey((int)(ticks/10));
  615.     }
  616. debug3("RWFC(%ld) got %d (%c)\n", ticks, key, key);
  617.     
  618.     if (key != -1)
  619.     {
  620.         /* Unfortunately the key has now been taken from the
  621.          * buffer, so we need to put it in outselves. It's a 
  622.          * shame, but the other way I can think of involves a
  623.          * keyboard scan, and this would return for SHIFT, etc.
  624.          */
  625.          if (inbufcount < INBUFLEN)
  626.          {
  627.              inbuf[inbufcount++] = key;
  628.         }
  629.     }
  630.     return (key != -1);
  631. }
  632.  
  633. /*
  634.  * ExpandWildCards() - this code does wild-card pattern matching using the shell
  635.  *
  636.  * Mool: return 0 for success, 1 for error (you may loose some memory) and
  637.  *       put an error message in *file.
  638.  *
  639.  * num_pat is number of input patterns
  640.  * pat is array of pointers to input patterns
  641.  * num_file is pointer to number of matched file names
  642.  * file is pointer to array of pointers to matched file names
  643.  * On Unix we do not check for files only yet
  644.  * list_notfound is ignored
  645.  */
  646.  
  647. #ifndef SEEK_SET
  648. # define SEEK_SET 0
  649. #endif
  650. #ifndef SEEK_END
  651. # define SEEK_END 2
  652. #endif
  653.  
  654.     int
  655. ExpandWildCards(num_pat, pat, num_file, file, files_only, list_notfound)
  656.     int             num_pat;
  657.     char          **pat;
  658.     int            *num_file;
  659.     char         ***file;
  660.     int                files_only;
  661.     int                list_notfound;
  662. {
  663.     char_u    *tempname;
  664.     char    *command;
  665.     int        i;
  666.     int        dir;
  667.     size_t    len;
  668.     FILE    *fd;
  669.     char    *buffer;
  670.     char    *p;
  671.  
  672.     *num_file = 0;        /* default: no files found */
  673.     *file = (char **)"";
  674.  
  675.     /*
  676.      * If there are no wildcards, just copy the names to allocated memory.
  677.      * Saves a lot of time, because we don't have to run glob.
  678.      */
  679.     if (!have_wildcard(num_pat, pat))
  680.     {
  681.         *file = (char **)alloc(num_pat * sizeof(char *));
  682.         if (*file == NULL)
  683.         {
  684.             *file = (char **)"";
  685.             return 1;
  686.         }
  687.         for (i = 0; i < num_pat; i++)
  688.             (*file)[i] = strsave(pat[i]);
  689.         *num_file = num_pat;
  690.         return 0;
  691.     }
  692.  
  693. /*
  694.  * get a name for the temp file
  695.  */
  696.     if ((tempname = vim_tempname('o')) == NULL)
  697.     {
  698.         emsg(e_notmp);
  699.         return 1;
  700.     }
  701.  
  702.     len = STRLEN(tempname) + 11;
  703.     for (i = 0; i < num_pat; ++i)        /* count the length of the patterns */
  704.         len += strlen(pat[i]) + 1;
  705.     command = (char *)alloc(len);
  706.     if (command == NULL)
  707.     {
  708.         vim_free(tempname);
  709.         return 1;
  710.     }
  711.     strcpy(command, "glob >");            /* built the shell command */
  712.     strcat(command, (char *)tempname);
  713.     for (i = 0; i < num_pat; ++i)
  714.     {
  715.         strcat(command, " ");
  716.         strcat(command, pat[i]);
  717.     }
  718.     i = call_shell(command, SHELL_EXPAND);    /* execute it */
  719.     vim_free(command);
  720.     if (i)                                    /* call_shell failed */
  721.     {
  722.         vim_remove(tempname);
  723.         vim_free(tempname);
  724.         mch_delay(1000L, TRUE);                /* give the user a chance to read
  725.                                                error messages */
  726.         must_redraw = CLEAR;                /* probably messed up screen */
  727.         return 1;
  728.     }
  729.  
  730. /*
  731.  * read the names from the file into memory
  732.  */
  733.      fd = fopen((char *)tempname, "r");
  734.     if (fd == NULL)
  735.     {
  736.         vim_free(tempname);
  737.         emsg(e_notopen);
  738.         return 1;
  739.     }
  740.  
  741.     fseek(fd, 0L, SEEK_END);
  742.     len = ftell(fd);                /* get size of temp file */
  743.     fseek(fd, 0L, SEEK_SET);
  744.     buffer = (char *)alloc(len + 1);
  745.     if (buffer == NULL)
  746.     {
  747.         vim_remove(tempname);
  748.         vim_free(tempname);
  749.         fclose(fd);
  750.         return 1;
  751.     }
  752.     i = fread(buffer, 1, len, fd);
  753.     fclose(fd);
  754.     vim_remove(tempname);
  755.     vim_free(tempname);
  756.     if (i != len)
  757.     {
  758.         emsg(e_notread);
  759.         vim_free(buffer);
  760.         return 1;
  761.     }
  762.  
  763.     buffer[len] = NUL;                    /* make sure the buffers ends in NUL */
  764.     i = 0;
  765.     for (p = buffer; p < buffer + len; ++p)
  766.         if (*p == NUL)                    /* count entry */
  767.             ++i;
  768.     if (len)
  769.         ++i;                            /* count last entry */
  770.  
  771.     *num_file = i;
  772.     *file = (char **)alloc(sizeof(char *) * i);
  773.     if (*file == NULL)
  774.     {
  775.         vim_free(buffer);
  776.         *file = (char **)"";
  777.         return 1;
  778.     }
  779.     p = buffer;
  780.  
  781.     for (i = 0; i < *num_file; ++i)
  782.     {
  783.         (*file)[i] = p;
  784.         while (*p && p < buffer + len)        /* skip entry */
  785.             ++p;
  786.         ++p;                                /* skip NUL */
  787.     }
  788.     for (i = 0; i < *num_file; ++i)
  789.     {
  790.         dir = (mch_isdir((*file)[i]));
  791.         if (dir < 0)            /* if file doesn't exist don't add '.' */
  792.             dir = 0;
  793.         p = alloc((unsigned)(strlen((*file)[i]) + 1 + dir));
  794.         if (p)
  795.         {
  796.             strcpy(p, (*file)[i]);
  797.             if (dir)
  798.                 strcat(p, ".");
  799.         }
  800.         (*file)[i] = p;
  801.     }
  802.     vim_free(buffer);
  803.     return 0;
  804. }
  805.  
  806.     int
  807. mch_has_wildcard(p)
  808.     char *p;
  809. {
  810.     return strpbrk(p, "*#") != NULL;
  811. }
  812.  
  813.     static int
  814. have_wildcard(num, file)
  815.     int        num;
  816.     char    **file;
  817. {
  818.     register int i;
  819.  
  820.     for (i = 0; i < num; i++)
  821.         if (mch_has_wildcard(file[i]))
  822.             return 1;
  823.     return 0;
  824. }
  825.