home *** CD-ROM | disk | FTP | other *** search
/ IBM Presents OS/2 Software Hits 1995 / OS-2_SW_HITS_2ND_EDITION_1995.ISO / i17 / lwp42n.exe / BWLOCK.C next >
C/C++ Source or Header  |  1994-10-05  |  18KB  |  735 lines

  1. #define VERSION  "3.1c"
  2. /*
  3.     BWNFSD is an RPC daemon used in conjunction with BWNFS (a client NFS
  4. for DOS based PCs. BWNFSD provides Authentication, Print Spooling,
  5. DOS 3.1 Locking, DOS 3.1 Sharing, GID name mapping, UID name mapping services
  6. for BWNFS and associated applications on the PC. BWNFSD is being used also
  7. by Macintosh NFS clients.
  8.  
  9.     The BWNFSD code is originally copyright Beame & Whiteside Software Ltd.
  10. and now is released to the Public Domain. The intent is that all server vendors
  11. included a version of BWNFSD with their operating system. BWNFSD can run
  12. simultanteously with PCNFSD, but provides more features.
  13.  
  14.     Please send modifications to:
  15.  
  16.         Beame & Whiteside Software, Inc.
  17.         706 Hillsborough St.
  18.         Raleigh, North Carolina
  19.         USA 27603-1655
  20.         +1 (919) 831-8989
  21.         support@bws.com
  22.  
  23.     Please modify by including "ifdefs" for your particular operating
  24. system, with appropriate modifications to the "makefile".
  25.  
  26. BWLOCK.C provides the locking and sharing service for BWNFS. This should be
  27. used if rpc.lockd does not include the extensions for DOS 3.1 locking or
  28. sharing, or if your system has the regular distribution of the rpc.lockd as
  29. the extensions most likely will not work.
  30.  
  31. One might want to make operating system calls to lock and unlock the files
  32. so that locking occurs not only against other BWNFS clients, but native
  33. clients as well.
  34.  
  35. MODIFICATION HISTORY
  36. --------------------
  37. 31/07/92 fjw  Cleaned up the code a little
  38. 01/08/92 fjw  Merged in SVR4 code from Frank Glass (gatech!holos0!fsg)
  39. 19/10/92 fjw  Changed code to use some manifest constants
  40. 05/11/92 fjw  Punched up some of the debug output
  41. 17/12/93 fjw  Changed some IFDEF names for clarity
  42. 09/02/94 fjw  Added code to allow locks/file/process to be removed
  43. */
  44.  
  45. /*
  46.  * HASH_LOCATION is a number between 0 and FHSIZE-1 inclusive. It should be
  47.  * set to the position in the file handle FHSIZE byte structure which
  48.  * changes the most between different files.
  49.  */
  50. #define HASH_LOCATION    17
  51.  
  52. #define LOCK_SHARE    20
  53. #define LOCK_UNSHARE    21
  54. #define LOCK_LOCK    22
  55. #define LOCK_REMOVE_ALL 23
  56. #define LOCK_UNLOCK    24
  57. #define LOCK_BREAK_FH    101        /* break all locks held on FH */
  58. #define LOCK_BREAK_IP    102        /* break all locks held by IP */
  59. #define LOCK_ZAP_LOCKS    105        /* remove locks on file by process */
  60.  
  61. #include <stdio.h>
  62. #include <signal.h>
  63. #include <string.h>
  64. #ifdef USE_BCOPY
  65. #define memcmp(a,b,c) bcmp((b),(a),(c))
  66. #define memcpy(a,b,c) bcopy((b),(a),(c))
  67. #else
  68. #include <memory.h>
  69. #endif
  70.  
  71. #ifdef INT_SIG
  72. #define Void int
  73. #define Return return(0)
  74. #else
  75. #define Void void
  76. #define Return return
  77. #endif
  78.  
  79. #define LOCK    'L'
  80. #define SHARE    'S'
  81.               /*          1st Open           */
  82.               /* ALL     DR    DW     DRW   COMP  */
  83.               /* I O B    I O B  I O B  I O B  I O B */
  84. char shares[15][15] = { {1,1,1, 0,0,0, 1,1,1, 0,0,0, 0,0,0}, /* I */
  85.             {1,1,1, 1,1,1, 0,0,0, 0,0,0, 0,0,0}, /* O  ALL */
  86.             {1,1,1, 0,0,0, 0,0,0, 0,0,0, 0,0,0}, /* B */
  87.             {0,1,0, 0,0,0, 0,1,0, 0,0,0, 0,0,0}, /* I */
  88.             {0,1,0, 0,1,0, 0,0,0, 0,0,0, 0,0,0}, /* O  DR */
  89.             {0,1,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0}, /* B */
  90.             {1,0,0, 0,0,0, 1,0,0, 0,0,0, 0,0,0}, /* I */
  91.             {1,0,0, 1,0,0, 0,0,0, 0,0,0, 0,0,0}, /* O DW 2nd Open */
  92.             {1,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0}, /* B */
  93.             {0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0}, /* I */
  94.             {0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0}, /* O  DRW */
  95.             {0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0}, /* B */
  96.             {0,0,0, 0,0,0, 0,0,0, 0,0,0, 1,1,1}, /* I */
  97.             {0,0,0, 0,0,0, 0,0,0, 0,0,0, 1,1,1}, /* O  COMP */
  98.             {0,0,0, 0,0,0, 0,0,0, 0,0,0, 1,1,1}  /* B */
  99. };
  100.  
  101. struct LK {
  102.     char type;
  103.     struct LK *nxt;
  104.     struct LK *prv;
  105.     struct LK *nxt_fh;
  106.     struct LK *prv_fh;
  107.     struct FH *fh;
  108.     struct PC *pc;
  109.     union {
  110.         struct {
  111.             char mode;
  112.             char access;
  113.         } s;
  114.         struct {
  115.             unsigned long offset;
  116.             unsigned long length;
  117.             unsigned long lockowner;
  118.         } l;
  119.     } lock;
  120. };
  121.  
  122. #define FHSIZE 32
  123. struct FH {
  124.     char fh[FHSIZE];
  125.     struct LK *lock;
  126.     struct FH *nxt;
  127.     struct FH *prv;
  128. };
  129.  
  130. struct PC {
  131.     char *owner;
  132.     struct PC *nxt;
  133.     struct PC *prv;
  134.     struct LK *lock;
  135.     unsigned long last_cookie;
  136.     int last_result;
  137. };
  138.  
  139. #define NUM_PCS 256
  140. #define NUM_FHS NUM_PCS
  141.  
  142. struct PC *pcs[NUM_PCS];
  143. struct FH *fhs[NUM_FHS];
  144. extern int debugmode;
  145.  
  146. char *
  147. requestname(req)
  148.     int req;
  149. {
  150. static char buff[100];
  151.  
  152.     switch(req) {
  153.     case LOCK_SHARE:
  154.         strcpy(buff, "Share file");
  155.         break;
  156.     case LOCK_UNSHARE:
  157.         strcpy(buff, "UnShare file");
  158.         break;
  159.     case LOCK_LOCK:
  160.         strcpy(buff, "Lock file");
  161.         break;
  162.     case LOCK_REMOVE_ALL:
  163.         strcpy(buff, "Remove all locks/shares held by owner");
  164.         break;
  165.     case LOCK_UNLOCK:
  166.         strcpy(buff, "UnLock file");
  167.         break;
  168.     case LOCK_BREAK_FH:
  169.         strcpy(buff, "Break all Locks/Shares on file");
  170.         break;
  171.     case LOCK_BREAK_IP:
  172.         strcpy(buff, "Break all Locks/Shares held by owner's IP");
  173.         break;
  174.     case LOCK_ZAP_LOCKS:
  175.         strcpy(buff, "Remove all locks on file by process");
  176.         break;
  177.     default:
  178.         sprintf(buff, "Unknown request - %d", req);
  179.         break;
  180.     }
  181.     return(buff);
  182. }
  183.  
  184. char *
  185. accessname(acc)
  186.     int acc;
  187. {
  188. static char buff[30];
  189.  
  190.     switch(acc) {
  191.     case 1:
  192.         strcpy(buff, "Input");
  193.         break;
  194.     case 2:
  195.         strcpy(buff, "Output");
  196.         break;
  197.     case 3:
  198.         strcpy(buff, "Input/Output");
  199.         break;
  200.     default:
  201.         sprintf(buff, "Unknown access value - %d", acc);
  202.         break;
  203.     }
  204.     return(buff);
  205. }
  206.  
  207. char *
  208. modename(mode)
  209.     int mode;
  210. {
  211. static char buff[30];
  212.  
  213.     switch(mode) {
  214.     case 0:
  215.         strcpy(buff, "Deny None");
  216.         break;
  217.     case 1:
  218.         strcpy(buff, "Deny Read");
  219.         break;
  220.     case 2:
  221.         strcpy(buff, "Deny Write");
  222.         break;
  223.     case 3:
  224.         strcpy(buff, "Deny Read/Write");
  225.         break;
  226.     case 4:
  227.         strcpy(buff, "Compatibility");
  228.         break;
  229.     default:
  230.         sprintf(buff, "Unknown mode value - %d", mode);
  231.         break;
  232.     }
  233.     return(buff);
  234. }
  235.  
  236. char
  237. *my_strdup(p)
  238.     char *p;
  239. {
  240. char *p1;
  241.  
  242.     if ((p1=(char *) malloc(strlen(p)+1)) == NULL)
  243.         return(NULL);
  244.     return(strcpy(p1,p));
  245. }
  246.  
  247. Void
  248. display_locks(unused)
  249.     int unused;
  250. {
  251. int i, j;
  252. struct PC *pc1;
  253. struct LK *lk1;
  254. struct FH *fh1;
  255. FILE *lock_file;
  256.  
  257. #ifdef SIGUSR1
  258.     (void) signal(SIGUSR1, display_locks);
  259. #endif
  260.     if ((lock_file=fopen("/etc/bwlocks.dmp","w")) == NULL)
  261.         Return;
  262.     for (i=0; i<NUM_PCS; i++) {
  263.         pc1 = pcs[i];
  264.         while (pc1 != NULL) {
  265.             j = 0;
  266.             fprintf(lock_file,"%3d %s -> ", i, pc1->owner);
  267.             lk1 = pc1->lock;
  268.             while (lk1 != NULL) {
  269.                 fprintf(lock_file, "%c/%3u/", lk1->type, (lk1->fh)->fh[HASH_LOCATION] & 0xff);
  270.                 if (lk1->type == SHARE) {
  271.                     fprintf(lock_file, "%1d -> ", lk1->lock.s.mode);
  272.                     j += 11;
  273.                 } else {
  274.                     fprintf(lock_file, "%3ld+%3ld(%3ld) -> ", lk1->lock.l.offset, lk1->lock.l.length, lk1->lock.l.lockowner);
  275.                     j += 17;
  276.                 }
  277.                 if (j > 70) {
  278.                     fprintf(lock_file, "\n                ");
  279.                     j = 0;
  280.                 }
  281.                 lk1 = lk1->nxt;
  282.             }
  283.             fprintf(lock_file, "NULL\n");
  284.             pc1 = pc1->nxt;
  285.         }
  286.     }
  287.     fprintf(lock_file, "File Handles\n");
  288.     for (i=0; i<NUM_FHS; i++) {
  289.         fh1 = fhs[i];
  290.         while (fh1 != NULL) {
  291.             fprintf(lock_file, "%3d ", i);
  292.             for (j=0; j<FHSIZE; j++)
  293.                    fprintf(lock_file, "%02X", fh1->fh[j] & 0xff);
  294.             fprintf(lock_file, " -> ");
  295.             j = 0;
  296.             lk1 = fh1->lock;
  297.             while (lk1 != NULL) {
  298.                 fprintf(lock_file, "%c/%3u/",lk1->type,*(lk1->pc)->owner & 0xff);
  299.                 if (lk1->type == SHARE) {
  300.                     fprintf(lock_file, "%1d -> ", lk1->lock.s.mode);
  301.                     j += 11;
  302.                 } else {
  303.                     fprintf(lock_file, "%3ld+%3ld(%3ld) -> ", lk1->lock.l.offset, lk1->lock.l.length, lk1->lock.l.lockowner);
  304.                     j += 17;
  305.                 }
  306.                 if (j > 70) {
  307.                     fprintf(lock_file, "\n                ");
  308.                     j = 0;
  309.                 }
  310.                 lk1 = lk1->nxt_fh;
  311.             }
  312.             fprintf(lock_file, "NULL\n");
  313.             fh1 = fh1->nxt;
  314.         }
  315.     }
  316.     fclose(lock_file);
  317.     Return;
  318. }
  319.  
  320. void
  321. init_locks()
  322. {
  323. int i;
  324.  
  325.     if (debugmode)
  326.         fprintf(stdout, "bwnfsd: [init_locks] called\n");
  327.     for (i=0; i<NUM_PCS; i++)
  328.         pcs[i] = NULL;
  329.     for (i=0; i<NUM_FHS; i++)
  330.         fhs[i] = NULL;
  331. #ifdef SIGUSR1
  332.     (void) signal(SIGUSR1, display_locks);
  333. #endif
  334. }
  335.  
  336. #define TRUE  1
  337. #define FALSE 0
  338.  
  339. static int pc_ptr, fh_ptr;
  340.  
  341. struct PC *
  342. locate_by_owner(owner)
  343.     char *owner;
  344. {
  345. struct PC *p;
  346.  
  347.     if (debugmode)
  348.         fprintf(stdout, "bwnfsd: [locate_by_owner] called for %s\n", owner);
  349.     p = pcs[pc_ptr];
  350.     while (p != NULL) {
  351.         if (debugmode)
  352.             fprintf(stdout, "bwnfsd: [locate_by_owner] owner is %s\n", p->owner);
  353.         if (strcmp(p->owner,owner) == 0)
  354.             return(p);
  355.         else
  356.             p = p->nxt;
  357.     }
  358.     return(p);
  359. }
  360.  
  361. struct FH *
  362. locate_by_handle(fh)
  363.     char *fh;
  364. {
  365. struct FH *p;
  366.  
  367.     if (debugmode)
  368.         fprintf(stdout, "bwnfsd: [locate_by_handle] called\n");
  369.     p = fhs[fh_ptr];
  370.     while (p != NULL)
  371.         if (memcmp(p->fh, fh, FHSIZE) == 0)
  372.             return(p);
  373.         else
  374.             p = p->nxt;
  375.     return(p);
  376. }
  377.  
  378. int
  379. process_lock_request(request, owner, fh, access, mode, offset, length, cookie, lockowner)
  380.     int request;
  381.     char *fh, *owner;
  382.     int access, mode;
  383.     unsigned long length, offset;
  384.     unsigned long cookie, lockowner;
  385. {
  386. struct PC *pc1;
  387. struct LK *lk1;
  388. struct LK *lk2;
  389. struct FH *fh1;
  390. int j, len;
  391.  
  392.     if (debugmode) {
  393.         fprintf(stdout, "bwnfsd: [process_lock_request] called with\n");
  394.         fprintf(stdout, "bwnfsd: request     = %s\n", requestname(request));
  395.         fprintf(stdout, "bwnfsd: owner       = %s\n", owner);
  396.         fprintf(stdout, "bwnfsd: file_handle = ");
  397.         for (j=0; j<FHSIZE; j++)
  398.             fprintf(stdout, "%02X", fh[j] & 0xff);
  399.         fprintf(stdout,"\n");
  400.         fprintf(stdout, "bwnfsd: access      = %s\n", accessname(access));
  401.         fprintf(stdout, "bwnfsd: mode        = %s\n", modename(mode));
  402.         fprintf(stdout, "bwnfsd: offset      = %lu\n", offset);
  403.         fprintf(stdout, "bwnfsd: length      = %lu\n", length);
  404.         fprintf(stdout, "bwnfsd: cookie      = %lu\n", cookie);
  405.         fprintf(stdout, "bwnfsd: lockowner   = %lu\n", lockowner);
  406.     }
  407.     if (owner == NULL)
  408.         len = 0;
  409.     else
  410.         len = strlen(owner);
  411.     if (len == 0)
  412.         pc_ptr = 0;
  413.     else
  414.         if (len == 1)
  415.             pc_ptr = *(owner+len-1) & 0xff;
  416.         else
  417.             pc_ptr = (*(owner+len-1) ^ *(owner+len-2)) & 0xff;
  418.  
  419.     if (request != LOCK_REMOVE_ALL)  {
  420.         if ((pc1=locate_by_owner(owner)) == NULL) {
  421.             if ((pc1=(struct PC *) malloc(sizeof(struct PC))) == NULL)
  422.                 return(FALSE);
  423.             pc1->owner = my_strdup(owner);
  424.             pc1->lock = NULL;
  425.             pc1->prv = NULL;
  426.             pc1->nxt = pcs[pc_ptr];
  427.             pc1->last_cookie = cookie-1;
  428.             pcs[pc_ptr] = pc1;
  429.             if ((pc1->nxt) != NULL)
  430.                 (pc1->nxt)->prv = pc1;
  431.         }
  432.         if (pc1->last_cookie == cookie)
  433.             return(pc1->last_result);
  434.         pc1->last_cookie = cookie;
  435.     }
  436.     switch(request) {
  437.     case LOCK_SHARE:
  438.         fh_ptr = fh[HASH_LOCATION] & 0xff;
  439.         if ((fh1=locate_by_handle(fh)) == NULL) {
  440.             if ((fh1=(struct FH *) malloc(sizeof(struct FH))) == NULL) {
  441.                 pc1->last_result = FALSE;
  442.                 return(FALSE);
  443.             }
  444.             (void) memcpy(fh1->fh,fh,FHSIZE);
  445.             fh1->lock = NULL;
  446.             fh1->prv = NULL;
  447.             fh1->nxt = fhs[fh_ptr];
  448.             fhs[fh_ptr] = fh1;
  449.             if ((fh1->nxt) != NULL)
  450.                    (fh1->nxt)->prv = fh1;
  451.         }
  452.         lk1 = fh1->lock;
  453.         while (lk1 != NULL) {
  454.             if (lk1->type == SHARE) {
  455.                 if (!shares[mode*3+access-1][lk1->lock.s.mode*3+lk1->lock.s.access-1]) {
  456.                     pc1->last_result = FALSE;
  457.                     return(FALSE);
  458.                 }
  459.             }
  460.             lk1 = lk1->nxt_fh;
  461.         }
  462.         if ((lk1=(struct LK *) malloc(sizeof(struct LK))) == NULL) {
  463.             pc1->last_result = FALSE;
  464.             return(FALSE);
  465.         }
  466.         lk1->fh = fh1;
  467.         lk1->pc = pc1;
  468.         lk1->type = SHARE;
  469.         lk1->lock.s.mode = mode;
  470.         lk1->lock.s.access = access;
  471.         lk1->prv = NULL;
  472.         lk1->prv_fh = NULL;
  473.         if ((lk1->nxt=pc1->lock) != NULL)
  474.             (lk1->nxt)->prv = lk1;
  475.         pc1->lock = lk1;
  476.         if ((lk1->nxt_fh=fh1->lock) != NULL)
  477.             (lk1->nxt_fh)->prv_fh = lk1;
  478.         fh1->lock = lk1;
  479.         pc1->last_result = TRUE;
  480.         return(TRUE);
  481.     case LOCK_UNSHARE:
  482.         fh_ptr = fh[HASH_LOCATION] & 0xff;
  483.         if ((fh1=locate_by_handle(fh)) == NULL) {
  484.             pc1->last_result = TRUE;
  485.             return(TRUE);
  486.         }
  487.         lk1 = fh1->lock;
  488.         while (lk1 != NULL) {
  489.             if ((lk1->pc == pc1) &&
  490.                 (lk1->type == SHARE) &&
  491.                 (mode == lk1->lock.s.mode) &&
  492.                 (access == lk1->lock.s.access))
  493.             {
  494.                 if ((lk1->prv_fh) == NULL) {
  495.                     if ((fh1->lock=lk1->nxt_fh) == NULL) {
  496.                         if (fh1->prv == NULL) {
  497.                             if ((fhs[fh_ptr]=fh1->nxt) != NULL)
  498.                                 (fh1->nxt)->prv = NULL;
  499.                         } else {
  500.                             if (((fh1->prv)->nxt=fh1->nxt) != NULL)
  501.                                 (fh1->nxt)->prv = fh1->prv;
  502.                         }
  503.                         free(fh1);
  504.                     } else
  505.                         (fh1->lock)->prv_fh = NULL;
  506.                 } else {
  507.                     if (((lk1->prv_fh)->nxt_fh=lk1->nxt_fh) != NULL)
  508.                         (lk1->nxt_fh)->prv_fh = lk1->prv_fh;
  509.                 }
  510.                 if ((lk1->prv) == NULL) {
  511.                     if ((pc1->lock=lk1->nxt) == NULL) {
  512.                         if (pc1->prv == NULL) {
  513.                             if ((pcs[pc_ptr]=pc1->nxt) != NULL)
  514.                                 (pc1->nxt)->prv = NULL;
  515.                         } else {
  516.                             if (((pc1->prv)->nxt=pc1->nxt) != NULL)
  517.                                 (pc1->nxt)->prv = pc1->prv;
  518.                         }
  519.                         free(pc1->owner);
  520.                         free(pc1);
  521.                         pc1 = NULL;
  522.                     } else
  523.                         (pc1->lock)->prv = NULL;
  524.                 } else {
  525.                     if (((lk1->prv)->nxt=lk1->nxt) != NULL)
  526.                         (lk1->nxt)->prv = lk1->prv;
  527.                 }
  528.                 free(lk1);
  529.                 if (pc1 != NULL)
  530.                     pc1->last_result = TRUE;
  531.                 return(TRUE);
  532.             }
  533.             lk1 = lk1->nxt_fh;
  534.         }
  535.         if (pc1 != NULL)
  536.             pc1->last_result = TRUE;
  537.         return(TRUE);
  538.     case LOCK_LOCK:
  539.         fh_ptr = fh[HASH_LOCATION] & 0xff;
  540.         if ((fh1=locate_by_handle(fh)) == NULL) {
  541.             if ((fh1=(struct FH *) malloc(sizeof(struct FH))) == NULL) {
  542.                 pc1->last_result = FALSE;
  543.                 return(FALSE);
  544.             }
  545.             (void) memcpy(fh1->fh,fh,FHSIZE);
  546.             fh1->lock = NULL;
  547.             fh1->prv = NULL;
  548.             fh1->nxt = fhs[fh_ptr];
  549.             fhs[fh_ptr] = fh1;
  550.             if ((fh1->nxt) != NULL)
  551.                 (fh1->nxt)->prv = fh1;
  552.         }
  553.         lk1 = fh1->lock;
  554.         while (lk1 != NULL) {
  555.             if (lk1->type == LOCK)
  556.                 if (((lk1->lock.l.offset >= offset) &&
  557.                       (offset+length > lk1->lock.l.offset)) ||
  558.                      ((lk1->lock.l.offset < offset) &&
  559.                       (lk1->lock.l.offset + lk1->lock.l.length > offset)))
  560.                 {
  561.                     pc1->last_result = FALSE;
  562.                     return(FALSE);
  563.                 }
  564.             lk1 = lk1->nxt_fh;
  565.         }
  566.         if ((lk1=(struct LK *) malloc(sizeof(struct LK))) == NULL) {
  567.             pc1->last_result = FALSE;
  568.             return(FALSE);
  569.         }
  570.         lk1->fh = fh1;
  571.         lk1->pc = pc1;
  572.         lk1->type = LOCK;
  573.         lk1->lock.l.offset = offset;
  574.         lk1->lock.l.length = length;
  575.         lk1->lock.l.lockowner = lockowner;
  576.         lk1->prv = NULL;
  577.         lk1->prv_fh = NULL;
  578.         if ((lk1->nxt=pc1->lock) != NULL)
  579.             (lk1->nxt)->prv = lk1;
  580.         pc1->lock = lk1;
  581.         if ((lk1->nxt_fh=fh1->lock) != NULL)
  582.             (lk1->nxt_fh)->prv_fh = lk1;
  583.         fh1->lock = lk1;
  584.         pc1->last_result = TRUE;
  585.         return(TRUE);
  586.     case LOCK_ZAP_LOCKS:
  587.         fh_ptr = fh[HASH_LOCATION] & 0xff;
  588.         if ((fh1=locate_by_handle(fh)) == NULL)
  589.             return(TRUE);
  590.         lk1 = fh1->lock;
  591.         while (lk1 != NULL) {
  592.             if ((lk1->type != LOCK) || (lk1->lock.l.lockowner != lockowner)) {
  593.                 lk1 = lk1->nxt;
  594.                 continue;
  595.             }
  596.             if ((lk1->prv_fh) == NULL) {
  597.                 if ((fh1->lock=lk1->nxt_fh) == NULL) {
  598.                     if (fh1->prv == NULL) {
  599.                         if ((fhs[fh_ptr]=fh1->nxt) != NULL)
  600.                             (fh1->nxt)->prv = NULL;
  601.                     } else {
  602.                         if (((fh1->prv)->nxt=fh1->nxt) != NULL)
  603.                             (fh1->nxt)->prv = fh1->prv;
  604.                     }
  605.                     free(fh1);
  606.                 } else
  607.                     (fh1->lock)->prv_fh = NULL;
  608.             } else {
  609.                 if (((lk1->prv_fh)->nxt_fh=lk1->nxt_fh) != NULL)
  610.                     (lk1->nxt_fh)->prv_fh = lk1->prv_fh;
  611.             }
  612.             if ((lk1->prv) == NULL) {
  613.                 if ((pc1->lock=lk1->nxt) == NULL) {
  614.                     if (pc1->prv == NULL) {
  615.                         if ((pcs[pc_ptr]=pc1->nxt) != NULL)
  616.                             (pc1->nxt)->prv = NULL;
  617.                     } else {
  618.                         if (((pc1->prv)->nxt=pc1->nxt) != NULL)
  619.                             (pc1->nxt)->prv = pc1->prv;
  620.                     }
  621.                     free(pc1->owner);
  622.                     free(pc1);
  623.                     pc1 = NULL;
  624.                 } else
  625.                     (pc1->lock)->prv = NULL;
  626.             } else {
  627.                 if (((lk1->prv)->nxt=lk1->nxt) != NULL)
  628.                     (lk1->nxt)->prv = lk1->prv;
  629.             }
  630.             lk2 = lk1->nxt;
  631.             free(lk1);
  632.             lk1 = lk2;
  633.         }
  634.         if (pc1 != NULL)
  635.             pc1->last_result = TRUE;
  636.         return(TRUE);
  637.     case LOCK_REMOVE_ALL:
  638.         if ((pc1=locate_by_owner(owner)) == NULL)
  639.             return(TRUE);
  640.         if (pc1->prv == NULL) {
  641.             if ((pcs[pc_ptr]=pc1->nxt) != NULL)
  642.                 (pc1->nxt)->prv = NULL;
  643.         } else {
  644.             if (((pc1->prv)->nxt=pc1->nxt) != NULL)
  645.                 (pc1->nxt)->prv = pc1->prv;
  646.         }
  647.         lk1 = pc1->lock;
  648.         while (lk1 != NULL) {
  649.             if ((lk1->prv_fh) == NULL) {
  650.                 fh1 = lk1->fh;
  651.                 if ((fh1->lock=lk1->nxt_fh) == NULL) {
  652.                     if (fh1->prv == NULL) {
  653.                         fh_ptr = fh1->fh[HASH_LOCATION] & 0xff;
  654.                         if ((fhs[fh_ptr]=fh1->nxt) != NULL)
  655.                             (fh1->nxt)->prv = NULL;
  656.                     } else {
  657.                         if (((fh1->prv)->nxt=fh1->nxt) != NULL)
  658.                             (fh1->nxt)->prv = fh1->prv;
  659.                     }
  660.                     free(fh1);
  661.                 } else
  662.                     (fh1->lock)->prv_fh = NULL;
  663.             } else
  664.                 if (((lk1->prv_fh)->nxt_fh=lk1->nxt_fh) != NULL)
  665.                     (lk1->nxt_fh)->prv_fh = lk1->prv_fh;
  666.             lk2 = lk1->nxt;
  667.             free(lk1);
  668.             lk1 = lk2;
  669.         }
  670.         free(pc1->owner);
  671.         free(pc1);
  672.         return(TRUE);
  673.     case LOCK_UNLOCK:
  674.         fh_ptr = fh[HASH_LOCATION] & 0xff;
  675.         if ((fh1=locate_by_handle(fh)) == NULL) {
  676.             pc1->last_result = TRUE;
  677.             return(TRUE);
  678.         }
  679.         lk1 = fh1->lock;
  680.         while (lk1 != NULL) {
  681.             if ((lk1->pc == pc1) &&
  682.                 (lk1->type == LOCK) &&
  683.                 (offset == lk1->lock.l.offset) &&
  684.                 (length == lk1->lock.l.length))
  685.             {
  686.                 if ((lk1->prv_fh) == NULL) {
  687.                     if ((fh1->lock=lk1->nxt_fh) == NULL) {
  688.                         if (fh1->prv == NULL) {
  689.                             if ((fhs[fh_ptr]=fh1->nxt) != NULL)
  690.                                 (fh1->nxt)->prv = NULL;
  691.                         } else {
  692.                             if (((fh1->prv)->nxt=fh1->nxt) != NULL)
  693.                                 (fh1->nxt)->prv = fh1->prv;
  694.                         }
  695.                         free(fh1);
  696.                     } else
  697.                         (fh1->lock)->prv_fh = NULL;
  698.                 } else {
  699.                     if (((lk1->prv_fh)->nxt_fh=lk1->nxt_fh) != NULL)
  700.                         (lk1->nxt_fh)->prv_fh = lk1->prv_fh;
  701.                 }
  702.                 if ((lk1->prv) == NULL) {
  703.                     if ((pc1->lock=lk1->nxt) == NULL) {
  704.                         if (pc1->prv == NULL) {
  705.                             if ((pcs[pc_ptr]=pc1->nxt) != NULL)
  706.                                 (pc1->nxt)->prv = NULL;
  707.                         } else {
  708.                             if (((pc1->prv)->nxt=pc1->nxt) != NULL)
  709.                                 (pc1->nxt)->prv = pc1->prv;
  710.                         }
  711.                         free(pc1->owner);
  712.                         free(pc1);
  713.                         pc1 = NULL;
  714.                     } else
  715.                         (pc1->lock)->prv = NULL;
  716.                 } else {
  717.                     if (((lk1->prv)->nxt=lk1->nxt) != NULL)
  718.                         (lk1->nxt)->prv = lk1->prv;
  719.                 }
  720.                 free(lk1);
  721.                 if (pc1 != NULL)
  722.                     pc1->last_result = TRUE;
  723.                 return(TRUE);
  724.             }
  725.             lk1 = lk1->nxt_fh;
  726.         }
  727.         if (pc1 != NULL)
  728.             pc1->last_result = TRUE;
  729.         return(TRUE);
  730.     }
  731.     if (pc1 != NULL)
  732.         pc1->last_result = FALSE;
  733.     return(FALSE);
  734. }
  735.