home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / new / util / edit / jade / src / unix_misc.c < prev    next >
C/C++ Source or Header  |  1994-10-15  |  18KB  |  741 lines

  1. /* unix_misc.c -- Miscellaneous functions for Unix
  2.    Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
  3.  
  4.    This file is part of Jade.
  5.  
  6.    Jade is free software; you can redistribute it and/or modify it
  7.    under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    Jade is distributed in the hope that it will be useful, but
  12.    WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with Jade; see the file COPYING.    If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "jade.h"
  21. #include "jade_protos.h"
  22.  
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include <sys/stat.h>
  26. #include <time.h>
  27. #include <unistd.h>
  28. #include <fcntl.h>
  29. #include <dirent.h>
  30. #include <pwd.h>
  31. #include <netdb.h>
  32.  
  33. #ifdef HAVE_STRERROR
  34. # include <errno.h>
  35. #else
  36.   extern int sys_nerr, errno;
  37.   extern char *sys_errlist[];
  38. #endif
  39.  
  40. #ifdef ENVIRON_UNDEFINED
  41.   extern char **environ;
  42. #endif
  43.  
  44. _PR bool file_exists(u_char *);
  45. _PR u_long file_mod_time(u_char *);
  46. _PR void sys_misc_init(void);
  47.  
  48. _PR bool same_files(u_char *, u_char *);
  49. _PR u_char * file_part(u_char *);
  50. _PR VALUE lookup_errno(void);
  51. _PR void doconmsg(u_char *);
  52. _PR VALUE read_file(u_char *);
  53. _PR u_long sys_time(void);
  54. _PR int add_file_part(u_char *, const u_char *, int);
  55. _PR VALUE sys_expand_file_name(VALUE);
  56. _PR VALUE sys_fully_qualify_file_name(VALUE);
  57.  
  58. bool
  59. same_files(u_char *file1, u_char *file2)
  60. {
  61.     bool rc = FALSE;
  62.     struct stat stat1, stat2;
  63.     if(!stat(file1, &stat1))
  64.     {
  65.     if(!stat(file2, &stat2))
  66.     {
  67.         if((stat1.st_dev == stat2.st_dev)
  68.            && (stat1.st_ino == stat2.st_ino))
  69.         {
  70.         rc = TRUE;
  71.         }
  72.     }
  73.     }
  74.     else
  75.     rc = !strcmp(file1, file2);
  76.     return(rc);
  77. }
  78.  
  79. u_char *
  80. file_part(u_char *fname)
  81. {
  82.     u_char *tmp = strrchr(fname, '/');
  83.     if(tmp)
  84.     return(tmp + 1);
  85.     return(fname);
  86. }
  87.  
  88. VALUE
  89. lookup_errno(void)
  90. {
  91. #ifdef HAVE_STRERROR
  92.     return(string_dup(strerror(errno)));
  93. #else
  94.     if(errno >= sys_nerr)
  95.         return(string_dup(sys_errlist[errno]));
  96.     else
  97.         return(MKSTR("<error>"));
  98. #endif
  99. }
  100.  
  101. void
  102. doconmsg(u_char *msg)
  103. {
  104.     fputs(msg, stderr);
  105. }
  106.  
  107. VALUE
  108. read_file(u_char *fileName)
  109. {
  110.     FILE *fh = fopen(fileName, "r");
  111.     if(fh)
  112.     {
  113.     struct stat stat;
  114.     if(!fstat(fileno(fh), &stat))
  115.     {
  116.         VALUE mem = make_string(stat.st_size + 1);
  117.         if(mem)
  118.         {
  119.         fread(VSTR(mem), 1, stat.st_size, fh);
  120.         VSTR(mem)[stat.st_size] = 0;
  121.         fclose(fh);
  122.         return(mem);
  123.         }
  124.         else
  125.         mem_error();
  126.     }
  127.     fclose(fh);
  128.     }
  129.     return(cmd_signal(sym_file_error,
  130.               list_2(lookup_errno(), string_dup(fileName))));
  131. }
  132.  
  133. u_long
  134. sys_time(void)
  135. {
  136.     return(time(NULL));
  137. }
  138.  
  139. int
  140. add_file_part(u_char *buf, const u_char *part, int bufLen)
  141. {
  142.     int bufend = strlen(buf);
  143.     int partlen = strlen(part);
  144.     if((bufend > 0) && (buf[bufend-1] != '/') && (*part != '/'))
  145.     {
  146.     if(++bufend >= bufLen)
  147.         return(FALSE);
  148.     buf[bufend-1] = '/';
  149.     buf[bufend] = 0;
  150.     }
  151.     if((bufend + partlen) >= bufLen)
  152.     return(FALSE);
  153.     strcpy(buf + bufend, part);
  154.     return(TRUE);
  155. }
  156.  
  157. _PR VALUE cmd_delete_file(VALUE file);
  158. DEFUN_INT("delete-file", cmd_delete_file, subr_delete_file, (VALUE file), V_Subr1, DOC_delete_file, "fDelete file:") /*
  159. ::doc:delete_file::
  160. delete-file FILE-NAME
  161.  
  162. Attempts to delete the file called FILE-NAME.
  163. ::end:: */
  164. {
  165.     DECLARE1(file, STRINGP);
  166.     if(!unlink(VSTR(file)))
  167.     return(sym_t);
  168.     return(signal_file_error(file));
  169. }
  170.  
  171. _PR VALUE cmd_rename_file(VALUE src, VALUE dst);
  172. DEFUN_INT("rename-file", cmd_rename_file, subr_rename_file, (VALUE src, VALUE dst), V_Subr2, DOC_rename_file, "fRename file:\nFRename file `%s' as:") /*
  173. ::doc:rename_file::
  174. rename-file SRC DEST
  175.  
  176. Tries to rename the file SRC as DEST, this doesn't work across filesystems, or
  177. if a file DEST already exists.
  178. ::end:: */
  179. {
  180.     DECLARE1(src, STRINGP);
  181.     DECLARE2(dst, STRINGP);
  182.     if(!rename(VSTR(src), VSTR(dst)))
  183.     return(sym_t);
  184.     return(signal_file_error(list_2(src, dst)));
  185. }
  186.  
  187. _PR VALUE cmd_copy_file(VALUE src, VALUE dst);
  188. DEFUN_INT("copy-file", cmd_copy_file, subr_copy_file, (VALUE src, VALUE dst), V_Subr2, DOC_copy_file, "fCopy file:\nFCopy file `%s' to:") /*
  189. ::doc:copy_file::
  190. copy-file SRC DEST
  191.  
  192. Copies the file called SRC to the file DEST.
  193. ::end:: */
  194. {
  195.     VALUE res = sym_t;
  196.     int srcf;
  197.     DECLARE1(src, STRINGP);
  198.     DECLARE2(dst, STRINGP);
  199.     srcf = open(VSTR(src), O_RDONLY);
  200.     if(srcf != -1)
  201.     {
  202.     int dstf = open(VSTR(dst), O_WRONLY | O_CREAT | O_TRUNC, 0666);
  203.     if(dstf != -1)
  204.     {
  205.         struct stat statb;
  206.         int rd;
  207.         if(fstat(srcf, &statb) == 0)
  208.         chmod(VSTR(dst), statb.st_mode);
  209.         do {
  210.         u_char buf[BUFSIZ];
  211.         int wr;
  212.         rd = read(srcf, buf, BUFSIZ);
  213.         if(rd < 0)
  214.         {
  215.             res = signal_file_error(src);
  216.             break;
  217.         }
  218.         wr = write(dstf, buf, rd);
  219.         if(wr != rd)
  220.         {
  221.             res = signal_file_error(dst);
  222.             break;
  223.         }
  224.         } while(rd != 0);
  225.         close(dstf);
  226.     }
  227.     else
  228.         res = signal_file_error(dst);
  229.     close(srcf);
  230.     }
  231.     else
  232.     res = signal_file_error(src);
  233.     return(res);
  234. }
  235.  
  236. _PR VALUE cmd_file_readable_p(VALUE file);
  237. DEFUN("file-readable-p", cmd_file_readable_p, subr_file_readable_p, (VALUE file), V_Subr1, DOC_file_readable_p) /*
  238. ::doc:file_readable_p::
  239. file-readable-p FILE
  240.  
  241. Returns t if FILE available for reading from.
  242. ::end:: */
  243. {
  244.     DECLARE1(file, STRINGP);
  245.     if(!access(VSTR(file), R_OK))
  246.     return(sym_t);
  247.     return(sym_nil);
  248. }
  249.  
  250. _PR VALUE cmd_file_writable_p(VALUE file);
  251. DEFUN("file-writable-p", cmd_file_writable_p, subr_file_writable_p, (VALUE file), V_Subr1, DOC_file_writeable_p) /*
  252. ::doc:file_writeable_p::
  253. file-writable-p FILE
  254.  
  255. Returns t if FILE available for writing to.
  256. ::end:: */
  257. {
  258.     DECLARE1(file, STRINGP);
  259.     if(!access(VSTR(file), W_OK))
  260.     return(sym_t);
  261.     return(sym_nil);
  262. }
  263.  
  264. _PR VALUE cmd_file_exists_p(VALUE file);
  265. DEFUN("file-exists-p", cmd_file_exists_p, subr_file_exists_p, (VALUE file), V_Subr1, DOC_file_exists_p) /*
  266. ::doc:file_exists_p::
  267. file-exists-p FILE
  268.  
  269. Returns t if FILE exists.
  270. ::end:: */
  271. {
  272.     DECLARE1(file, STRINGP);
  273.     if(!access(VSTR(file), F_OK))
  274.     return(sym_t);
  275.     return(sym_nil);
  276. }
  277. bool
  278. file_exists(u_char *fileName)
  279. {
  280.     if(!access(fileName, F_OK))
  281.     {
  282.     struct stat statb;
  283.     if(!stat(fileName, &statb) && !S_ISDIR(statb.st_mode))
  284.         return(TRUE);
  285.     }
  286.     return(FALSE);
  287. }
  288.  
  289. _PR VALUE cmd_file_regular_p(VALUE file);
  290. DEFUN("file-regular-p", cmd_file_regular_p, subr_file_regular_p, (VALUE file), V_Subr1, DOC_file_regular_p) /*
  291. ::doc:file_regular_p::
  292. file-regular-p FILE
  293.  
  294. Returns t if FILE is a ``normal'' file, ie, not a directory, device, symbolic
  295. link, etc...
  296. ::end:: */
  297. {
  298.     struct stat statb;
  299.     DECLARE1(file, STRINGP);
  300.     if(!stat(VSTR(file), &statb))
  301.     {
  302.     if(S_ISREG(statb.st_mode))
  303.         return(sym_t);
  304.     }
  305.     return(sym_nil);
  306. }
  307.  
  308. _PR VALUE cmd_file_directory_p(VALUE file);
  309. DEFUN("file-directory-p", cmd_file_directory_p, subr_file_directory_p, (VALUE file), V_Subr1, DOC_file_directory_p) /*
  310. ::doc:file_directory_p::
  311. file-directory-p FILE
  312.  
  313. Returns t if FILE is a directory.
  314. ::end:: */
  315. {
  316.     struct stat statb;
  317.     DECLARE1(file, STRINGP);
  318.     if(!stat(VSTR(file), &statb))
  319.     {
  320.     if(S_ISDIR(statb.st_mode))
  321.         return(sym_t);
  322.     }
  323.     return(sym_nil);
  324. }
  325.  
  326. _PR VALUE cmd_file_symlink_p(VALUE file);
  327. DEFUN("file-symlink-p", cmd_file_symlink_p, subr_file_symlink_p, (VALUE file), V_Subr1, DOC_file_symlink_p) /*
  328. ::doc:file_symlink_p::
  329. file-symlink-p FILE
  330.  
  331. Returns t if FILE is a symbolic link to another file.
  332. ::end:: */
  333. {
  334.     struct stat statb;
  335.     DECLARE1(file, STRINGP);
  336.     if(!stat(VSTR(file), &statb))
  337.     {
  338.     if(S_ISLNK(statb.st_mode))
  339.         return(sym_t);
  340.     }
  341.     return(sym_nil);
  342. }
  343.  
  344. _PR VALUE cmd_file_owner_p(VALUE file);
  345. DEFUN("file-owner-p", cmd_file_owner_p, subr_file_owner_p, (VALUE file), V_Subr1, DOC_file_owner_p) /*
  346. ::doc:file_owner_p::
  347. file-owner-p FILE
  348.  
  349. Returns t if the ownership (uid & gid) of file FILE (a string) is the same
  350. as that of any files written by the editor.
  351. ::end:: */
  352. {
  353.     struct stat statb;
  354.     DECLARE1(file, STRINGP);