Annotation of coherent/d/usr/lib/libmisc/lock.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *  lock.c
                      3:  *
                      4:  *  Provide a locking mechanism for UUCP
                      5:  */
                      6: 
                      7: #include <stdio.h>
                      8: #include <access.h>
                      9: #include <sys/stat.h>
                     10: 
                     11: char *gen_res_name();
                     12: 
                     13: #ifdef UUCP
                     14: #include "dcp.h"
                     15: #else
                     16: #define SPOOLDIR       "/usr/spool/uucp"
                     17: #define LOCKSIG                9       /* Significant Chars of Lockable Resources.  */
                     18: #define LOKFLEN                64      /* Max Length of UUCP Lock File Name.        */
                     19: #endif /* UUCP */
                     20: 
                     21: #define LOCKDIR        SPOOLDIR
                     22: #define        LOCKPRE "LCK.."
                     23: #define PIDLEN 6       /* Maximum length of string representing a PID.  */
                     24: 
                     25: /* There is a special version of DEVMASK for the PE multiport driver
                     26:  * because of the peculiar way it uses the minor device number.  For
                     27:  * all other drivers, the lower 5 bits describe the physical port--
                     28:  * the upper 3 bits give attributes for the port.
                     29:  */
                     30: 
                     31: #define PE_DRIVER 21   /* Major device number for the PE driver.  */
                     32: #define PE_DEVMASK 0x3f        /* PE driver minor device mask.  */
                     33: #define DEVMASK 0x1f   /* Minor device mask.  */
                     34: 
                     35: 
                     36: /*
                     37:  *  lockit(resource)  char *resource;
                     38:  *
                     39:  *  Lock the given resource.
                     40:  *  Returns (-1) if already locked or error in locking.
                     41:  *          ( 0) if all ok, resource locked.
                     42:  */
                     43: 
                     44: lockit(resource)
                     45: char *resource;
                     46: {
                     47: 
                     48:        int lockfd;
                     49:        char lockfn[LOKFLEN];
                     50:        char pidstring[PIDLEN];
                     51: 
                     52:        sprintf(lockfn, "%s/%s%.*s", LOCKDIR, LOCKPRE, LOCKSIG, resource);
                     53:        if ( (access(lockfn, AEXISTS) == 0) ||
                     54:             ((lockfd=creat(lockfn, 0644)) == -1) ) {
                     55: #ifdef UUCP
                     56:                printmsg(M_DEBUG, "Can't lock: %s", lockfn);
                     57: #endif /* UUCP */
                     58:                return( -1 );
                     59:        }
                     60: #ifdef UUCP
                     61:        printmsg(M_DEBUG, "Just created lock: %s", lockfn);
                     62: #endif /* UUCP */
                     63:        sprintf(pidstring, "%d", getpid());
                     64:        if(-1 == write(lockfd, pidstring, strlen(pidstring))){
                     65:                close(lockfd);
                     66:                unlink(lockfn);
                     67:                return(-1);
                     68:        }
                     69: 
                     70:        close(lockfd);
                     71:        return( 0 );
                     72: }
                     73: 
                     74: /*
                     75:  *  lockrm(resource)  char *resource;
                     76:  *
                     77:  *  Simply remove the lock on the given resource.
                     78:  *  Returns (-1) if not locked or error in unlocking.
                     79:  *          ( 0) if all ok, resource lock removed.
                     80:  *
                     81:  *
                     82:  * Open the lock file for read operations to try to read the PID
                     83:  * stored in the file. If the open fails, abort. If the read fails, 
                     84:  * abort. If the read PID does not match our PID, abort. We will only
                     85:  * remove the lock if our PID matches the PID written to the file.
                     86: */
                     87: 
                     88: lockrm(resource)
                     89: char *resource;
                     90: {
                     91:        return(locknrm(resource, getpid()));
                     92: }
                     93: 
                     94: 
                     95: /*
                     96:  *  locknrm(resource, pid)  char *resource;
                     97:  *
                     98:  *  Remove the lock on the given resource, using pid as the process id to
                     99:  *  look for.
                    100:  *
                    101:  *  Returns (-1) if not locked or error in unlocking.
                    102:  *          ( 0) if all ok, resource lock removed.
                    103:  *
                    104:  *  Open the lock file for read operations to try to read the PID
                    105:  *  stored in the file. If the open fails, abort. If the read fails, 
                    106:  *  abort. If the read PID does not match our PID, abort. We will only
                    107:  *  remove the lock if the passed matches the PID written to the file.
                    108:  */
                    109: 
                    110: locknrm(resource, pid)
                    111:        char *resource;
                    112:        int pid;
                    113: {
                    114:        int lockfd;     /* pointer to file to read */
                    115:        int chars_read; /* Number of characters read().  */
                    116: 
                    117:        char gotpid[PIDLEN + 1];        /* String value of the PID that should be stored
                    118:                                 * in the lock file pointed to by *lockfp.
                    119:                                 */
                    120:        char lockfn[LOKFLEN];
                    121: 
                    122:        if ( resource == NULL ) {
                    123: #ifdef UUCP
                    124:                plog(M_CALL, "Unlocking NULL resource.");
                    125: #endif /* UUCP */
                    126:                return( 0 );
                    127:        }
                    128: 
                    129:        sprintf(lockfn, "%s/%s%.*s", LOCKDIR, LOCKPRE, LOCKSIG, resource);
                    130: 
                    131:        /* open the lock file for read, abort on failure */
                    132:        if(-1 == (lockfd = (open(lockfn, 0)))){
                    133: #ifdef UUCP
                    134:                printmsg(M_DEBUG, "Error opening lock file for PID verify");
                    135:                plog(M_CALL, "Error opening lock file for PID verify");
                    136: #endif /* UUCP */
                    137:                close(lockfd);
                    138:                return(-1);
                    139:        }
                    140: 
                    141:        /* read the contents of the file. Abort if empty */
                    142:        if ( -1 == (chars_read = read(lockfd, gotpid, PIDLEN))) {
                    143: #ifdef UUCP
                    144:                printmsg(M_DEBUG, "Lockrm: Error reading lock file for PID verify");
                    145:                plog(M_CALL, "Lockrm: Error reading lock file for PID verify");
                    146: #endif /* UUCP */
                    147:                close(lockfd);
                    148:                return(-1);
                    149:        }
                    150: 
                    151:        gotpid[chars_read] = '\0';      /* NUL terminate the string.  */
                    152:        if (atoi(gotpid) != pid){
                    153: #ifdef UUCP
                    154:                printmsg(M_DEBUG, "Lockrm: PID verify failed. PID read was %s.", 
                    155:                        gotpid);
                    156:                plog(M_CALL, "Lockrm: PID verify failed. PID read was %s", gotpid);
                    157: #endif /* UUCP */
                    158:                close(lockfd);
                    159:                return(-1);
                    160:        }else{
                    161: #ifdef UUCP
                    162:                printmsg(M_DEBUG, "Lockrm: PID verify successful, removing lock.");
                    163:                plog(M_CALL, "Lockrm: PID verify successful, removing lock.");
                    164: #endif /* UUCP */
                    165: 
                    166:                if ( unlink(lockfn) < 0 ) {
                    167: #ifdef UUCP
                    168:                        printmsg(M_DEBUG, "Lockrm: Error unlocking: %s", lockfn);
                    169:                        plog(M_CALL, "Lockrm: Error unlocking: %s", lockfn);
                    170: #endif /* UUCP */
                    171:                        close(lockfd);
                    172:                        return( -1 );
                    173:                }
                    174: #ifdef UUCP
                    175:                printmsg(M_DEBUG, "Just unlocked: %s", lockfn);
                    176: #endif /* UUCP */
                    177:                close(lockfd);
                    178:                return( 0 );
                    179:        }
                    180: #ifdef UUCP
                    181:        plog(M_CALL, "Unreachable code in locknrm().");
                    182: #endif /* UUCP */
                    183: }
                    184: 
                    185: /*
                    186:  *  lockexist(resource)  char *resource;
                    187:  *
                    188:  *  Test for existance of a lock on the given resource.
                    189:  *
                    190:  *  Returns:  (1)  Resource is locked.
                    191:  *           (0)  Resource is not locked.
                    192:  */
                    193: 
                    194: lockexist(resource)
                    195: char   *resource;
                    196: {
                    197:        char lockfn[LOKFLEN];
                    198: 
                    199:        if ( resource == NULL )
                    200:                return(0);
                    201:        sprintf(lockfn, "%s/%s%.*s", LOCKDIR, LOCKPRE, LOCKSIG, resource);
                    202: 
                    203:        return (!access(lockfn, AEXISTS));
                    204: }
                    205: 
                    206: 
                    207: /*
                    208:  * Attempt to lock a tty device.  Takes the name of the tty itself,
                    209:  * otherwise behaves like lockit().
                    210:  */
                    211: locktty(ttyname)
                    212: {
                    213:        char resource[LOKFLEN];
                    214:        char filename[LOKFLEN];
                    215: 
                    216:        sprintf(filename, "/dev/%s", ttyname);
                    217:        if (NULL == gen_res_name(filename, resource)){
                    218:                return(-1);
                    219:        }
                    220:        return(lockit(resource));
                    221: 
                    222: } /* locktty() */
                    223: 
                    224: /*
                    225:  * Unlock a tty device.  Takes the name of the tty itself,
                    226:  * otherwise behaves like lockrm().
                    227:  */
                    228: unlocktty(ttyname)
                    229:        char *ttyname;
                    230: {
                    231:        return(unlockntty(ttyname, getpid()));
                    232: } /* unlocktty() */
                    233: 
                    234: /*
                    235:  * Unlock a tty device.  Takes the name of the tty itself,
                    236:  * otherwise behaves like locknrm().
                    237:  */
                    238: unlockntty(ttyname, pid)
                    239:        char *ttyname;
                    240:        int pid;
                    241: {
                    242:        char resource[LOKFLEN];
                    243:        char filename[LOKFLEN];
                    244: 
                    245:        sprintf(filename, "/dev/%s", ttyname);
                    246:        if (NULL == gen_res_name(filename, resource)){
                    247: #ifdef UUCP
                    248:                plog(M_CALL, "Can't generate resource for %s.", ttyname);
                    249: #endif /* UUCP */
                    250:                return(-1);
                    251:        }
                    252:        return(locknrm(resource, pid));
                    253: } /* unlockntty() */
                    254: 
                    255: /*
                    256:  * Attempt to lock a tty device.  Takes the name of the tty itself,
                    257:  * otherwise behaves like lockit().
                    258:  */
                    259: lockttyexist(ttyname)
                    260: {
                    261:        char resource[LOKFLEN];
                    262:        char filename[LOKFLEN];
                    263: 
                    264:        sprintf(filename, "/dev/%s", ttyname);
                    265:        if (NULL == gen_res_name(filename, resource)){
                    266:                return(0);      /* Non-existent tty can not be locked :-) */
                    267:        }
                    268: 
                    269:        return(lockexist(resource));
                    270: } /* lockttyexist() */
                    271: 
                    272: /*
                    273:  * Generates a resource name for locking, based on the major number
                    274:  * and the lower 4 bits of the minor number of the tty device.
                    275:  *
                    276:  * Builds the name in buff as two "." separated decimal numbers.
                    277:  * Returns NULL on failure, buff on success.
                    278:  */
                    279: char *
                    280: gen_res_name(path, buff)
                    281:        char *path;
                    282:        char *buff;
                    283: {
                    284:        struct stat sbuf;
                    285:        int status;
                    286:        
                    287:        if (0 != (status = stat(path, &sbuf))) {
                    288:                /* Can't stat the file.  */
                    289:                return (NULL);
                    290:        }
                    291: 
                    292:        if (PE_DRIVER == major(sbuf.st_rdev)) {
                    293:                sprintf(buff, "%d.%d", major(sbuf.st_rdev),
                    294:                                       PE_DEVMASK & minor(sbuf.st_rdev));
                    295:        } else {
                    296:                sprintf(buff, "%d.%d", major(sbuf.st_rdev),
                    297:                                       DEVMASK & minor(sbuf.st_rdev));
                    298:        }
                    299: 
                    300:        return(buff);
                    301: } /* gen_res_name */
                    302: 
                    303: #ifdef TEST
                    304: #include <stdio.h>
                    305: 
                    306: #define LOCKSIG 9      /* Significant Chars of Lockable Resources.  */
                    307: 
                    308: main(argc, argv)
                    309:        int argc;
                    310:        char *argv[];
                    311: {
                    312:        char buffer[LOCKSIG + 1];
                    313:        char path[LOKFLEN];
                    314: 
                    315:        if (argc != 2) {
                    316:                fprintf(stderr, "Usage: %s ttyname\n", argv[0]);
                    317:                exit(1);
                    318:        }
                    319: 
                    320:        sprintf(path, "/dev/%s", argv[1]);
                    321: 
                    322:        if (NULL == gen_res_name(path, buffer)) {
                    323:                fprintf(stderr, "%s: Can't stat %s.\n", argv[0], argv[1]);
                    324:                exit(1);
                    325:        }
                    326: 
                    327:        printf("Resource to lock: %s\n", buffer);
                    328: 
                    329:        if (-1 == locktty(argv[1])) {
                    330:                fprintf(stderr, "%s: Can't lock %s.\n", argv[0], argv[1]);
                    331:                exit(1);
                    332:        }
                    333: 
                    334:        printf("I think I've locked %s.\n", argv[1]);
                    335: 
                    336:        if (lockttyexist(argv[1])) {
                    337:                printf("Yep, %s is locked.\n", argv[1]);
                    338:        } else {
                    339:                fprintf(stderr, "%s: Failed to lock %s.\n", argv[0], argv[1]);
                    340:                exit(1);
                    341:        }
                    342: 
                    343: 
                    344:        sprintf(path, "cat /usr/spool/uucp/LCK..%s", buffer);
                    345:        printf("Contents of lock file: ");
                    346:        fflush(stdout);
                    347:        system(path);
                    348:        printf("\n");
                    349: 
                    350:        if (-1 == unlocktty(argv[1])) {
                    351:                fprintf(stderr, "%s: Problem removing lock on %s.\n", argv[0], argv[1]);
                    352:                exit(1);
                    353:        }
                    354: 
                    355:        printf("I think I've unlocked %s.\n", argv[1]);
                    356: 
                    357:        if (lockttyexist(argv[1])) {
                    358:                fprintf(stderr, "%s: Failed to unlock %s.\n", argv[0], argv[1]);
                    359:                exit(1);
                    360:        } else {
                    361:                printf("Successfully unlocked %s.\n", argv[1]);
                    362:        }
                    363: 
                    364:        
                    365:        exit(0);
                    366: }
                    367: #endif /* TEST */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.