home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / elm23-2.zip / filter / lock.c < prev    next >
C/C++ Source or Header  |  1992-03-22  |  5KB  |  176 lines

  1.  
  2. static char rcsid[] ="@(#)$Id: lock.c,v 4.1.1.3 90/06/21 23:51:34 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 4.1.1.3 $   $State: Exp $
  6.  *
  7.  *             Copyright (c) 1986, 1987 Dave Taylor
  8.  *             Copyright (c) 1988, 1989, 1990 USENET Community Trust
  9.  *******************************************************************************
  10.  * Bug reports, patches, comments, suggestions should be sent to:
  11.  *
  12.  *    Syd Weinstein - elm@DSI.COM
  13.  *            dsinc!elm
  14.  *
  15.  *******************************************************************************
  16.  * $Log:    lock.c,v $
  17.  * Revision 4.1.1.3  90/06/21  23:51:34  syd
  18.  * Fix typo
  19.  *
  20.  * Revision 4.1.1.2  90/06/21  23:02:37  syd
  21.  * Make lock use same name as elm
  22.  * From: Edwin WIles
  23.  *
  24.  * Revision 4.1.1.1  90/06/05  20:28:53  syd
  25.  * The open system call in actions.c for EMERGENCY_MAILBOX and EMER_MBOX
  26.  * were tested with the inequality >= 0 exactly backwards.
  27.  * If the user's system mail box (/usr/spool/mail/user_id) is
  28.  * removed the attempt of filter to flock it fails.  If it does not exist then
  29.  * it should create it and then lock it.
  30.  * From: john@hopf.math.nwu.edu (John Franks)
  31.  *
  32.  * Revision 4.1  90/04/28  22:41:57  syd
  33.  * checkin of Elm 2.3 as of Release PL0
  34.  *
  35.  *
  36.  ******************************************************************************/
  37.  
  38.  
  39. /** The lock() and unlock() routines herein duplicate exactly the
  40.     equivalent routines in the Elm Mail System, and should also be
  41.     compatible with sendmail, rmail, etc etc.
  42.  
  43.  
  44. **/
  45.  
  46. #include <stdio.h>
  47. #include <fcntl.h>
  48. #include <errno.h>
  49. #include "defs.h"
  50. #include "filter.h"
  51.  
  52. static  int  we_locked_it;
  53. static  char lockfile[SLEN];
  54.  
  55. #ifdef    LOCK_BY_FLOCK
  56. #include <sys/types.h>
  57. #include <sys/file.h>
  58. static    flock_fd = -1;
  59. static    char flock_name[SLEN];
  60. #endif
  61.  
  62. char *
  63. mk_lockname(home, user)
  64. char *home, *user;
  65. {
  66.     /** Create the proper name of the lock file for file_to_lock.
  67.         Return lock_name for informational purposes.
  68.      **/
  69.  
  70. #ifdef XENIX
  71.     /* lock is /tmp/[basename of file_to_lock].mlk */
  72.     sprintf(lockfile, "/tmp/%.10s.mlk", user);
  73. #else
  74.     /* lock is [file_to_lock].lock */
  75.     sprintf(lockfile, "%s%s.lck", home, user);
  76. #endif
  77.     return(lockfile);
  78. }
  79.  
  80.  
  81. int
  82. lock()
  83. {
  84.     /** This routine will return 1 if we could lock the mailfile,
  85.         zero otherwise.
  86.     **/
  87.  
  88.     int attempts = 0, ret;
  89.  
  90. #ifndef    LOCK_FLOCK_ONLY            /* { !LOCK_FLOCK_ONLY    */
  91.     mk_lockname(mailhome, username);
  92. #ifdef PIDCHECK
  93.     /** first, try to read the lock file, and if possible, check the pid.
  94.         If we can validate that the pid is no longer active, then remove
  95.         the lock file.
  96.     **/
  97.     if((ret=open(lockfile,O_RDONLY)) != -1) {
  98.       char pid_buffer[SHORT];
  99.       if (read(ret, pid_buffer, SHORT) > 0) {
  100.         attempts = atoi(pid_buffer);
  101.         if (attempts) {
  102.           if (kill(attempts, 0)) {
  103.             close(ret);
  104.             if (unlink(lockfile) != 0)
  105.           return(1);
  106.           }
  107.         }
  108.       }
  109.       attempts = 0;
  110.         }
  111. #endif
  112.  
  113.     while ((ret = open(lockfile, O_WRONLY | O_CREAT | O_EXCL, 0666)) < 0
  114.            && attempts++ < 10) {
  115.       sleep(3);    /* wait three seconds each pass, okay?? */
  116.     }
  117.  
  118.     if (ret >= 0) {
  119.       we_locked_it++;
  120.       close(ret);            /* no need to keep it open! */
  121.       ret = 1;
  122.     } else {
  123.       ret = 0;
  124.     }
  125.  
  126. #endif                    /* } !LOCK_FLOCK_ONLY    */
  127. #ifdef    LOCK_BY_FLOCK            /* { LOCK_BY_FLOCK    */
  128.     (void)sprintf(flock_name,"%s%s",mailhome,username);
  129.     flock_fd = open(flock_name, O_RDONLY | O_CREAT, 0666);
  130.     if ( flock_fd >= 0 )
  131.       for (attempts = 0; attempts < 10; attempts++) {
  132.         if ( (ret = flock(flock_fd,LOCK_NB|LOCK_EX)) != -1 )
  133.             break;
  134.         if ( errno != EWOULDBLOCK && errno != EAGAIN )
  135.             break;
  136.         (void)sleep((unsigned)3);
  137.       }
  138.     if ( flock_fd >= 0 && ret == 0 ) {
  139.         we_locked_it++;
  140.         ret = 1;
  141.     } else {
  142.         we_locked_it = 0;
  143.         if ( lockfile[0] ) {
  144.             (void)unlink(lockfile);
  145.         lockfile[0] = 0;
  146.         }
  147.         if ( flock_fd >= 0 ) {
  148.             (void)close(flock_fd);
  149.             flock_fd = -1;
  150.         }
  151.         ret = 0;
  152.     }
  153. #endif
  154.     return(ret);
  155. }
  156.  
  157. unlock()
  158. {
  159.     /** this routine will remove the lock file, but only if we were
  160.         the people that locked it in the first place... **/
  161.  
  162. #ifndef    LOCK_FLOCK_ONLY
  163.     if (we_locked_it && lockfile[0]) {
  164.       unlink(lockfile);    /* blamo! */
  165.       lockfile[0] = 0;
  166.     }
  167. #endif
  168. #ifdef    LOCK_BY_FLOCK
  169.     if (we_locked_it && flock_fd >= 0) {
  170.       (void)close(flock_fd);
  171.       flock_fd = -1;
  172.     }
  173. #endif
  174.     we_locked_it = 0;
  175. }
  176.