home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume22 / nfsxopen / part01 next >
Text File  |  1991-08-23  |  6KB  |  152 lines

  1. Newsgroups: comp.sources.misc
  2. From: Stephen R. van den Berg <berg@messua.informatik.rwth-aachen.de>
  3. Subject:  v22i054:  nfsxopen - NFS secure exclusive open lib v1.1, Part01/01
  4. Message-ID: <1991Aug23.181109.6339@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: dd020acb99be7d1db10faac0719b6e9d
  6. Date: Fri, 23 Aug 1991 18:11:09 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Stephen R. van den Berg <berg@messua.informatik.rwth-aachen.de>
  10. Posting-number: Volume 22, Issue 54
  11. Archive-name: nfsxopen/part01
  12. Environment: UNIX
  13.  
  14. This is a very small library that enables you create files exclusively.
  15. This normally is accomplished by open(...,O_CREAT|O_EXCL,...); but this
  16. does not work reliably across NFS mounted filesystems.  That is where
  17. this library comes in, it works across any UNIX-alike filesystem and
  18. does not depend on lockd, lockf or flock.
  19.  
  20. Typical applications are the creation of lockfiles.  This code is donated
  21. to the public domain.
  22.  
  23. -- 
  24. Sincerely,                                berg@messua.informatik.rwth-aachen.de
  25.            Stephen R. van den Berg (AKA BuGless).    berg@physik.tu-muenchen.de
  26.  
  27. ---- Cut Here and feed the following to sh ----
  28. #!/bin/sh
  29. # This is NFSxopen, a shell archive (produced by shar 3.49)
  30. # To extract the files from this archive, save it to a file, remove
  31. # everything above the "!/bin/sh" line above, and type "sh file_name".
  32. #
  33. # made 08/23/1991 13:28 UTC by berg@messua.informatik.rwth-aachen.de
  34. # Source directory /tmp_mnt/tmp/.am/baghira/berg/tmp
  35. #
  36. # existing files will NOT be overwritten unless -c is specified
  37. #
  38. # This shar contains:
  39. # length  mode       name
  40. # ------ ---------- ------------------------------------------
  41. #   3436 -rw-r--r-- NFSxopen.c
  42. #
  43. # ============= NFSxopen.c ==============
  44. if test -f 'NFSxopen.c' -a X"$1" != X"-c"; then
  45.     echo 'x - skipping NFSxopen.c (File already exists)'
  46. else
  47. echo 'x - extracting NFSxopen.c (Text)'
  48. sed 's/^X//' << 'SHAR_EOF' > 'NFSxopen.c' &&
  49. X/************************************************************************
  50. X *    NFS secure exclusive open/lock    v1.1                *
  51. X *                                    *
  52. X *    Created 1990-1991, S.R.van den Berg, The Netherlands        *
  53. X *            berg@messua.informatik.rwth-aachen.de        *
  54. X *            berg@physik.tu-muenchen.de            *
  55. X *                                    *
  56. X *    This file is donated to the public domain.            *
  57. X *                                    *
  58. X *    Usage: NFSxopen(char*filename,mode_t mode)            *
  59. X *                                    *
  60. X *        returns        0:success    -1:failure        *
  61. X *                                    *
  62. X *        sets errno on failure                    *
  63. X *                                    *
  64. X *    Sorry for the formatting style, feed it through your        *
  65. X *    favourite C-beautifier if you can't resist :-)            *
  66. X *                                    *
  67. X ************************************************************************/
  68. X#define HOSTNAMElen    8          /* significant characters for hostname */
  69. X/*#define NOuname              /* uncomment if uname is not available */
  70. X#define const                  /* can be undefined for ANSI compilers */
  71. Xstatic const char dirsep[]="/";                 /* directory separators */
  72. X
  73. X#include <unistd.h>            /* open() close() link() unlink() */
  74. X#include <fcntl.h>            /* O_WRONLY O_CREAT O_EXCL */
  75. X#include <stdlib.h>            /* malloc() free() */
  76. X#include <string.h>            /* strncpy() strcat() strpbrk() */
  77. X#include <sys/stat.h>            /* stat() struct stat */
  78. X#ifndef NOuname
  79. X#include <sys/utsname.h>        /* uname() struct utsname */
  80. X#endif
  81. X#include <errno.h>
  82. X
  83. X/************************************************************************
  84. X * Only edit below this line if you *think* you know what you are doing *
  85. X ************************************************************************/
  86. X
  87. X#define log(string)                  /* should log string to stderr */
  88. X#define SERIALchars    3
  89. X#define UNIQnamelen    (1+SERIALchars+HOSTNAMElen+1)
  90. X#define SERIALmask    ((1L<<6*SERIALchars)-1)
  91. X
  92. Xextern errno;
  93. X
  94. Xstatic const char*hostname(){static char name[HOSTNAMElen+1];
  95. X#ifdef    NOuname
  96. X gethostname(name,HOSTNAMElen+1);
  97. X#else
  98. X struct utsname names;
  99. X uname(&names);strncpy(name,names.nodename,HOSTNAMElen);
  100. X#endif
  101. X name[HOSTNAMElen]='\0';return name;}
  102. X
  103. Xstatic ultoan(val,dest)unsigned long val;char*dest;{register i;/* convert to */
  104. X do{                    /* a number within the set [0-9A-Za-z-_] */
  105. X    i=val&0x3f;
  106. X    *dest++=i+(i<10?'0':i<10+26?'A'-10:i<10+26+26?'a'-10-26:
  107. X       i==10+26+26?'-'-10-26-26:'_'-10-26-27);}
  108. X while(val>>=6);
  109. X *dest='\0';}
  110. X
  111. Xstatic unique(full,p,mode)const char*const full;char*const p;
  112. X const mode_t mode;{
  113. X unsigned long retry=3;int i;              /* create unique file name */
  114. X do{
  115. X   ultoan(SERIALmask&(retry<<16)+(unsigned long)getpid(),p+1);
  116. X   *p='_';strcat(p,hostname());}
  117. X while(0>(i=open(full,O_WRONLY|O_CREAT|O_EXCL|O_SYNC,mode))&&errno==EEXIST
  118. X   &&retry--);        /* casually check if it already exists (highly unlikely) */
  119. X if(i<0){
  120. X   log("Error while writing to \"");log(full);log("\"\n");return 0;}
  121. X close(i);return 1;}
  122. X                     /* rename MUST fail if already existent */
  123. Xstatic myrename(old,new)const char*const old,*const new;{int i,serrno;
  124. X struct stat stbuf;
  125. X link(old,new);serrno=errno;i=stat(old,&stbuf);unlink(old);errno=serrno;
  126. X return stbuf.st_nlink==2?i:-1;}
  127. X                    /* an NFS secure exclusive file open */
  128. XNFSxopen(name,mode)char*name;const mode_t mode;{char*p,*q;int j= -1,i;
  129. X for(q=name;p=strpbrk(q,dirsep);q=p+1);             /* find last DIRSEP */
  130. X if(!(p=malloc(i+UNIQnamelen)))                    /* out of memory */
  131. X   return j;
  132. X i=q-name;strncpy(p,name,i);
  133. X if(unique(p,p+i,mode))
  134. X   j=myrename(p,name);         /* try and rename it, fails if nonexclusive */
  135. X free(p);return j;}
  136. SHAR_EOF
  137. chmod 0644 NFSxopen.c ||
  138. echo 'restore of NFSxopen.c failed'
  139. Wc_c="`wc -c < 'NFSxopen.c'`"
  140. test 3436 -eq "$Wc_c" ||
  141.     echo 'NFSxopen.c: original size 3436, current size' "$Wc_c"
  142. fi
  143. exit 0
  144.  
  145. -- 
  146. Sincerely,                                berg@messua.informatik.rwth-aachen.de
  147.            Stephen R. van den Berg (AKA BuGless).    berg@physik.tu-muenchen.de
  148.  
  149. "My name is Psmith, the P is not pronounced."
  150.  
  151. exit 0 # Just in case...
  152.