home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / elm / elm2.4 / src / lock.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-31  |  17.5 KB  |  620 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: lock.c,v 5.15 1993/05/31 19:16:24 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 5.15 $   $State: Exp $
  6.  *
  7.  *            Copyright (c) 1988-1992 USENET Community Trust
  8.  *            Copyright (c) 1986,1987 Dave Taylor
  9.  *******************************************************************************
  10.  * Bug reports, patches, comments, suggestions should be sent to:
  11.  *
  12.  *    Syd Weinstein, Elm Coordinator
  13.  *    elm@DSI.COM            dsinc!elm
  14.  *
  15.  *******************************************************************************
  16.  * $Log: lock.c,v $
  17.  * Revision 5.15  1993/05/31  19:16:24  syd
  18.  * It looks like there was some earlier patch that re-introduced
  19.  * some lock problems from the past time of 2.4beta.
  20.  * From: Jukka Ukkonen <ukkonen@csc.fi>
  21.  *
  22.  * Revision 5.14  1993/04/16  14:13:49  syd
  23.  * Make it clear errno, some systems arent
  24.  * From: Syd
  25.  *
  26.  * Revision 5.13  1993/04/16  03:58:57  syd
  27.  * Fix where Solaris 2.0 leaves an error code
  28.  * yet creates the lock file
  29.  * From: Syd via pointer from Daniel Bidwell <bidwell@elrond.cs.andrews.edu>
  30.  *
  31.  * Revision 5.12  1993/02/03  17:12:53  syd
  32.  * move more declarations to defs.h, including sleep
  33.  * From: Syd
  34.  *
  35.  * Revision 5.11  1993/01/20  03:02:19  syd
  36.  * Move string declarations to defs.h
  37.  * From: Syd
  38.  *
  39.  * Revision 5.10  1992/12/11  01:45:04  syd
  40.  * remove sys/types.h include, it is now included by defs.h
  41.  * and this routine includes defs.h or indirectly includes defs.h
  42.  * From: Syd
  43.  *
  44.  * Revision 5.9  1992/12/07  03:49:49  syd
  45.  * use BSD or not apollo on file.h include as its not valid
  46.  * for Apollos under sys5.3 compile type
  47.  * From: gordonb@mcil.comm.mot.com (Gordon Berkley)
  48.  *
  49.  * Revision 5.8  1992/12/07  02:23:35  syd
  50.  * Always init fcntlerr and flockerr so useage after ifdef code doesnt cause problem
  51.  * From: Syd via prompt from wdh@grouper.mkt.csd.harris.com (W. David Higgins)
  52.  *
  53.  * Revision 5.7  1992/11/26  00:46:13  syd
  54.  * changes to first change screen back (Raw off) and then issue final
  55.  * error message.
  56.  * From: Syd
  57.  *
  58.  * Revision 5.6  1992/10/27  01:52:16  syd
  59.  * Always include <sys/ioctl.h> in curses.c When calling ioctl()
  60.  *
  61.  * Remove declaration of getegid() from leavembox.c & lock.c
  62.  * They aren't even used there.
  63.  * From: tom@osf.org
  64.  *
  65.  * Revision 5.5  1992/10/19  16:50:41  syd
  66.  * Fix a couple more compiler gripes from SYSVR4
  67.  * From: Tom Moore <tmoore@wnas.DaytonOH.NCR.COM>
  68.  *
  69.  * Revision 5.4  1992/10/17  22:13:50  syd
  70.  * ci -u src/lock.c < mail/lock.pat.i
  71.  *
  72.  * Revision 5.3  1992/10/12  00:25:52  syd
  73.  * Lock error codes (fcntl vs flock) were backwards
  74.  * From: howardl@wb3ffv.ampr.org (Howard Leadmon - WB3FFV)
  75.  *
  76.  * Revision 5.2  1992/10/11  00:52:11  syd
  77.  * Switch to wrapper for flock and fcntl locking.
  78.  * Change order to fcntl first, other order blocked.
  79.  * From: Jukka Ukkonen <ukkonen@csc.fi>
  80.  *
  81.  * Revision 5.1  1992/10/03  22:58:40  syd
  82.  * Initial checkin as of 2.4 Release at PL0
  83.  *
  84.  *
  85.  ******************************************************************************/
  86.  
  87. /** leave current folder, updating etc. as needed...
  88.   
  89. **/
  90.  
  91.  
  92. #include "headers.h"
  93. #include "s_elm.h"
  94. #include <sys/stat.h>
  95.  
  96. #ifdef USE_FCNTL_LOCKING
  97. # define SYSCALL_LOCKING
  98. #else
  99. # ifdef USE_FLOCK_LOCKING
  100. #   define SYSCALL_LOCKING
  101. # endif
  102. #endif
  103.  
  104. #ifdef SYSCALL_LOCKING
  105. #  if (defined(BSD) || !defined(apollo))
  106. #    include <sys/file.h>
  107. #  endif
  108. #endif
  109. #include <errno.h>
  110. #ifdef I_TIME
  111. #  include <time.h>
  112. #endif
  113. #ifdef I_SYSTIME
  114. #  include <sys/time.h>
  115. #endif
  116.  
  117.  
  118. extern int errno;
  119.  
  120. char *error_description();
  121.  
  122. #define    FLOCKING_OK    0
  123. #define    FLOCKING_RETRY    1
  124. #define    FLOCKING_FAIL    -1
  125.  
  126. extern char *mk_lockname();
  127.  
  128. static int  lock_state = OFF;
  129.  
  130. #ifdef    USE_DOTLOCK_LOCKING
  131. static char *lockfile=(char*)0;
  132. #endif  /* USE_DOTLOCK_LOCKING */
  133.  
  134. static int flock_fd,    /* file descriptor for flocking mailbox itself */
  135.        create_fd;    /* file descriptor for creating lock file */
  136.  
  137. #ifdef USE_FCNTL_LOCKING
  138. static struct flock lock_info;
  139. #endif
  140.  
  141. int
  142. Grab_the_file(flock_fd)
  143. int flock_fd;
  144. {
  145.     int    retcode    = FLOCKING_OK;
  146.  
  147.     errno = 0;
  148.  
  149. #ifdef   USE_FCNTL_LOCKING
  150.     lock_info.l_type = F_WRLCK;
  151.     lock_info.l_whence = 0;
  152.     lock_info.l_start = 0;
  153.     lock_info.l_len = 0;
  154.  
  155.     if (fcntl(flock_fd, F_SETLK, &lock_info)) {
  156.     return ((errno == EACCES) || (errno == EAGAIN))
  157.         ? FLOCKING_RETRY
  158.         : FLOCKING_FAIL ;
  159.     }
  160. #endif
  161.  
  162. #ifdef    USE_FLOCK_LOCKING
  163.     if (flock (flock_fd, LOCK_NB | LOCK_EX)) {
  164.  
  165.     retcode = ((errno == EWOULDBLOCK) || (errno == EAGAIN))
  166.            ? FLOCKING_RETRY
  167.            : FLOCKING_FAIL ;
  168.  
  169. #ifdef USE_FCNTL_LOCKING
  170.     lock_info.l_type = F_UNLCK;
  171.     lock_info.l_whence = 0;
  172.     lock_info.l_start = 0;
  173.     lock_info.l_len = 0;
  174.  
  175.     /*
  176.      *  Just unlock it because we did not succeed with the
  177.      *  flock()-style locking. Never mind the return value.
  178.      *  It was our own lock anyway if we ever got this far.
  179.      */
  180.     fcntl (flock_fd, F_SETLK, &lock_info);
  181. #endif
  182.     return retcode;
  183.     }
  184. #endif
  185.  
  186.     return FLOCKING_OK;
  187. }
  188.  
  189. int
  190. Release_the_file(flock_fd)
  191. int flock_fd;
  192. {
  193.     int    fcntlret = 0,
  194.     flockret = 0,
  195.     fcntlerr = 0,
  196.     flockerr = 0;
  197.  
  198. #ifdef    USE_FLOCK_LOCKING
  199.     errno = 0;
  200.     flockret = flock (flock_fd, LOCK_UN);
  201.     flockerr = errno;
  202. #endif
  203.  
  204. #ifdef    USE_FCNTL_LOCKING
  205.     lock_info.l_type = F_UNLCK;
  206.     lock_info.l_whence = 0;
  207.     lock_info.l_start = 0;
  208.     lock_info.l_len = 0;
  209.  
  210.     errno = 0;
  211.     fcntlret = fcntl (flock_fd, F_SETLK, &lock_info);
  212.     fcntlerr = errno;
  213. #endif
  214.  
  215.     if (fcntlret) {
  216.     errno = fcntlerr;
  217.     return fcntlret;
  218.     }
  219.     else if (flockret) {
  220.     errno = flockerr;
  221.     return flockret;
  222.     }
  223.     return 0;
  224. }
  225.  
  226. lock(direction)
  227. int direction;
  228. {
  229.       /** Create lock file to ensure that we don't get any mail 
  230.       while altering the folder contents!
  231.       If it already exists sit and spin until 
  232.          either the lock file is removed...indicating new mail
  233.       or
  234.          we have iterated MAX_ATTEMPTS times, in which case we
  235.          either fail or remove it and make our own (determined
  236.          by if REMOVE_AT_LAST is defined in header file
  237.  
  238.       If direction == INCOMING then DON'T remove the lock file
  239.       on the way out!  (It'd mess up whatever created it!).
  240.  
  241.       But if that succeeds and if we are also locking by flock(),
  242.       follow a similar algorithm. Now if we can't lock by flock(),
  243.       we DO need to remove the lock file, since if we got this far,
  244.       we DID create it, not another process.
  245.       **/
  246.  
  247.       register int create_iteration = 0,
  248.            flock_iteration = 0;
  249.       int kill_status;
  250.       char pid_buffer[SHORT];
  251.  
  252. #ifdef    USE_DOTLOCK_LOCKING        /* { USE_DOTLOCK_LOCKING  */
  253.       /* formulate lock file name */
  254.       lockfile=mk_lockname(cur_folder);
  255.  
  256. #ifdef SAVE_GROUP_MAILBOX_ID
  257.       setgid(mailgroupid); /* reset id so that we can get at lock file */
  258. #endif
  259.  
  260. #ifdef PIDCHECK
  261.       /** first, try to read the lock file, and if possible, check the pid.
  262.       If we can validate that the pid is no longer active, then remove
  263.       the lock file.
  264.        **/
  265.       errno = 0; /* some systems don't clear the errno flag */
  266.       if((create_fd=open(lockfile,O_RDONLY)) != -1) {
  267.     if (read(create_fd, pid_buffer, SHORT) > 0) {
  268.       create_iteration = atoi(pid_buffer);
  269.       if (create_iteration) {
  270.         kill_status = kill(create_iteration, 0);
  271.         if (kill_status != 0 && errno != EPERM) {
  272.           close(create_fd);
  273.           if (unlink(lockfile) != 0) {
  274.             MoveCursor(LINES, 0);
  275.         Raw(OFF);
  276.         dprint(1, (debugfile,
  277.           "Error %s\n\ttrying to unlink file %s (%s)\n", 
  278.           error_description(errno), lockfile, "lock"));
  279.         printf(catgets(elm_msg_cat, ElmSet, ElmLeaveCouldntRemoveCurLock,
  280.           "\nCouldn't remove the current lock file %s\n"), lockfile);
  281.         printf("** %s **\n", error_description(errno));
  282. #ifdef SAVE_GROUP_MAILBOX_ID
  283.         setgid(groupid);
  284. #endif
  285.         if (direction == INCOMING)
  286.           leave(0);
  287.         else
  288.           emergency_exit();
  289.           }
  290.         }
  291.       }
  292.     }
  293.     create_iteration = 0;
  294.       }
  295. #endif
  296.           
  297.       /* try to assert create lock file MAX_ATTEMPTS times */
  298.       do {
  299.  
  300.     errno = 0;
  301.     if((create_fd=open(lockfile,O_WRONLY | O_CREAT | O_EXCL,0444)) != -1)
  302.       break;
  303.     else {
  304.       if(errno != EEXIST) {
  305.         /* Creation of lock failed NOT because it already exists!!! */
  306.  
  307.         MoveCursor(LINES, 0);
  308.         Raw(OFF);
  309.         if (direction == OUTGOING) {
  310.           dprint(1, (debugfile, 
  311.         "Error encountered attempting to create lock %s\n", lockfile));
  312.           dprint(1, (debugfile, "** %s **\n", error_description(errno)));
  313.           printf(catgets(elm_msg_cat, ElmSet, ElmLeaveErrorCreatingLock,
  314.        "\nError encountered while attempting to create lock file %s;\n"),
  315.         lockfile);
  316.           printf("** %s.**\n\n", error_description(errno));
  317.         } else {    /* incoming - permission denied in the middle?  Odd. */
  318.           dprint(1, (debugfile,
  319.            "Can't create lock file: creat(%s) raises error %s (lock)\n", 
  320.         lockfile, error_description(errno)));
  321.           printf(catgets(elm_msg_cat, ElmSet, ElmLeaveCantCreateLock,
  322.            "Can't create lock file! Need write permission in \"%s\".\n"),
  323.         mailhome);
  324.         }
  325. #ifdef SAVE_GROUP_MAILBOX_ID
  326.         setgid(groupid);
  327. #endif
  328.         leave(0);
  329.       }
  330.     }
  331.     dprint(2, (debugfile,"File '%s' already exists!  Waiting...(lock)\n", 
  332.       lockfile));
  333.     error1(catgets(elm_msg_cat, ElmSet, ElmLeaveWaitingToRead,
  334.       "Waiting to read mailbox while mail is being received: attempt #%d"),
  335.       create_iteration);
  336.     sleep(5);
  337.       } while (create_iteration++ < MAX_ATTEMPTS);
  338.       clear_error();
  339.       if (errno == ENOENT && create_fd >= 0)
  340.     errno = 0; /* Some os leave the errno from the open on the creat call */
  341.  
  342.       if(errno != 0) {
  343.     
  344.     /* we weren't able to create the lock file */
  345.  
  346. #ifdef REMOVE_AT_LAST
  347.  
  348.     /** time to waste the lock file!  Must be there in error! **/
  349.     dprint(2, (debugfile, 
  350.        "Warning: I'm giving up waiting - removing lock file(lock)\n"));
  351.     if (direction == INCOMING)
  352.       PutLine0(LINES, 0, catgets(elm_msg_cat, ElmSet, ElmLeaveTimedOutRemoving,
  353.         "\nTimed out - removing current lock file..."));
  354.     else
  355.       error(catgets(elm_msg_cat, ElmSet, ElmLeaveThrowingAwayLock,
  356.         "Throwing away the current lock file!"));
  357.  
  358.     if (unlink(lockfile) != 0) {
  359.       MoveCursor(LINES, 0);
  360.       Raw(OFF);
  361.       dprint(1, (debugfile,
  362.         "Error %s\n\ttrying to unlink file %s (%s)\n", 
  363.         error_description(errno), lockfile, "lock"));
  364.       printf(catgets(elm_msg_cat, ElmSet, ElmLeaveCouldntRemoveCurLock,
  365.         "\nCouldn't remove the current lock file %s\n"), lockfile);
  366.       printf("** %s **\n", error_description(errno));
  367. #ifdef SAVE_GROUP_MAILBOX_ID
  368.       setgid(groupid);
  369. #endif
  370.       if (direction == INCOMING)
  371.         leave(0);
  372.       else
  373.         emergency_exit();
  374.     }
  375.  
  376.     /* we've removed the bad lock, let's try to assert lock once more */
  377.     if((create_fd=open(lockfile,O_WRONLY | O_CREAT | O_EXCL,0444)) == -1){
  378.  
  379.       /* still can't lock it - just give up */
  380.       dprint(1, (debugfile, 
  381.         "Error encountered attempting to create lock %s\n", lockfile));
  382.       dprint(1, (debugfile, "** %s **\n", error_description(errno)));
  383.       MoveCursor(LINES, 0);
  384.       Raw(OFF);
  385.       printf(catgets(elm_msg_cat, ElmSet, ElmLeaveErrorCreatingLock,
  386.       "\nError encountered while attempting to create lock file %s;\n"),
  387.         lockfile);
  388.       printf("** %s. **\n\n", error_description(errno));
  389. #ifdef SAVE_GROUP_MAILBOX_ID
  390.       setgid(groupid);
  391. #endif
  392.       leave(0);
  393.     }
  394. #else
  395.     /* Okay...we die and leave, not updating the mailfile mbox or
  396.        any of those! */
  397.  
  398.     MoveCursor(LINES, 0);
  399.     Raw(OFF);
  400.     if (direction == INCOMING) {
  401.       printf(catgets(elm_msg_cat, ElmSet, ElmLeaveGivingUp,
  402.         "\n\nGiving up after %d iterations.\n"), 
  403.         create_iteration);
  404.       printf(catgets(elm_msg_cat, ElmSet, ElmLeavePleaseTryAgain,
  405.       "\nPlease try to read your mail again in a few minutes.\n\n"));
  406.       dprint(1, (debugfile, 
  407.         "Warning: bailing out after %d iterations...(lock)\n",
  408.         create_iteration));
  409. #ifdef SAVE_GROUP_MAILBOX_ID
  410.       setgid(groupid);
  411. #endif
  412.       leave_locked(0);
  413.     } else {
  414.       dprint(1, (debugfile, 
  415.        "Warning: after %d iterations, timed out! (lock)\n",
  416.        create_iteration));
  417. #ifdef SAVE_GROUP_MAILBOX_ID
  418.       setgid(groupid);
  419. #endif
  420.       printf(catgets(elm_msg_cat, ElmSet, ElmLeaveErrorTimedOutLock,
  421.         "Timed out on locking mailbox.  Leaving program.\n"));
  422.       leave(0);
  423.     }
  424. #endif
  425.       }
  426.  
  427.       /* If we're here we successfully created the lock file */
  428.       dprint(5,
  429.     (debugfile, "Lock %s %s for file %s on.\n", lockfile,
  430.     (direction == INCOMING ? "incoming" : "outgoing"), cur_folder));
  431.  
  432.       /* Place the pid of Elm into the lock file for SVR3.2 and its ilk */
  433.       sprintf(pid_buffer, "%d", getpid());
  434.       write(create_fd, pid_buffer, strlen(pid_buffer));
  435.  
  436.       (void)close(create_fd);
  437. #ifdef SAVE_GROUP_MAILBOX_ID
  438.       setgid(groupid);
  439. #endif
  440. #endif    /* } USE_DOTLOCK_LOCKING */
  441.                    
  442. #ifdef SYSCALL_LOCKING
  443.       /* Now we also need to lock the file with flock(2) */
  444.  
  445.       /* Open mail file separately for locking */
  446.       if((flock_fd = open(cur_folder, O_RDWR)) < 0) {
  447.     dprint(1, (debugfile, 
  448.         "Error encountered attempting to reopen %s for lock\n", cur_folder));
  449.     dprint(1, (debugfile, "** %s **\n", error_description(errno)));
  450.     MoveCursor(LINES, 0);
  451.     Raw(OFF);
  452.     printf(catgets(elm_msg_cat, ElmSet, ElmLeaveErrorReopenMailbox,
  453.  "\nError encountered while attempting to reopen mailbox %s for lock;\n"), 
  454.           cur_folder);
  455.     printf("** %s. **\n\n", error_description(errno));
  456. #ifdef    USE_DOTLOCK_LOCKING
  457.     (void)unlink(lockfile);
  458. #endif /* USE_DOTLOCK_LOCKING */
  459.     leave(0);
  460.       }
  461.  
  462.       /* try to assert lock MAX_ATTEMPTS times */
  463.       do {
  464.  
  465.     switch (Grab_the_file (flock_fd)) {
  466.  
  467.     case    FLOCKING_OK:
  468.         goto    EXIT_RETRY_LOOP;
  469.  
  470.     case    FLOCKING_FAIL:
  471.         /*
  472.          *    Creation of lock failed
  473.          *    NOT because it already exists!!!
  474.          */
  475.  
  476.         dprint (1, (debugfile, 
  477.             "Error encountered attempting to flock %s\n",
  478.             cur_folder));
  479.         dprint (1, (debugfile, "** %s **\n", error_description(errno)));
  480.         MoveCursor(LINES, 0);
  481.         Raw(OFF);
  482.         printf (catgets(elm_msg_cat, ElmSet, ElmLeaveErrorFlockMailbox,
  483.      "\nError encountered while attempting to flock mailbox %s;\n"), 
  484.           cur_folder);
  485.         printf("** %s. **\n\n", error_description(errno));
  486. #ifdef    USE_DOTLOCK_LOCKING
  487.         (void)unlink(lockfile);
  488. #endif /* USE_DOTLOCK_LOCKING */
  489.         leave(0);
  490.  
  491.         break;
  492.  
  493.     case    FLOCKING_RETRY:
  494.     default:
  495.         dprint (2, (debugfile,
  496.           "Mailbox '%s' already locked!  Waiting...(lock)\n", cur_folder));
  497.         error1 (catgets(elm_msg_cat, ElmSet, ElmLeaveWaitingToRead,
  498.                "Waiting to read mailbox while mail is being received: attempt #%d"),
  499.             flock_iteration);
  500.         sleep(5);
  501.     }
  502.       } while (flock_iteration++ < MAX_ATTEMPTS);
  503.  
  504. EXIT_RETRY_LOOP:
  505.       clear_error();
  506.  
  507.       if(errno != 0) {
  508.  
  509.     MoveCursor(LINES, 0);
  510.     Raw(OFF);
  511.     /* We couldn't lock the file. We die and leave not updating
  512.      * the mailfile mbox or any of those! */
  513.  
  514.     if (direction == INCOMING) {
  515.       printf(catgets(elm_msg_cat, ElmSet, ElmLeaveGivingUp,
  516.         "\n\nGiving up after %d iterations.\n"), 
  517.         flock_iteration);
  518.       printf(catgets(elm_msg_cat, ElmSet, ElmLeavePleaseTryAgain,
  519.       "\nPlease try to read your mail again in a few minutes.\n\n"));
  520.       dprint(1, (debugfile, 
  521.         "Warning: bailing out after %d iterations...(lock)\n",
  522.         flock_iteration));
  523.     } else {
  524.       dprint(1, (debugfile, 
  525.        "Warning: after %d iterations, timed out! (lock)\n",
  526.        flock_iteration));
  527.     }
  528. #ifdef    USE_DOTLOCK_LOCKING
  529.     (void)unlink(lockfile);
  530. #endif
  531.     printf(catgets(elm_msg_cat, ElmSet, ElmLeaveErrorTimedOutLock,
  532.         "Timed out on locking mailbox.  Leaving program.\n"));
  533.     leave(0);
  534.       }
  535.  
  536.       /* We locked the file */
  537.       dprint(5,
  538.     (debugfile, "Lock %s on file %s on.\n",
  539.     (direction == INCOMING ? "incoming" : "outgoing"), cur_folder));
  540. #endif /* SYSCALL_LOCKING */
  541.  
  542.       dprint(5,
  543.     (debugfile, "Lock %s for file %s on successfully.\n",
  544.     (direction == INCOMING ? "incoming" : "outgoing"), cur_folder));
  545.       lock_state = ON;
  546.       return(0);
  547. }
  548.  
  549. int
  550. unlock()
  551. {
  552.     /** Remove the lock file!    This must be part of the interrupt
  553.         processing routine to ensure that the lock file is NEVER
  554.         left sitting in the mailhome directory!
  555.  
  556.         If also using flock(), remove the file lock as well.
  557.      **/
  558.  
  559.     int retcode = 0;
  560.  
  561. #ifndef USE_DOTLOCK_LOCKING
  562.     dprint(5,
  563.       (debugfile, "Lock (no .lock) for file %s %s off.\n",
  564.         cur_folder, (lock_state == ON ? "going" : "already")));
  565. #else   /* USE_DOTLOCK_LOCKING */
  566.     dprint(5,
  567.       (debugfile, "Lock %s for file %s %s off.\n",
  568.          (lockfile ? lockfile : "none"),
  569.         cur_folder,
  570.         (lock_state == ON ? "going" : "already")));
  571. #endif  /* USE_DOTLOCK_LOCKING */
  572.  
  573.     if(lock_state == ON) {
  574.  
  575. #ifdef SYSCALL_LOCKING
  576.         if (retcode = Release_the_file (flock_fd)) {
  577.  
  578.         dprint(1, (debugfile,
  579.                "Error %s\n\ttrying to unlock file %s (%s)\n", 
  580.                error_description(errno), cur_folder, "unlock"));
  581.  
  582.         /* try to force unlock by closing file */
  583.         if (close (flock_fd) == -1) {
  584.             dprint (1, (debugfile,
  585.           "Error %s\n\ttrying to force unlock file %s via close() (%s)\n", 
  586.                 error_description(errno),
  587.                 cur_folder, "unlock"));
  588.             error1 (catgets (elm_msg_cat, ElmSet,
  589.                      ElmLeaveCouldntUnlockOwnMailbox,
  590.                      "Couldn't unlock my own mailbox %s!"),
  591.                      cur_folder);
  592.             return(retcode);
  593.         }
  594.         }
  595.         (void)close(flock_fd);
  596. #endif
  597. #ifndef    USE_DOTLOCK_LOCKING    /* { USE_DOTLOCK_LOCKING */
  598.        lock_state = OFF;        /* indicate we don't have a lock on */
  599. #else
  600. #ifdef SAVE_GROUP_MAILBOX_ID
  601.       setgid(mailgroupid);
  602. #endif
  603.       if((retcode = unlink(lockfile)) == 0) {    /* remove lock file */
  604.         *lockfile = '\0';        /* null lock file name */
  605.         lock_state = OFF;        /* indicate we don't have a lock on */
  606.       } else {
  607.         dprint(1, (debugfile,
  608.           "Error %s\n\ttrying to unlink file %s (%s)\n", 
  609.           error_description(errno), lockfile,"unlock"));
  610.           error1(catgets(elm_msg_cat, ElmSet, ElmLeaveCouldntRemoveOwnLock,
  611.         "Couldn't remove my own lock file %s!"), lockfile);
  612.       }
  613. #ifdef SAVE_GROUP_MAILBOX_ID
  614.       setgid(groupid);
  615. #endif
  616. #endif    /* } !USE_DOTLOCK_LOCKING */
  617.     }
  618.     return(retcode);
  619. }
  620.