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