home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / memacs400_src.lzh / MEMACS400 / SRC / dolock.c < prev    next >
Text File  |  1996-04-25  |  9KB  |  463 lines

  1. /*    DOLOCK.C:    Machine specific code for File Locking
  2.             for MicroEMACS
  3.             (C)Copyright 1995 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 || AIX || AUX || AVIION || BSD || FREEBSD || HPUX8 || HPUX9 || AMIGA)
  57. #if    OS2 || ((MSDOS || WINNT) && MSC) || BSD || FREEBSD
  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
  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 + 1) = '\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.  
  225.     /* separate filespec into components */
  226.     strcpy(filename, parse_name(filespec));
  227.     strcpy(pathname, parse_path(filespec));
  228.     strcpy(drivename, parse_drive(filespec));
  229.     if (pathname[0] == 0)
  230.         strcpy(pathname, ".");
  231.  
  232.     /* merge the drive into the pathname */
  233.     strcat(drivename, pathname);
  234.     strcpy(pathname, drivename);
  235.  
  236. #if    LOCKDEBUG
  237.     printf("Locking [%s] [%s]\n", pathname, filename); tgetc();
  238. #endif
  239.  
  240. #if    MSDOS == 0 && WINNT == 0 && OS2 == 0
  241.     /* check to see if we can access the path */
  242.     if (stat(pathname, &sb) != 0) {
  243. #if    LOCKDEBUG
  244.         printf("stat() = %u   errno = %u\n", stat(pathname, &sb), errno); tgetc();
  245. #endif
  246.         strcpy(result, LOCKMSG);
  247.         strcat(result, "Path not found");
  248.         return(result);
  249.     }
  250.     if ((sb.st_mode & S_IFDIR) == 0) {
  251.         strcpy(result, LOCKMSG);
  252.         strcat(result, "Illegal Path");
  253.         return(result);
  254.     }
  255. #endif
  256.  
  257.     /* create the lock directory if it does not exist */
  258.     strcpy(lockpath, pathname);
  259.     strcat(lockpath, DIRSEPSTR);
  260.     strcat(lockpath, LOCKDIR);
  261. #if    LOCKDEBUG
  262.     printf("Lockdir [%s]\n", lockpath); tgetc();
  263. #endif
  264.  
  265.     if (stat(lockpath, &sb) != 0) {
  266.  
  267.         /* create it! */
  268. #if    LOCKDEBUG
  269.         printf("MKDIR(%s)\n", lockpath); tgetc();
  270. #endif
  271. #if    MSDOS || WINNT || OS2
  272.         if (mkdir(lockpath) != 0) {
  273. #else
  274.         if (mkdir(lockpath, 0777) != 0) {
  275. #endif
  276.             strcpy(result, LOCKMSG);
  277.             switch (errno) {
  278.  
  279.                 case EACCES:
  280.                 strcat(result, "Permission Denied");
  281.                 break;
  282.  
  283.                 case ENOENT:
  284.                 strcat(result, "No such file or directory");
  285.                 break;
  286.             }
  287.             return(result);
  288.         }
  289.     }
  290.  
  291.     /* check for the existance of this lockfile */
  292.     strcpy(lockfile, lockpath);
  293.     strcat(lockfile, DIRSEPSTR);
  294.     strcat(lockfile, filename);
  295. #if    LOCKDEBUG
  296.     printf("Lockfile [%s]\n", lockfile); tgetc();
  297. #endif
  298.  
  299.     if (stat(lockfile, &sb) != 0) {
  300.  
  301.         /* create the lock file */
  302.         fp = fopen(lockfile, "w");
  303.         if (fp == (FILE *)NULL) {
  304.             strcpy(result, LOCKMSG);
  305.             strcat(result, "Can not open lock file");
  306.             return(result);
  307.         }
  308.  
  309.         /* and output the info needed */
  310. #if    MSDOS || WINNT || OS2
  311.         fprintf(fp, "0\n");        /* process ID */
  312. #endif
  313. #if    SUN
  314.         fprintf(fp, "%u\n", getpid());
  315. #endif
  316.  
  317. #if HPUX8 | HPUX9
  318.         /* user name */
  319.         if (getenv("LOGNAME"))
  320.             fprintf(fp, "%s\n", getenv("LOGNAME"));
  321. #else
  322.         /* user name */
  323.         if (getenv("USER"))
  324.             fprintf(fp, "%s\n", getenv("USER"));
  325. #endif
  326.         else
  327.             fprintf(fp, "<unknown>\n");
  328.  
  329.         /* host name */
  330.         if (getenv("HOST"))
  331.             fprintf(fp, "%s\n", getenv("HOST"));
  332.         else {
  333. #if    MSDOS || WINNT || OS2
  334.             fprintf(fp, "<unknown>\n");
  335. #endif
  336. #if    SUN
  337.             gethostname(buf, NFILEN);
  338.             fprintf(fp, "%s\n", buf);
  339. #endif
  340.         }
  341.  
  342.         /* time... */
  343.         fprintf(fp, "%s\n", timeset());
  344.  
  345.         fclose(fp);
  346.         return(NULL);
  347.  
  348.     } else {
  349.  
  350.         /* get the existing lock info */
  351.         fp = fopen(lockfile, "r");
  352.         if (fp == (FILE *)NULL) {
  353.             strcpy(result, LOCKMSG);
  354.             strcat(result, "Can not read lock file");
  355.             return(result);
  356.         }
  357.  
  358.         /* get the process id */
  359.         fgets(buf, NSTRING, fp);
  360.         proc_id = asc_int(buf);
  361.  
  362.         /* get the user name */
  363.         fgets(result, NSTRING, fp);
  364.         term_trim(result);
  365.  
  366.         /* get the host name */
  367.         strcat(result, "@");
  368.         fgets(buf, NSTRING, fp);
  369.         term_trim(buf);
  370.         strcat(result, buf);
  371.  
  372. #if    SUN
  373.         /* is it the current host? */
  374.         gethostname(host, NFILEN);
  375.         if (strcmp(buf, host) == 0) {
  376.  
  377.             /* see if the process is dead already */
  378.             if (kill(proc_id, 0) != 0 && errno == ESRCH) {
  379.  
  380.                 /* kill the lock file and retry the lock */
  381.                 fclose(fp);
  382.                 unlink(lockfile);
  383.                 return(dolock(filespec));
  384.             }
  385.         }
  386. #endif
  387.  
  388.         /* get the time */
  389.         strcat(result, " at ");
  390.         fgets(buf, NSTRING, fp);
  391.         term_trim(buf);
  392.         strcat(result, buf);
  393.         fclose(fp);
  394.         return(result);
  395.     }
  396. }
  397.  
  398. /**********************
  399.  *
  400.  * undolock -- unlock the file fname
  401.  *
  402.  * if successful, returns NULL 
  403.  * if other error, returns "LOCK ERROR: explanation"
  404.  *
  405.  *********************/
  406.  
  407. char *undolock(filespec)
  408.  
  409. char *filespec;        /* filespec to unlock */
  410.  
  411. {
  412.     char filename[NFILEN];        /* name of file to lock */
  413.     char pathname[NFILEN];        /* path leading to file to lock */
  414.     char drivename[NFILEN];        /* drive for file to lock */
  415.     char lockpath[NFILEN];        /* lock directory name */
  416.     char lockfile[NFILEN];        /* lock file name */
  417.     static char result[NSTRING];    /* error return string */
  418.  
  419.     /* separate filespec into components */
  420.     strcpy(filename, parse_name(filespec));
  421.     strcpy(pathname, parse_path(filespec));
  422.     strcpy(drivename, parse_drive(filespec));
  423.     if (pathname[0] == 0)
  424.         strcpy(pathname, ".");
  425.  
  426.     /* merge the drive into the pathname */
  427.     strcat(drivename, pathname);
  428.     strcpy(pathname, drivename);
  429.  
  430. #if    LOCKDEBUG
  431.     printf("\nUnLocking [%s] [%s]\n", pathname, filename); tgetc();
  432. #endif
  433.  
  434.     /* create the lock directory if it does not exist */
  435.     strcpy(lockpath, pathname);
  436.     strcat(lockpath, DIRSEPSTR);
  437.     strcat(lockpath, LOCKDIR);
  438. #if    LOCKDEBUG
  439.     printf("Lockdir [%s]\n", lockpath); tgetc();
  440. #endif
  441.     /* check for the existance of this lockfile */
  442.     strcpy(lockfile, lockpath);
  443.     strcat(lockfile, DIRSEPSTR);
  444.     strcat(lockfile, filename);
  445. #if    LOCKDEBUG
  446.     printf("Lockfile [%s]\n", lockfile); tgetc();
  447. #endif
  448.     if (unlink(lockfile)) { 
  449.         strcat(result, "could not remove lock file"); 
  450.         return(result); 
  451.     } else {
  452.         rmdir(lockpath);   /* this will work only if dir is empty */
  453.             return(NULL);
  454.     }
  455. }
  456.  
  457. #else
  458. dolhello()
  459. {
  460. }
  461. #endif
  462.  
  463.