home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / UE311C.ZIP / DOLOCK.C < prev    next >
C/C++ Source or Header  |  1991-10-07  |  9KB  |  432 lines

  1. /*    DOLOCK.C:    Machine specific code for File Locking
  2.             for MicroEMACS
  3.             (C)Copyright 1987 by Daniel M Lawrence
  4. */
  5.  
  6. #include    <stdio.h>
  7. #include    "estruct.h"
  8. #include    "eproto.h"
  9. #include    "elang.h"
  10.  
  11. #if    WMCS
  12. /*    file locking for WMCS */
  13.  
  14. #include "sys$disk/sysincl.sys/sysequ.h"
  15. #include <stdio.h>
  16. #include <ctype.h>
  17.  
  18. char msg[] = TEXT35;
  19. /*           "another user" */
  20.  
  21. char *dolock(fname)
  22. char *fname;
  23. {
  24.     int lun,status;
  25.     status = _open(fname,OPREADACC|OPWRITEACC|OPWRITELOCK,-1,&lun);
  26.     if(status == 133 || status == 0 ) return(NULL);
  27.     return(msg);
  28. }
  29.  
  30. char *undolock(fname)
  31. char *fname;
  32. {
  33.     int i,j,k,lun,status;
  34.     char xname[95],c;
  35.     
  36.     for(lun=4; _getfnam(lun,xname) == 0; lun++) {
  37.         for(i=0;i<strlen(xname);i++)    {
  38.             k = i;
  39.             for(j=0;j<strlen(fname);j++)  {
  40.                 c = fname[j];
  41.                 if(islower(c)) c = toupper(c);
  42.                 if(c == xname[k]) { ++k; continue; }
  43.                 if(c == '\0') break;
  44.                 break;
  45.                 }
  46.             if(j == strlen(fname)) {
  47.                 _close(lun,0);
  48.                 return(NULL);
  49.                 }
  50.             }
  51.     }
  52.     return(NULL);
  53. }
  54. #endif
  55.  
  56. #if    FILOCK && (MSDOS || OS2 || SUN)
  57. #if    OS2 || (MSDOS && MSC)
  58. #include    <sys/types.h>
  59. #endif
  60. #include    <sys/stat.h>
  61. #include    <errno.h>
  62. #if    MSDOS && TURBO
  63. #include    <dir.h>
  64. #endif
  65. #if    SUN
  66. #include    <sys/dir.h>
  67. #include    <signal.h>
  68. #endif
  69.  
  70. #if    OS2 == 0
  71. #if    ZTC
  72. extern volatile int errno;
  73. #else
  74. extern int errno;
  75. #endif
  76. #endif
  77.  
  78. #define LOCKDIR "_xlk"
  79. #define LOCKMSG "LOCK ERROR -- "
  80. #define    LOCKDEBUG    FALSE
  81.  
  82. /*    dolock:    Generic non-UNIX file locking mechinism    */
  83.  
  84. /**********************
  85.  *
  86.  * dolock -- lock the file fname
  87.  *
  88.  * if successful, returns NULL 
  89.  * if file locked, returns username of person locking the file
  90.  * if other error, returns "LOCK ERROR: explanation"
  91.  *
  92.  *********************/
  93.  
  94. char *parse_name(filespec)        /* get name component of filespec */
  95.  
  96. char *filespec;
  97.  
  98. {
  99.     char *rname;
  100.  
  101.     rname = &filespec[strlen(filespec) - 1];
  102.     while (rname >= filespec) {
  103.         if (*rname == DIRSEPCHAR || *rname == DRIVESEPCHAR) {
  104.             ++rname;
  105.             break;
  106.         }
  107.         --rname;
  108.     }
  109.  
  110.     if (rname >= filespec)
  111.         return(rname);
  112.     else
  113.         return(filespec);
  114. }
  115.  
  116. char *parse_path(filespec)
  117.  
  118. char *filespec;
  119.  
  120. {
  121.     static char rbuff[NFILEN];
  122.     char *rname;
  123.  
  124.     /* make a copy we can mung */
  125.     strcpy(rbuff,filespec);
  126.  
  127.     /* starting from the end */
  128.     rname = &rbuff[strlen(rbuff)-1];
  129.  
  130.     /* scan for a directory separator */
  131.     while (rname >= rbuff) {
  132.         if (*rname == DIRSEPCHAR)
  133.             break;
  134.         --rname;
  135.     }
  136.  
  137.     /* no path here! */
  138.     if (rname < rbuff)
  139.         return("");
  140.  
  141.  
  142.     *(rname) = '\0';    /* point just beyond slash */
  143.  
  144.     /* no skip beyond any drive spec */
  145.     rname = rbuff;
  146.     while (*rname) {
  147.         if (*rname == DRIVESEPCHAR)
  148.             return(++rname);
  149.         ++rname;
  150.     }
  151.  
  152.     /* none to be found, return the whole string */
  153.     return(rbuff);
  154. }
  155.  
  156. char *parse_drive(filespec)
  157.  
  158. char *filespec;
  159.  
  160. {
  161.     static char rbuff[NFILEN];
  162.     char *rname;
  163.  
  164.     /* search for a drive specifier */
  165.     strcpy(rbuff,filespec);
  166.     rname = rbuff;
  167.     while (*rname) {
  168.         if (*rname == DRIVESEPCHAR) {
  169.             *(++rname) = 0;
  170.             return(rbuff);
  171.         }
  172.         ++rname;
  173.     }
  174.  
  175.     /* no drive letter/name */
  176.     return("");
  177. }
  178.  
  179. char *dolock(filespec)
  180.  
  181. char *filespec;        /* full file spec of file to lock */
  182.  
  183. {
  184.     struct stat sb;            /* stat buffer for info on files/dirs */
  185.     FILE *fp;            /* ptr to lock file */
  186.     long proc_id;            /* process id from lock file */
  187.     char filename[NFILEN];        /* name of file to lock */
  188.     char pathname[NFILEN];        /* path leading to file to lock */
  189.     char drivename[NFILEN];        /* drive for file to lock */
  190.     char lockpath[NFILEN];        /* lock directory name */
  191.     char lockfile[NFILEN];        /* lock file name */
  192.     char buf[NSTRING];        /* input buffer */
  193.     char host[NSTRING];        /* current host name */
  194.     static char result[NSTRING];    /* error return string */
  195.     char *getenv(); 
  196.  
  197.     /* separate filespec into components */
  198.     strcpy(filename, parse_name(filespec));
  199.     strcpy(pathname, parse_path(filespec));
  200.     strcpy(drivename, parse_drive(filespec));
  201.     if (pathname[0] == 0)
  202.         strcpy(pathname, ".");
  203.  
  204.     /* merge the drive into the pathname */
  205.     strcat(drivename, pathname);
  206.     strcpy(pathname, drivename);
  207.  
  208. #if    LOCKDEBUG
  209.     printf("Locking [%s] [%s]\n", pathname, filename); tgetc();
  210. #endif
  211.  
  212. #if    MSDOS == 0 && OS2 == 0
  213.     /* check to see if we can access the path */
  214.     if (stat(pathname, &sb) != 0) {
  215. #if    LOCKDEBUG
  216.         printf("stat() = %u   errno = %u\n", stat(pathname, &sb), errno); tgetc();
  217. #endif
  218.         strcpy(result, LOCKMSG);
  219.         strcat(result, "Path not found");
  220.         return(result);
  221.     }
  222.     if ((sb.st_mode & S_IFDIR) == 0) {
  223.         strcpy(result, LOCKMSG);
  224.         strcat(result, "Illegal Path");
  225.         return(result);
  226.     }
  227. #endif
  228.  
  229.     /* create the lock directory if it does not exist */
  230.     strcpy(lockpath, pathname);
  231.     strcat(lockpath, DIRSEPSTR);
  232.     strcat(lockpath, LOCKDIR);
  233. #if    LOCKDEBUG
  234.     printf("Lockdir [%s]\n", lockpath); tgetc();
  235. #endif
  236. #if    MSDOS || OS2
  237.     if (TRUE) {
  238. #else
  239.     if (stat(lockpath, &sb) != 0) {
  240. #endif
  241.  
  242.         /* create it! */
  243. #if    LOCKDEBUG
  244.         printf("MKDIR(%s)\n", lockpath); tgetc();
  245. #endif
  246. #if    MSDOS || OS2
  247.         mkdir(lockpath);
  248. #else
  249.         if (mkdir(lockpath, 0777) != 0) {
  250.             strcpy(result, LOCKMSG);
  251.             switch (errno) {
  252.  
  253.                 case EACCES:
  254.                 strcat(result, "Permission Denied");
  255.                 break;
  256.  
  257.                 case ENOENT:
  258.                 strcat(result, "No such file or directory");
  259.                 break;
  260.             }
  261.             return(result);
  262.         }
  263. #endif
  264.     }
  265.  
  266.     /* check for the existance of this lockfile */
  267.     strcpy(lockfile, lockpath);
  268.     strcat(lockfile, DIRSEPSTR);
  269.     strcat(lockfile, filename);
  270. #if    LOCKDEBUG
  271.     printf("Lockfile [%s]\n", lockfile); tgetc();
  272. #endif
  273.  
  274.     if (stat(lockfile, &sb) != 0) {
  275.  
  276.         /* create the lock file */
  277.         fp = fopen(lockfile, "w");
  278.         if (fp == (FILE *)NULL) {
  279.             strcpy(result, LOCKMSG);
  280.             strcat(result, "Can not open lock file");
  281.             return(result);
  282.         }
  283.  
  284.         /* and output the info needed */
  285. #if    MSDOS || OS2
  286.         fprintf(fp, "0\n");        /* process ID */
  287. #endif
  288. #if    SUN
  289.         fprintf(fp, "%u\n", getpid());
  290. #endif
  291.  
  292.         /* user name */
  293.         if (getenv("USER"))
  294.             fprintf(fp, "%s\n", getenv("USER"));
  295.         else
  296.             fprintf(fp, "<unknown>\n");
  297.  
  298.         /* host name */
  299.         if (getenv("HOST"))
  300.             fprintf(fp, "%s\n", getenv("HOST"));
  301.         else {
  302. #if    MSDOS || OS2
  303.             fprintf(fp, "<unknown>\n");
  304. #endif
  305. #if    SUN
  306.             gethostname(buf, NFILEN);
  307.             fprintf(fp, "%s\n", buf);
  308. #endif
  309.         }
  310.  
  311.         /* time... */
  312.         fprintf(fp, "%s\n", timeset());
  313.  
  314.         fclose(fp);
  315.         return(NULL);
  316.  
  317.     } else {
  318.  
  319.         /* get the existing lock info */
  320.         fp = fopen(lockfile, "r");
  321.         if (fp == (FILE *)NULL) {
  322.             strcpy(result, LOCKMSG);
  323.             strcat(result, "Can not read lock file");
  324.             return(result);
  325.         }
  326.  
  327.         /* get the process id */
  328.         fgets(buf, NSTRING, fp);
  329.         proc_id = asc_int(buf);
  330.  
  331.         /* get the user name */
  332.         fgets(result, NSTRING, fp);
  333.         result[strlen(result)-1] = 0;
  334.  
  335.         /* get the host name */
  336.         strcat(result, "@");
  337.         fgets(buf, NSTRING, fp);
  338.         buf[strlen(buf)-1] = 0;
  339.         strcat(result, buf);
  340.  
  341. #if    SUN
  342.         /* is it the current host? */
  343.         gethostname(host, NFILEN);
  344.         if (strcmp(buf, host) == 0) {
  345.  
  346.             /* see if the process is dead already */
  347.             if (kill(proc_id, 0) != 0 && errno == ESRCH) {
  348.  
  349.                 /* kill the lock file and retry the lock */
  350.                 fclose(fp);
  351.                 unlink(lockfile);
  352.                 return(dolock(filespec));
  353.             }
  354.         }
  355. #endif
  356.  
  357.         /* get the time */
  358.         strcat(result, " at ");
  359.         fgets(buf, NSTRING, fp);
  360.         buf[strlen(buf)-1] = 0;
  361.         strcat(result, buf);
  362.         fclose(fp);
  363.         return(result);
  364.     }
  365. }
  366.  
  367. /**********************
  368.  *
  369.  * undolock -- unlock the file fname
  370.  *
  371.  * if successful, returns NULL 
  372.  * if other error, returns "LOCK ERROR: explanation"
  373.  *
  374.  *********************/
  375.  
  376. char *undolock(filespec)
  377.  
  378. char *filespec;        /* filespec to unlock */
  379.  
  380. {
  381.     char filename[NFILEN];        /* name of file to lock */
  382.     char pathname[NFILEN];        /* path leading to file to lock */
  383.     char drivename[NFILEN];        /* drive for file to lock */
  384.     char lockpath[NFILEN];        /* lock directory name */
  385.     char lockfile[NFILEN];        /* lock file name */
  386.     static char result[NSTRING];    /* error return string */
  387.  
  388.     /* separate filespec into components */
  389.     strcpy(filename, parse_name(filespec));
  390.     strcpy(pathname, parse_path(filespec));
  391.     strcpy(drivename, parse_drive(filespec));
  392.     if (pathname[0] == 0)
  393.         strcpy(pathname, ".");
  394.  
  395.     /* merge the drive into the pathname */
  396.     strcat(drivename, pathname);
  397.     strcpy(pathname, drivename);
  398.  
  399. #if    LOCKDEBUG
  400.     printf("\nUnLocking [%s] [%s]\n", pathname, filename); tgetc();
  401. #endif
  402.  
  403.     /* create the lock directory if it does not exist */
  404.     strcpy(lockpath, pathname);
  405.     strcat(lockpath, DIRSEPSTR);
  406.     strcat(lockpath, LOCKDIR);
  407. #if    LOCKDEBUG
  408.     printf("Lockdir [%s]\n", lockpath); tgetc();
  409. #endif
  410.     /* check for the existance of this lockfile */
  411.     strcpy(lockfile, lockpath);
  412.     strcat(lockfile, DIRSEPSTR);
  413.     strcat(lockfile, filename);
  414. #if    LOCKDEBUG
  415.     printf("Lockfile [%s]\n", lockfile); tgetc();
  416. #endif
  417.     if (unlink(lockfile)) { 
  418.         strcat(result, "could not remove lock file"); 
  419.         return(result); 
  420.     } else {
  421.         rmdir(lockpath);   /* this will work only if dir is empty */
  422.             return(NULL);
  423.     }
  424. }
  425.  
  426. #else
  427. dolhello()
  428. {
  429. }
  430. #endif
  431.  
  432.