Annotation of coherent/b/etc/init/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:  *  or if the pid we are passed was 0.
                    109:  *
                    110:  */
                    111: 
                    112: locknrm(resource, pid)
                    113:        char *resource;
                    114:        int pid;
                    115: {
                    116:        int lockfd;     /* pointer to file to read */
                    117:        int chars_read; /* Number of characters read().  */
                    118: 
                    119:        char gotpid[PIDLEN + 1];        /* String value of the PID that should be stored
                    120:                                 * in the lock file pointed to by *lockfp.
                    121:                                 */
                    122:        char lockfn[LOKFLEN];
                    123: 
                    124:        if ( resource == NULL ) {
                    125: #ifdef UUCP
                    126:                plog(M_CALL, "Unlocking NULL resource.");
                    127: #endif /* UUCP */
                    128:                return( 0 );
                    129:        }
                    130: 
                    131:        sprintf(lockfn, "%s/%s%.*s", LOCKDIR, LOCKPRE, LOCKSIG, resource);
                    132: 
                    133:        /* open the lock file for read, abort on failure */
                    134:        if(-1 == (lockfd = (open(lockfn, 0)))){
                    135: #ifdef UUCP
                    136:                printmsg(M_DEBUG, "Error opening lock file for PID verify");
                    137:                plog(M_CALL, "Error opening lock file for PID verify");
                    138: #endif /* UUCP */
                    139:                close(lockfd);
                    140:                return(-1);
                    141:        }
                    142: 
                    143:        /* read the contents of the file. Abort if empty */
                    144:        if ( -1 == (chars_read = read(lockfd, gotpid, PIDLEN))) {
                    145: #ifdef UUCP
                    146:                printmsg(M_DEBUG, "Lockrm: Error reading lock file for PID verify");
                    147:                plog(M_CALL, "Lockrm: Error reading lock file for PID verify");
                    148: #endif /* UUCP */
                    149:                close(lockfd);
                    150:                return(-1);
                    151:        }
                    152: 
                    153:        gotpid[chars_read] = '\0';      /* NUL terminate the string.  */
                    154:        if ( (0 != pid) && (atoi(gotpid) != pid) ){
                    155: #ifdef UUCP
                    156:                printmsg(M_DEBUG, "Lockrm: PID verify failed. PID read was %s.", 
                    157:                        gotpid);
                    158:                plog(M_CALL, "Lockrm: PID verify failed. PID read was %s", gotpid);
                    159: #endif /* UUCP */
                    160:                close(lockfd);
                    161:                return(-1);
                    162:        } else {
                    163: #ifdef UUCP
                    164:                printmsg(M_DEBUG, "Lockrm: PID verify successful, removing lock.");
                    165:                plog(M_CALL, "Lockrm: PID verify successful, removing lock.");
                    166: #endif /* UUCP */
                    167: 
                    168:                if ( unlink(lockfn) < 0 ) {
                    169: #ifdef UUCP
                    170:                        printmsg(M_DEBUG, "Lockrm: Error unlocking: %s", lockfn);
                    171:                        plog(M_CALL, "Lockrm: Error unlocking: %s", lockfn);
                    172: #endif /* UUCP */
                    173:                        close(lockfd);
                    174:                        return( -1 );
                    175:                }
                    176: #ifdef UUCP
                    177:                printmsg(M_DEBUG, "Just unlocked: %s", lockfn);
                    178: #endif /* UUCP */
                    179:                close(lockfd);
                    180:                return( 0 );
                    181:        }
                    182: #ifdef UUCP
                    183:        plog(M_CALL, "Unreachable code in locknrm().");
                    184: #endif /* UUCP */
                    185: }
                    186: 
                    187: /*
                    188:  *  lockexist(resource)  char *resource;
                    189:  *
                    190:  *  Test for existance of a lock on the given resource.
                    191:  *
                    192:  *  Returns:  (1)  Resource is locked.
                    193:  *           (0)  Resource is not locked.
                    194:  */
                    195: 
                    196: lockexist(resource)
                    197: char   *resource;
                    198: {
                    199:        char lockfn[LOKFLEN];
                    200: 
                    201:        if ( resource == NULL )
                    202:                return(0);
                    203:        sprintf(lockfn, "%s/%s%.*s", LOCKDIR, LOCKPRE, LOCKSIG, resource);
                    204: 
                    205:        return (!access(lockfn, AEXISTS));
                    206: }
                    207: 
                    208: 
                    209: /*
                    210:  * Attempt to lock a tty device.  Takes the name of the tty itself,
                    211:  * otherwise behaves like lockit().
                    212:  */
                    213: locktty(ttyname)
                    214: {
                    215:        char resource[LOKFLEN];
                    216:        char filename[LOKFLEN];
                    217: 
                    218:        sprintf(filename, "/dev/%s", ttyname);
                    219:        if (NULL == gen_res_name(filename, resource)){
                    220:                return(-1);
                    221:        }
                    222:        return(lockit(resource));
                    223: 
                    224: } /* locktty() */
                    225: 
                    226: /*
                    227:  * Unlock a tty device.  Takes the name of the tty itself,
                    228:  * otherwise behaves like lockrm().
                    229:  */
                    230: unlocktty(ttyname)
                    231:        char *ttyname;
                    232: {
                    233:        return(unlockntty(ttyname, getpid()));
                    234: } /* unlocktty() */
                    235: 
                    236: /*
                    237:  * Unlock a tty device.  Takes the name of the tty itself,
                    238:  * otherwise behaves like locknrm().
                    239:  */
                    240: unlockntty(ttyname, pid)
                    241:        char *ttyname;
                    242:        int pid;
                    243: {
                    244:        char resource[LOKFLEN];
                    245:        char filename[LOKFLEN];
                    246: 
                    247:        sprintf(filename, "/dev/%s", ttyname);
                    248:        if (NULL == gen_res_name(filename, resource)){
                    249: #ifdef UUCP
                    250:                plog(M_CALL, "Can't generate resource for %s.", ttyname);
                    251: #endif /* UUCP */
                    252:                return(-1);
                    253:        }
                    254:        return(locknrm(resource, pid));
                    255: } /* unlockntty() */
                    256: 
                    257: /*
                    258:  * Attempt to lock a tty device.  Takes the name of the tty itself,
                    259:  * otherwise behaves like lockit().
                    260:  */
                    261: lockttyexist(ttyname)
                    262: {
                    263:        char resource[LOKFLEN];
                    264:        char filename[LOKFLEN];
                    265: 
                    266:        sprintf(filename, "/dev/%s", ttyname);
                    267:        if (NULL == gen_res_name(filename, resource)){
                    268:                return(0);      /* Non-existent tty can not be locked :-) */
                    269:        }
                    270: 
                    271:        return(lockexist(resource));
                    272: } /* lockttyexist() */
                    273: 
                    274: /*
                    275:  * Generates a resource name for locking, based on the major number
                    276:  * and the lower 4 bits of the minor number of the tty device.
                    277:  *
                    278:  * Builds the name in buff as two "." separated decimal numbers.
                    279:  * Returns NULL on failure, buff on success.
                    280:  */
                    281: char *
                    282: gen_res_name(path, buff)
                    283:        char *path;
                    284:        char *buff;
                    285: {
                    286:        struct stat sbuf;
                    287:        int status;
                    288:        
                    289:        if (0 != (status = stat(path, &sbuf))) {
                    290:                /* Can't stat the file.  */
                    291:                return (NULL);
                    292:        }
                    293: 
                    294:        if (PE_DRIVER == major(sbuf.st_rdev)) {
                    295:                sprintf(buff, "%d.%d", major(sbuf.st_rdev),
                    296:                                       PE_DEVMASK & minor(sbuf.st_rdev));
                    297:        } else {
                    298:                sprintf(buff, "%d.%d", major(sbuf.st_rdev),
                    299:                                       DEVMASK & minor(sbuf.st_rdev));
                    300:        }
                    301: 
                    302:        return(buff);
                    303: } /* gen_res_name */
                    304: 
                    305: #ifdef TEST
                    306: #include <stdio.h>
                    307: 
                    308: #define LOCKSIG 9      /* Significant Chars of Lockable Resources.  */
                    309: 
                    310: main(argc, argv)
                    311:        int argc;
                    312:        char *argv[];
                    313: {
                    314:        char buffer[LOCKSIG + 1];
                    315:        char path[LOKFLEN];
                    316: 
                    317:        if (argc != 2) {
                    318:                fprintf(stderr, "Usage: %s ttyname\n", argv[0]);
                    319:                exit(1);
                    320:        }
                    321: 
                    322:        sprintf(path, "/dev/%s", argv[1]);
                    323: 
                    324:        if (NULL == gen_res_name(path, buffer)) {
                    325:                fprintf(stderr, "%s: Can't stat %s.\n", argv[0], argv[1]);
                    326:                exit(1);
                    327:        }
                    328: 
                    329:        printf("Resource to lock: %s\n", buffer);
                    330: 
                    331:        if (-1 == locktty(argv[1])) {
                    332:                fprintf(stderr, "%s: Can't lock %s.\n", argv[0], argv[1]);
                    333:                exit(1);
                    334:        }
                    335: 
                    336:        printf("I think I've locked %s.\n", argv[1]);
                    337: 
                    338:        if (lockttyexist(argv[1])) {
                    339:                printf("Yep, %s is locked.\n", argv[1]);
                    340:        } else {
                    341:                fprintf(stderr, "%s: Failed to lock %s.\n", argv[0], argv[1]);
                    342:                exit(1);
                    343:        }
                    344: 
                    345: 
                    346:        sprintf(path, "cat /usr/spool/uucp/LCK..%s", buffer);
                    347:        printf("Contents of lock file: ");
                    348:        fflush(stdout);
                    349:        system(path);
                    350:        printf("\n");
                    351: 
                    352:        if (-1 == unlocktty(argv[1])) {
                    353:                fprintf(stderr, "%s: Problem removing lock on %s.\n", argv[0], argv[1]);
                    354:                exit(1);
                    355:        }
                    356: 
                    357:        printf("I think I've unlocked %s.\n", argv[1]);
                    358: 
                    359:        if (lockttyexist(argv[1])) {
                    360:                fprintf(stderr, "%s: Failed to unlock %s.\n", argv[0], argv[1]);
                    361:                exit(1);
                    362:        } else {
                    363:                printf("Successfully unlocked %s.\n", argv[1]);
                    364:        }
                    365: 
                    366:        
                    367:        exit(0);
                    368: }
                    369: #endif /* TEST */

unix.superglobalmegacorp.com

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