home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / may94 / util / edit / jade.lha / Jade / src / unix_misc.c < prev    next >
C/C++ Source or Header  |  1994-04-19  |  15KB  |  585 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 <errno.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. _PR int fileexists(u_char *);
  34. _PR u_long filemodtime(u_char *);
  35. _PR void sys_misc_init(void);
  36.  
  37. _PR bool samefiles(u_char *, u_char *);
  38. _PR u_char * filepart(u_char *);
  39. _PR VALUE geterrstring(void);
  40. _PR void doconmsg(u_char *);
  41. _PR u_char * squirrelfile(u_char *);
  42. _PR VALUE valsquirrelfile(u_char *);
  43. _PR u_long getsystime(void);
  44. _PR int addfilepart(u_char *, const u_char *, int);
  45.  
  46. bool
  47. samefiles(u_char *file1, u_char *file2)
  48. {
  49.     bool rc = FALSE;
  50.     struct stat stat1, stat2;
  51.     if(!stat(file1, &stat1))
  52.     {
  53.     if(!stat(file2, &stat2))
  54.     {
  55.         if((stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino))
  56.         rc = TRUE;
  57.     }
  58.     }
  59.     else
  60.     rc = !strcmp(file1, file2);
  61.     return(rc);
  62. }
  63.  
  64. u_char *
  65. filepart(u_char *fname)
  66. {
  67.     u_char *tmp = strrchr(fname, '/');
  68.     if(tmp)
  69.     return(tmp + 1);
  70.     return(fname);
  71. }
  72.  
  73. VALUE
  74. geterrstring(void)
  75. {
  76.     return(valstrdup(ERRNO_STRING));
  77. }
  78.  
  79. void
  80. doconmsg(u_char *msg)
  81. {
  82.     fputs(msg, stderr);
  83. }
  84.  
  85. u_char *
  86. squirrelfile(u_char *fileName)
  87. {
  88.     FILE *fh = fopen(fileName, "r");
  89.     if(fh)
  90.     {
  91.     struct stat stat;
  92.     if(!fstat(fileno(fh), &stat))
  93.     {
  94.         u_char *mem = mystralloc(stat.st_size + 1);
  95.         if(mem)
  96.         {
  97.         fread(mem, 1, stat.st_size, fh);
  98.         mem[stat.st_size] = 0;
  99.         fclose(fh);
  100.         return(mem);
  101.         }
  102.         else
  103.         settitle(NoMemMsg);
  104.     }
  105.     fclose(fh);
  106.     }
  107.     return(FALSE);
  108. }
  109. VALUE
  110. valsquirrelfile(u_char *fileName)
  111. {
  112.     FILE *fh = fopen(fileName, "r");
  113.     if(fh)
  114.     {
  115.     struct stat stat;
  116.     if(!fstat(fileno(fh), &stat))
  117.     {
  118.         VALUE mem = valstralloc(stat.st_size + 1);
  119.         if(mem)
  120.         {
  121.         fread(VSTR(mem), 1, stat.st_size, fh);
  122.         VSTR(mem)[stat.st_size] = 0;
  123.         fclose(fh);
  124.         return(mem);
  125.         }
  126.         else
  127.         settitle(NoMemMsg);
  128.     }
  129.     fclose(fh);
  130.     }
  131.     return(cmd_signal(sym_file_error, list_2(geterrstring(), valstrdup(fileName))));
  132. }
  133.  
  134. u_long
  135. getsystime(void)
  136. {
  137.     return(time(NULL));
  138. }
  139.  
  140. int
  141. addfilepart(u_char *buf, const u_char *part, int bufLen)
  142. {
  143.     int bufend = strlen(buf);
  144.     int partlen = strlen(part);
  145.     if((bufend > 0) && (buf[bufend-1] != '/'))
  146.     {
  147.     if(++bufend >= bufLen)
  148.         return(FALSE);
  149.     buf[bufend-1] = '/';
  150.     buf[bufend] = 0;
  151.     }
  152.     if((bufend + partlen) >= bufLen)
  153.     return(FALSE);
  154.     strcpy(buf + bufend, part);
  155.     return(TRUE);
  156. }
  157.  
  158. _PR VALUE cmd_delete_file(VALUE file);
  159. DEFUN("delete-file", cmd_delete_file, subr_delete_file, (VALUE file), V_Subr1, DOC_delete_file) /*
  160. ::doc:delete_file::
  161. (delete-file FILE-NAME)
  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(signalfileerror(file));
  169. }
  170.  
  171. _PR VALUE cmd_rename_file(VALUE src, VALUE dst);
  172. DEFUN("rename-file", cmd_rename_file, subr_rename_file, (VALUE src, VALUE dst), V_Subr2, DOC_rename_file) /*
  173. ::doc:rename_file::
  174. (rename-file SRC DEST)
  175. Tries to rename the file SRC as DEST, this doesn't work across filesystems, or
  176. if a file DEST already exists.
  177. ::end:: */
  178. {
  179.     DECLARE1(src, STRINGP);
  180.     DECLARE2(dst, STRINGP);
  181.     if(!rename(VSTR(src), VSTR(dst)))
  182.     return(sym_t);
  183.     return(signalfileerror(list_2(src, dst)));
  184. }
  185.  
  186. _PR VALUE cmd_copy_file(VALUE src, VALUE dst);
  187. DEFUN("copy-file", cmd_copy_file, subr_copy_file, (VALUE src, VALUE dst), V_Subr2, DOC_copy_file) /*
  188. ::doc:copy_file::
  189. (copy-file SRC DEST)
  190. Copies the file called SRC to the file DEST.
  191. ::end:: */
  192. {
  193.     VALUE res = sym_t;
  194.     int srcf;
  195.     DECLARE1(src, STRINGP);
  196.     DECLARE2(dst, STRINGP);
  197.     srcf = open(VSTR(src), O_RDONLY);
  198.     if(srcf != -1)
  199.     {
  200.     int dstf = open(VSTR(dst), O_WRONLY | O_CREAT, 0666);
  201.     if(dstf != -1)
  202.     {
  203.         struct stat statb;
  204.         int rd;
  205.         if(fstat(srcf, &statb) == 0)
  206.         chmod(VSTR(dst), statb.st_mode);
  207.         do {
  208.         u_char buf[BUFSIZ];
  209.         int wr;
  210.         rd = read(srcf, buf, BUFSIZ);
  211.         if(rd < 0)
  212.         {
  213.             res = signalfileerror(src);
  214.             break;
  215.         }
  216.         wr = write(dstf, buf, rd);
  217.         if(wr != rd)
  218.         {
  219.             res = signalfileerror(dst);
  220.             break;
  221.         }
  222.         } while(rd != 0);
  223.         close(dstf);
  224.     }
  225.     else
  226.         res = signalfileerror(dst);
  227.     close(srcf);
  228.     }
  229.     else
  230.     res = signalfileerror(src);
  231.     return(res);
  232. }
  233.  
  234. _PR VALUE cmd_file_readable_p(VALUE file);
  235. DEFUN("file-readable-p", cmd_file_readable_p, subr_file_readable_p, (VALUE file), V_Subr1, DOC_file_readable_p) /*
  236. ::doc:file_readable_p::
  237. (file-readable-p FILE)
  238. Returns t if FILE available for reading from.
  239. ::end:: */
  240. {
  241.     DECLARE1(file, STRINGP);
  242.     if(!access(VSTR(file), R_OK))
  243.     return(sym_t);
  244.     return(sym_nil);
  245. }
  246.  
  247. _PR VALUE cmd_file_writeable_p(VALUE file);
  248. DEFUN("file-writeable-p", cmd_file_writeable_p, subr_file_writeable_p, (VALUE file), V_Subr1, DOC_file_writeable_p) /*
  249. ::doc:file_writeable_p::
  250. (file-writeable-p FILE)
  251. Returns t if FILE available for writing to.
  252. ::end:: */
  253. {
  254.     DECLARE1(file, STRINGP);
  255.     if(!access(VSTR(file), W_OK))
  256.     return(sym_t);
  257.     return(sym_nil);
  258. }
  259.  
  260. _PR VALUE cmd_file_exists_p(VALUE file);
  261. DEFUN("file-exists-p", cmd_file_exists_p, subr_file_exists_p, (VALUE file), V_Subr1, DOC_file_exists_p) /*
  262. ::doc:file_exists_p::
  263. (file-exists-p FILE)
  264. Returns t if FILE exists.
  265. ::end:: */
  266. {
  267.     DECLARE1(file, STRINGP);
  268.     if(!access(VSTR(file), F_OK))
  269.     return(sym_t);
  270.     return(sym_nil);
  271. }
  272. int
  273. fileexists(u_char *fileName)
  274. {
  275.     if(!access(fileName, F_OK))
  276.     {
  277.     struct stat statb;
  278.     if(!stat(fileName, &statb) && !S_ISDIR(statb.st_mode))
  279.         return(TRUE);
  280.     }
  281.     return(FALSE);
  282. }
  283.  
  284. _PR VALUE cmd_file_regular_p(VALUE file);
  285. DEFUN("file-regular-p", cmd_file_regular_p, subr_file_regular_p, (VALUE file), V_Subr1, DOC_file_regular_p) /*
  286. ::doc:file_regular_p::
  287. (file-regular-p FILE)
  288. Returns t if FILE is a ``normal'' file, ie, not a directory, device, symbolic
  289. link, etc...
  290. ::end:: */
  291. {
  292.     struct stat statb;
  293.     DECLARE1(file, STRINGP);
  294.     if(!stat(VSTR(file), &statb))
  295.     {
  296.     if(S_ISREG(statb.st_mode))
  297.         return(sym_t);
  298.     }
  299.     return(sym_nil);
  300. }
  301.  
  302. _PR VALUE cmd_file_directory_p(VALUE file);
  303. DEFUN("file-directory-p", cmd_file_directory_p, subr_file_directory_p, (VALUE file), V_Subr1, DOC_file_directory_p) /*
  304. ::doc:file_directory_p::
  305. (file-directory-p FILE)
  306. Returns t if FILE is a directory.
  307. ::end:: */
  308. {
  309.     struct stat statb;
  310.     DECLARE1(file, STRINGP);
  311.     if(!stat(VSTR(file), &statb))
  312.     {
  313.     if(S_ISDIR(statb.st_mode))
  314.         return(sym_t);
  315.     }
  316.     return(sym_nil);
  317. }
  318.  
  319. _PR VALUE cmd_file_symlink_p(VALUE file);
  320. DEFUN("file-symlink-p", cmd_file_symlink_p, subr_file_symlink_p, (VALUE file), V_Subr1, DOC_file_symlink_p) /*
  321. ::doc:file_symlink_p::
  322. (file-symlink-p FILE)
  323. Returns t if FILE is a symbolic link to another file.
  324. ::end:: */
  325. {
  326.     struct stat statb;
  327.     DECLARE1(file, STRINGP);
  328.     if(!stat(VSTR(file), &statb))
  329.     {
  330.     if(S_ISLNK(statb.st_mode))
  331.         return(sym_t);
  332.     }
  333.     return(sym_nil);
  334. }
  335.  
  336. _PR VALUE cmd_file_owner_p(VALUE file);
  337. DEFUN("file-owner-p", cmd_file_owner_p, subr_file_owner_p, (VALUE file), V_Subr1, DOC_file_owner_p) /*
  338. ::doc:file_owner_p::
  339. (file-owner-p FILE)
  340. Returns t if the ownership (uid & gid) of file FILE (a string) is the same
  341. as that of any files written by the editor.
  342. ::end:: */
  343. {
  344.     struct stat statb;
  345.     DECLARE1(file, STRINGP);
  346.     if(!stat(VSTR(file), &statb))
  347.     {
  348.     if((statb.st_uid == geteuid()) && (statb.st_gid == getegid()))
  349.         return(sym_t);
  350.     }
  351.     return(sym_nil);
  352. }
  353.  
  354. _PR VALUE cmd_file_n