188 lines
3.9 KiB
C
188 lines
3.9 KiB
C
/*
|
|
* This file is part of the ISDN master program.
|
|
*
|
|
* Copyright (C) 1995 Matthias Urlichs.
|
|
* See the file COPYING for license details.
|
|
*/
|
|
|
|
#include "master.h"
|
|
|
|
|
|
|
|
/* Device names. 's'=short, 'm'=medium, ''=fullname; 'i'=non-terminal version */
|
|
|
|
char *
|
|
sdevname (short minor)
|
|
{
|
|
static char dev[20];
|
|
|
|
sprintf (dev, "i%02d", minor & 0xFF);
|
|
return dev;
|
|
}
|
|
|
|
char *
|
|
mdevname (short minor)
|
|
{
|
|
static char dev[20];
|
|
|
|
sprintf (dev, "tty%s", sdevname (minor));
|
|
return dev;
|
|
}
|
|
|
|
char *
|
|
devname (short minor)
|
|
{
|
|
static char dev[20];
|
|
|
|
sprintf (dev, "/dev/%s", mdevname (minor));
|
|
return dev;
|
|
}
|
|
|
|
char *
|
|
isdevname (short minor)
|
|
{
|
|
static char dev[20];
|
|
|
|
sprintf (dev, "isdn%d", minor & 0xFF);
|
|
return dev;
|
|
}
|
|
|
|
char *
|
|
idevname (short minor)
|
|
{
|
|
static char dev[20];
|
|
|
|
sprintf (dev, "/dev/isdn/%s", isdevname (minor));
|
|
return dev;
|
|
}
|
|
|
|
|
|
/* Check a lock file. */
|
|
void
|
|
checkdev(int dev)
|
|
{
|
|
char permtt1[sizeof(LOCKNAME)+15];
|
|
char permtt2[sizeof(LOCKNAME)+15];
|
|
int f, len, pid;
|
|
char sbuf[10];
|
|
|
|
sprintf(permtt1,LOCKNAME,mdevname(dev));
|
|
sprintf(permtt2,LOCKNAME,isdevname(dev));
|
|
|
|
if((f = open(permtt1,O_RDWR)) < 0) {
|
|
if(0)syslog(LOG_WARNING,"Checking %s: unopenable, deleted, %m",permtt1);
|
|
unlink(permtt1);
|
|
} else {
|
|
len=read(f,sbuf,sizeof(sbuf)-1);
|
|
if(len<=0) {
|
|
if(0)syslog(LOG_WARNING,"Checking %s: unreadable, deleted, %m",permtt1);
|
|
unlink(permtt1);
|
|
} else {
|
|
if(sbuf[len-1]=='\n')
|
|
sbuf[len-1]='\0';
|
|
else
|
|
sbuf[len]='\0';
|
|
pid = atoi(sbuf);
|
|
if(pid <= 0 || (kill(pid,0) == -1 && errno == ESRCH)) {
|
|
if(0)syslog(LOG_WARNING,"Checking %s: unkillable, pid %d, deleted, %m",permtt1, pid);
|
|
unlink(permtt1);
|
|
}
|
|
}
|
|
close(f);
|
|
}
|
|
if((f = open(permtt2,O_RDWR)) < 0) {
|
|
if(0)syslog(LOG_WARNING,"Checking %s: unopenable, deleted, %m",permtt2);
|
|
unlink(permtt2);
|
|
} else {
|
|
len=read(f,sbuf,sizeof(sbuf)-1);
|
|
if(len<=0) {
|
|
if(0)syslog(LOG_WARNING,"Checking %s: unreadable, deleted, %m",permtt2);
|
|
unlink(permtt2);
|
|
} else {
|
|
if(sbuf[len-1]=='\n')
|
|
sbuf[len-1]='\0';
|
|
else
|
|
sbuf[len]='\0';
|
|
pid = atoi(sbuf);
|
|
if(pid <= 0 || (kill(pid,0) == -1 && errno == ESRCH)) {
|
|
if(0)syslog(LOG_WARNING,"Checking %s: unkillable, pid %d, deleted, %m",permtt2, pid);
|
|
unlink(permtt2);
|
|
}
|
|
}
|
|
close(f);
|
|
}
|
|
}
|
|
|
|
|
|
/* Lock a device. One failure, for externally-opened devices (cu), may be tolerated. */
|
|
int
|
|
lockdev(int dev, char onefailok)
|
|
{
|
|
char permtt1[sizeof(LOCKNAME)+15];
|
|
char permtt2[sizeof(LOCKNAME)+15];
|
|
char vartt[sizeof(LOCKNAME)+15];
|
|
char pidnum[7];
|
|
int f, err, len;
|
|
|
|
len = sprintf(pidnum,"%d",getpid());
|
|
sprintf(vartt,LOCKNAME,pidnum);
|
|
sprintf(permtt1,LOCKNAME,mdevname(dev));
|
|
sprintf(permtt2,LOCKNAME,isdevname(dev));
|
|
|
|
unlink(vartt);
|
|
f=open(vartt,O_WRONLY|O_CREAT,0644);
|
|
if(f < 0) {
|
|
syslog(LOG_WARNING,"Locktemp %s: unopenable, %m",vartt);
|
|
return -1;
|
|
}
|
|
if((err = write(f,pidnum,len)) != len) {
|
|
syslog(LOG_WARNING,"Locktemp %s: unwriteable, %m",vartt);
|
|
close(f);
|
|
return -1;
|
|
}
|
|
close(f);
|
|
chmod(vartt,S_IRUSR|S_IRGRP|S_IROTH);
|
|
|
|
if((err = link(vartt,permtt1)) < 0) {
|
|
if(onefailok == 0) {
|
|
if(0) syslog(LOG_WARNING,"Lock %s: unlinkable, %m",permtt1);
|
|
checkdev(dev);
|
|
unlink(vartt);
|
|
return -1;
|
|
}
|
|
--onefailok;
|
|
if(0) syslog(LOG_INFO,"Lock %s: unlinkable(ignored), %m",permtt1);
|
|
}
|
|
if((err = link(vartt,permtt2)) < 0) {
|
|
if (onefailok == 0) {
|
|
if(0) syslog(LOG_WARNING,"Lock %s: unlinkable, %m",permtt2);
|
|
checkdev(dev);
|
|
unlink(vartt);
|
|
unlink(permtt1);
|
|
return -1;
|
|
}
|
|
--onefailok;
|
|
if(0) syslog(LOG_INFO,"Lock %s: unlinkable(ignored), %m",permtt2);
|
|
}
|
|
unlink(vartt);
|
|
if(0) syslog(LOG_DEBUG,"Locked %s and %s",permtt1,permtt2);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* ... and unlock it. */
|
|
void
|
|
unlockdev(int dev)
|
|
{
|
|
char permtt1[sizeof(LOCKNAME)+15];
|
|
char permtt2[sizeof(LOCKNAME)+15];
|
|
|
|
sprintf(permtt1,LOCKNAME,mdevname(dev));
|
|
sprintf(permtt2,LOCKNAME,isdevname(dev));
|
|
|
|
unlink(permtt1);
|
|
unlink(permtt2);
|
|
if(0) syslog(LOG_DEBUG,"Unlocked %s and %s",permtt1,permtt2);
|
|
}
|
|
|