+ }
+
+/*
+ * Code for locking/unlocking the serial device.
+ * This code is derived from chat.c.
+ */
+
+#define LOCK_PREFIX "/var/lock/LCK.."
+
+/*
+ * lock - create a lock file for the named device
+ */
+
+int lock (char *dev)
+ {
+ char hdb_lock_buffer[12];
+ int fd, pid, n;
+ char *p;
+
+ p = strrchr(dev, '/');
+ if (p != NULL)
+ {
+ dev = ++p;
+ }
+
+ lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1);
+ if (lock_file == NULL)
+ {
+ novm("lock file name");
+ }
+
+ strcpy (lock_file, LOCK_PREFIX);
+ strcat (lock_file, dev);
+/*
+ * Attempt to create the lock file at this point.
+ */
+ while (1)
+ {
+ fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644);
+ if (fd >= 0)
+ {
+ sprintf(hdb_lock_buffer, "%010d\n", getpid());
+ write(fd, hdb_lock_buffer, 11);
+ close(fd);
+ return 0;
+ }
+/*
+ * If the file exists then check to see if the pid is stale
+ */
+ if (errno == EEXIST)
+ {
+ fd = open(lock_file, O_RDONLY, 0);
+ if (fd < 0)
+ {
+ if (errno == ENOENT) /* This is just a timing problem. */
+ {
+ continue;
+ }
+ break;
+ }
+
+ /* Read the lock file to find out who has the device locked */
+ n = read (fd, hdb_lock_buffer, 11);
+ close (fd);
+ if (n < 0)
+ {
+ syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file);
+ break;
+ }
+
+ /* See the process still exists. */
+ if (n > 0)
+ {
+ hdb_lock_buffer[n] = '\0';
+ sscanf (hdb_lock_buffer, " %d", &pid);
+ if (kill(pid, 0) == -1 && errno == ESRCH)
+ {
+ n = 0;
+ }
+ }
+
+ /* If the process does not exist then try to remove the lock */
+ if (n == 0 && unlink (lock_file) == 0)
+ {
+ syslog (LOG_NOTICE, "Removed stale lock on %s (pid %d)",
+ dev, pid);
+ continue;
+ }
+
+ syslog (LOG_NOTICE, "Device %s is locked by pid %d", dev, pid);
+ break;
+ }
+
+ syslog(LOG_ERR, "Can't create lock file %s: %m", lock_file);
+ break;
+ }
+
+ free(lock_file);
+ lock_file = NULL;
+ return -1;