⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lock.c

📁 cipe 编程
💻 C
字号:
/*   PKCIPE - public key based configuration tool for CIPE   lock.c - lock and PID file handling   Copyright 2000 Olaf Titz <olaf@bigred.inka.de>   This program is free software; you can redistribute it and/or   modify it under the terms of the GNU General Public License   as published by the Free Software Foundation; either version   2 of the License, or (at your option) any later version.*//* $Id: lock.c,v 1.6 2003/07/22 19:35:26 olaf81825 Exp $ */#include <fcntl.h>#include <string.h>#include <unistd.h>#include <sys/file.h>#include "pkcipe.h"/* Locking scheme:   All locks are in /var/run/cipe (or OPTDIR).   The file @@LOCKFILE ("master") is flock()d while the others are processed.   For each PEER,     PEER.pid holds the PID of a running ciped, managed by ip-up/ip-down.     PEER.pkc holds the PID of pkcipe while negotiating.   The pkc file is only removed after ciped has started, so there is no gap.*/#ifndef OPTDIR#define OPTDIR "/var/run/cipe/%s"#endif#define PIDDIR OPTDIR ".pid"#define PKCDIR OPTDIR ".pkc"static int writeint(int fd, int n){    char buf[16];    int i=snprintf(buf, sizeof(buf), "%11d\n", n);    return xwrite(fd, buf, i);}static char *master=NULL;static char masterfd=-1;int lockMaster(void){    debug((DEB_LOCK, "lockMaster"));    if (!master) {	if (!(master=dsprintf(OPTDIR, "@@LOCKFILE"))) {	    Log(LOG_ERR, "lockMaster: malloc failure");	    return -1;	}    }    if (masterfd<0) {	if ((masterfd=open(master, O_RDWR|O_CREAT, 0600))<0) {	    Log(LOG_ERR, "lockMaster: open: %m");	    return -1;	}	if (fcntl(masterfd, F_SETFD, FD_CLOEXEC)<0)	    Log(LOG_ERR, "lockMaster: FD_CLOEXEC: %m"); /* not fatal */    }    if (flock(masterfd, LOCK_EX)<0) {	Log(LOG_ERR, "lockMaster: flock: %m");	return -1;    }    return writeint(masterfd, getpid());}int unlockMaster(void){    debug((DEB_LOCK, "unlockMaster"));    if (masterfd<0) {	Log(LOG_ERR, "unlockMaster: internal not locked");	return -1;    }    if (flock(masterfd, LOCK_UN)<0) {	Log(LOG_ERR, "unlockMaster: flock: %m");	return -1;    }    (void)close(masterfd);    /* (void)unlink(master); no! race! */    masterfd=-1;    return 0;}/* these routines are run under master lock which should guarantee it to   be free of races */INLINE int handleLock(FILE *f){    int i, pid, e=0;    char buf[32];    FILE *p;    if (fscanf(f, "%d", &pid)<1) {	Log(LOG_NOTICE, "handleLock: pid file garbage");	goto out;    }    debug((DEB_LOCK, "handleLock: %d", pid));    snprintf(buf, sizeof(buf), "/proc/%d/stat", pid);    if (!(p=fopen(buf, "r"))) {	Log(LOG_INFO, "handleLock: open %s: %m", buf);	goto out;    }    if (fscanf(p, "%d %31s", &i, buf)<2 || i!=pid) {	Log(LOG_ERR, "handleLock: proc/stat garbage?");	fclose(p);	goto out;    }    fclose(p);    if (strstr(buf, "pkcipe")) {	debug((DEB_LOCK, "handleLock: found pkcipe process %d", pid));	e=pid;	goto out;    }    if (strstr(buf, "ciped")) {	Log(LOG_NOTICE, "handleLock: killing process %d %s", pid, buf);	kill(pid, SIGTERM);	snprintf(buf, sizeof(buf), "/proc/%d/stat", pid);	for (i=0; i<10; ++i) {	    if (access(buf, R_OK)<0)		break;	    debug((DEB_LOCK, "handleLock: waiting..."));	    sleep(1);	}	if (i>=10)	    Log(LOG_WARNING, "handleLock: %d not going away", pid);    } else {	Log(LOG_NOTICE, "handleLock: lock seems to be stale %s", buf);    } out:    rewind(f);    return e;}static void unlockPeer(void){    char *buf=dsprintf(PKCDIR, peerIdentity);    if (!buf) {	Log(LOG_ERR, "unlockPeer: malloc failure");	return;    }    unlink(buf);    free(buf);}int lockPeer(void){    FILE *f;    int i=0;    char *pkc=dsprintf(PKCDIR, peerIdentity);    if (!pkc) {	Log(LOG_ERR, "lockPeer: malloc failure");	return -1;    }    debug((DEB_LOCK, "lockPeer"));    if (access(pkc, R_OK|W_OK)==0) {	/* pkc file exists */	f=fopen(pkc, "r+");	if (f)	    i=handleLock(f);    } else {	/* pkc file does not exist, first check pid file */	char *pid=dsprintf(PIDDIR, peerIdentity);	if (!pid) {	    Log(LOG_ERR, "lockPeer: malloc failure");	    i=-1;	    goto out;	}	f=fopen(pid, "r");	if (f) {	    i=handleLock(f);	    fclose(f);	}	f=fopen(pkc, "w");	free(pid);    }    if (!f) {	Log(LOG_ERR, "lockPeer: fopen: %m");	i=-1;	goto out;    }    fprintf(f, "%d\n", getpid());    fclose(f); out:    if (pkc)	free(pkc);    if (!i)	atexit(unlockPeer);    return i;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -