home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / ue312os2.zip / src / dolock.c < prev    next >
C/C++ Source or Header  |  1994-08-26  |  10KB  |  461 lines

  1. /*    DOLOCK.C:    Machine specific code for File Locking
  2.             for MicroEMACS
  3.             (C)Copyright 1987,1993 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(is_lower(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 || WINNT || OS2 || SUN || USG || AUX || V7 || BSD || HPUX8 || HPUX9)
  57. #if    OS2 || ((MSDOS || WINNT) && MSC) || BSD
  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    (WINNT && MSC) || ICC
  71. #include <direct.h>
  72. #define chdir    _chdir
  73. #define getcwd    _getcwd
  74. #define mkdir    _mkdir
  75. #define rmdir    _rmdir
  76. #endif
  77.  
  78. #if    OS2 == 0
  79. #if    ZTC
  80. extern volatile int errno;
  81. #else
  82. #if    MSC == 0
  83. extern int errno;
  84. #endif
  85. #endif
  86. #endif
  87.  
  88. #define LOCKDIR "_xlk"
  89. #define LOCKMSG "LOCK ERROR -- "
  90. #define    LOCKDEBUG    FALSE
  91.  
  92. /*    dolock:    Generic non-UNIX file locking mechinism    */
  93.  
  94. /**********************
  95.  *
  96.  * dolock -- lock the file fname
  97.  *
  98.  * if successful, returns NULL 
  99.  * if file locked, returns username of person locking the file
  100.  * if other error, returns "LOCK ERROR: explanation"
  101.  *
  102.  *********************/
  103.  
  104. char *parse_name(filespec)        /* get name component of filespec */
  105.  
  106. char *filespec;
  107.  
  108. {
  109.     char *rname;
  110.  
  111.     rname = &filespec[strlen(filespec) - 1];
  112.     while (rname >= filespec) {
  113.         if (*rname == DIRSEPCHAR || *rname == DRIVESEPCHAR) {
  114.             ++rname;
  115.             break;
  116.         }
  117.         --rname;
  118.     }
  119.  
  120.     if (rname >= filespec)
  121.         return(rname);
  122.     else
  123.         return(filespec);
  124. }
  125.  
  126. char *parse_path(filespec)
  127.  
  128. char *filespec;
  129.  
  130. {
  131.     static char rbuff[NFILEN];
  132.     char *rname;
  133.  
  134.     /* make a copy we can mung */
  135.     strcpy(rbuff,filespec);
  136.  
  137.     /* starting from the end */
  138.     rname = &rbuff[strlen(rbuff)-1];
  139.  
  140.     /* scan for a directory separator */
  141.     while (rname >= rbuff) {
  142.         if (*rname == DIRSEPCHAR)
  143.             break;
  144.         --rname;
  145.     }
  146.  
  147.     /* no path here! */
  148.     if (rname < rbuff) {
  149.         rbuff[0] = '.';
  150.         rbuff[1] = DIRSEPCHAR;
  151.         rbuff[2] = 0;
  152.         return(rbuff);
  153.     }
  154.  
  155.     *(rname) = '\0';    /* point just beyond slash */
  156.  
  157.     /* no skip beyond any drive spec */
  158.     rname = rbuff;
  159.     while (*rname) {
  160.         if (*rname == DRIVESEPCHAR)
  161.             return(++rname);
  162.         ++rname;
  163.     }
  164.  
  165.     /* none to be found, return the whole string */
  166.     return(rbuff);
  167. }
  168.  
  169. char *parse_drive(filespec)
  170.  
  171. char *filespec;
  172.  
  173. {
  174.     static char rbuff[NFILEN];
  175.     char *rname;
  176.  
  177.     /* search for a drive specifier */
  178.     strcpy(rbuff,filespec);
  179.     rname = rbuff;
  180.     while (*rname) {
  181.         if (*rname == DRIVESEPCHAR) {
  182.             *(++rname) = 0;
  183.             return(rbuff);
  184.         }
  185.         ++rname;
  186.     }
  187.  
  188.     /* no drive letter/name */
  189.     return("");
  190. }
  191.  
  192. VOID term_trim(buf)    /* trim line terminators and whitespace from end of string */
  193.  
  194. char *buf;
  195.  
  196. {
  197.     char *c;    /* ptr to current character to examine */
  198.  
  199.     c = buf + strlen(buf) - 1;
  200.     while ((c >= buf) && (*c == '\r') || (*c == '\n') || (*c == ' ')
  201.         || (*c == '\t')) {
  202.         *c = 0;
  203.         c--;
  204.     }
  205.     return;
  206. }
  207.  
  208. char *dolock(filespec)
  209.  
  210. char *filespec;        /* full file spec of file to lock */
  211.  
  212. {
  213.     struct stat sb;            /* stat buffer for info on files/dirs */
  214.     FILE *fp;            /* ptr to lock file */
  215.     long proc_id;            /* process id from lock file */
  216.     char filename[NFILEN];        /* name of file to lock */
  217.     char pathname[NFILEN];        /* path leading to file to lock */
  218.     char drivename[NFILEN];        /* drive for file to lock */
  219.     char lockpath[NFILEN];        /* lock directory name */
  220.     char lockfile[NFILEN];        /* lock file name */
  221.     char buf[NSTRING];        /* input buffer */
  222.     char host[NSTRING];        /* current host name */
  223.     static char result[NSTRING];    /* error return string */
  224.     char *getenv(); 
  225.  
  226.     /* separate filespec into components */
  227.     strcpy(filename, parse_name(filespec));
  228.     strcpy(pathname, parse_path(filespec));
  229.     strcpy(drivename, parse_drive(filespec));
  230.     if (pathname[0] == 0)
  231.         strcpy(pathname, ".");
  232.  
  233.     /* merge the drive into the pathname */
  234.     strcat(drivename, pathname);
  235.     strcpy(pathname, drivename);
  236.  
  237. #if    LOCKDEBUG
  238.     printf("Locking [%s] [%s]\n", pathname, filename); tgetc();
  239. #endif
  240.  
  241. #if    MSDOS == 0 && WINNT == 0 && OS2 == 0
  242.     /* check to see if we can access the path */
  243.     if (stat(pathname, &sb) != 0) {
  244. #if    LOCKDEBUG
  245.         printf("stat() = %u   errno = %u\n", stat(pathname, &sb), errno); tgetc();
  246. #endif
  247.         strcpy(result, LOCKMSG);
  248.         strcat(result, "Path not found");
  249.         return(result);
  250.     }
  251.     if ((sb.st_mode & S_IFDIR) == 0) {
  252.         strcpy(result, LOCKMSG);
  253.         strcat(result, "Illegal Path");
  254.         return(result);
  255.     }
  256. #endif
  257.  
  258.     /* create the lock directory if it does not exist */
  259.     strcpy(lockpath, pathname);
  260.     strcat(lockpath, DIRSEPSTR);
  261.     strcat(lockpath, LOCKDIR);
  262. #if    LOCKDEBUG
  263.     printf("Lockdir [%s]\n", lockpath); tgetc();
  264. #endif
  265. #if    MSDOS || WINNT || OS2
  266.     if (TRUE) {
  267. #else
  268.     if (stat(lockpath, &sb) != 0) {
  269. #endif
  270.  
  271.         /* create it! */
  272. #if    LOCKDEBUG
  273.         printf("MKDIR(%s)\n", lockpath); tgetc();
  274. #endif
  275. #if    MSDOS || WINNT || OS2
  276.         mkdir(lockpath);
  277. #else
  278.         if (mkdir(lockpath, 0777) != 0) {
  279.             strcpy(result, LOCKMSG);
  280.             switch (errno) {
  281.  
  282.                 case EACCES:
  283.                 strcat(result, "Permission Denied");
  284.                 break;
  285.  
  286.                 case ENOENT:
  287.                 strcat(result, "No such file or directory");
  288.                 break;
  289.             }
  290.             return(result);
  291.         }
  292. #endif
  293.     }
  294.  
  295.     /* check for the existance of this lockfile */
  296.     strcpy(lockfile, lockpath);
  297.     strcat(lockfile, DIRSEPSTR);
  298.     strcat(lockfile, filename);
  299. #if    LOCKDEBUG
  300.     printf("Lockfile [%s]\n", lockfile); tgetc();
  301. #endif
  302.  
  303.     if (stat(lockfile, &sb) != 0) {
  304.  
  305.         /* create the lock file */
  306.         fp = fopen(lockfile, "w");
  307.         if (fp == (FILE *)NULL) {
  308.             strcpy(result, LOCKMSG);
  309.             strcat(result, "Can not open lock file");
  310.             return(result);
  311.         }
  312.  
  313.         /* and output the info needed */
  314. #if    MSDOS || WINNT || OS2
  315.         fprintf(fp, "0\n");        /* process ID */
  316. #endif
  317. #if    SUN
  318.         fprintf(fp, "%u\n", getpid());
  319. #endif
  320.  
  321.         /* user name */
  322.         if (getenv("USER"))
  323.             fprintf(fp, "%s\n", getenv("USER"));
  324.         else
  325.             fprintf(fp, "<unknown>\n");
  326.  
  327.         /* host name */
  328.         if (getenv("HOST"))
  329.             fprintf(fp, "%s\n", getenv("HOST"));
  330.         else {
  331. #if    MSDOS || WINNT || OS2
  332.             fprintf(fp, "<unknown>\n");
  333. #endif
  334. #if    SUN
  335.             gethostname(buf, NFILEN);
  336.             fprintf(fp, "%s\n", buf);
  337. #endif
  338.         }
  339.  
  340.         /* time... */
  341.         fprintf(fp, "%s\n", timeset());
  342.  
  343.         fclose(fp);
  344.         return(NULL);
  345.  
  346.     } else {
  347.  
  348.         /* get the existing lock info */
  349.         fp = fopen(lockfile, "r");
  350.         if (fp == (FILE *)NULL) {
  351.             strcpy(result, LOCKMSG);
  352.             strcat(result, "Can not read lock file");
  353.             return(result);
  354.         }
  355.  
  356.         /* get the process id */
  357.         fgets(buf, NSTRING, fp);
  358.         proc_id = asc_int(buf);
  359.  
  360.         /* get the user name */
  361.         fgets(result, NSTRING, fp);
  362.         term_trim(result);
  363.  
  364.         /* get the host name */
  365.         strcat(result, "@");
  366.         fgets(buf, NSTRING, fp);
  367.         term_trim(buf);
  368.         strcat(result, buf);
  369.  
  370. #if    SUN
  371.         /* is it the current host? */
  372.         gethostname(host, NFILEN);
  373.         if (strcmp(buf, host) == 0) {
  374.  
  375.             /* see if the process is dead already */
  376.             if (kill(proc_id, 0) != 0 && errno == ESRCH) {
  377.  
  378.                 /* kill the lock file and retry the lock */
  379.                 fclose(fp);
  380.                 unlink(lockfile);
  381.                 return(dolock(filespec));
  382.             }
  383.         }
  384. #endif
  385.  
  386.         /* get the time */
  387.         strcat(result, " at ");
  388.         fgets(buf, NSTRING, fp);
  389.         term_trim(buf);
  390.         strcat(result, buf);
  391.         fclose(fp);
  392.         return(result);
  393.     }
  394. }
  395.  
  396. /**********************
  397.  *
  398.  * undolock -- unlock the file fname
  399.  *
  400.  * if successful, returns NULL 
  401.  * if other error, returns "LOCK ERROR: explanation"
  402.  *
  403.  *********************/
  404.  
  405. char *undolock(filespec)
  406.  
  407. char *filespec;        /* filespec to unlock */
  408.  
  409. {
  410.     char filename[NFILEN];        /* name of file to lock */
  411.     char pathname[NFILEN];        /* path leading to file to lock */
  412.     char drivename[NFILEN];        /* drive for file to lock */
  413.     char lockpath[NFILEN];        /* lock directory name */
  414.     char lockfile[NFILEN];        /* lock file name */
  415.     static char result[NSTRING];    /* error return string */
  416.  
  417.     /* separate filespec into components */
  418.     strcpy(filename, parse_name(filespec));
  419.     strcpy(pathname, parse_path(filespec));
  420.     strcpy(drivename, parse_drive(filespec));
  421.     if (pathname[0] == 0)
  422.         strcpy(pathname, ".");
  423.  
  424.     /* merge the drive into the pathname */
  425.     strcat(drivename, pathname);
  426.     strcpy(pathname, drivename);
  427.  
  428. #if    LOCKDEBUG
  429.     printf("\nUnLocking [%s] [%s]\n", pathname, filename); tgetc();
  430. #endif
  431.  
  432.     /* create the lock directory if it does not exist */
  433.     strcpy(lockpath, pathname);
  434.     strcat(lockpath, DIRSEPSTR);
  435.     strcat(lockpath, LOCKDIR);
  436. #if    LOCKDEBUG
  437.     printf("Lockdir [%s]\n", lockpath); tgetc();
  438. #endif
  439.     /* check for the existance of this lockfile */
  440.     strcpy(lockfile, lockpath);
  441.     strcat(lockfile, DIRSEPSTR);
  442.     strcat(lockfile, filename);
  443. #if    LOCKDEBUG
  444.     printf("Lockfile [%s]\n", lockfile); tgetc();
  445. #endif
  446.     if (unlink(lockfile)) { 
  447.         strcat(result, "could not remove lock file"); 
  448.         return(result); 
  449.     } else {
  450.         rmdir(lockpath);   /* this will work only if dir is empty */
  451.             return(NULL);
  452.     }
  453. }
  454.  
  455. #else
  456. dolhello()
  457. {
  458. }
  459. #endif
  460.  
  461.