]>
Commit | Line | Data |
---|---|---|
212380e3 AC |
1 | /* |
2 | * viconf.c | |
3 | * | |
4 | * $Id: viconf.c 6 2005-09-10 01:02:21Z nenolod $ | |
5 | */ | |
6 | #include <stdio.h> | |
7 | #include <unistd.h> | |
8 | #include <fcntl.h> | |
9 | #include <stdlib.h> | |
10 | #include <errno.h> | |
11 | #include <string.h> | |
12 | #include <limits.h> | |
13 | #include <signal.h> | |
14 | #include "config.h" | |
15 | ||
16 | ||
17 | /* wait.h is in /include on solaris, likely on other SYSV machines as well | |
18 | * but wait.h is normally in /include/sys on BSD boxen, | |
19 | * probably we should have an #ifdef SYSV? | |
20 | * -Dianora | |
21 | */ | |
22 | ||
23 | #ifdef SOL20 | |
24 | #include <wait.h> | |
25 | #else | |
26 | #include <sys/wait.h> | |
27 | #endif | |
28 | ||
29 | static int LockedFile(const char *filename); | |
30 | static char lockpath[PATH_MAX + 1]; | |
31 | ||
32 | ||
33 | int main(int argc, char *argv[]) | |
34 | { | |
35 | const char *ed, *p, *filename = CPATH; | |
36 | ||
37 | if( chdir(DPATH) < 0 ) | |
38 | { | |
39 | fprintf(stderr,"Cannot chdir to %s\n", DPATH); | |
40 | exit(errno); | |
41 | } | |
42 | ||
43 | if((p = strrchr(argv[0], '/')) == NULL) | |
44 | p = argv[0]; | |
45 | else | |
46 | p++; | |
47 | #ifdef KPATH | |
48 | if(strcmp(p, "viklines") == 0) | |
49 | filename = KPATH; | |
50 | #endif /* KPATH */ | |
51 | ||
52 | if(strcmp(p, "vimotd") == 0) | |
53 | filename = MPATH; | |
54 | ||
55 | if(LockedFile(filename)) | |
56 | { | |
57 | fprintf(stderr,"Can't lock %s\n", filename); | |
58 | exit(errno); | |
59 | } | |
60 | ||
61 | /* ed config file */ | |
62 | switch(fork()) | |
63 | { | |
64 | case -1: | |
65 | fprintf(stderr, "error forking, %d\n", errno); | |
66 | exit(errno); | |
67 | case 0: /* Child */ | |
68 | if((ed = getenv("EDITOR")) == NULL) | |
69 | ed = "vi"; | |
70 | execlp(ed, ed, filename, NULL); | |
71 | fprintf(stderr, "error running editor, %d\n", errno); | |
72 | exit(errno); | |
73 | default: | |
74 | wait(0); | |
75 | } | |
76 | ||
77 | unlink(lockpath); | |
78 | return 0; | |
79 | } | |
80 | ||
81 | /* | |
82 | * LockedFile() (copied from m_kline.c in ircd) | |
83 | * Determine if 'filename' is currently locked. If it is locked, | |
84 | * there should be a filename.lock file which contains the current | |
85 | * pid of the editing process. Make sure the pid is valid before | |
86 | * giving up. | |
87 | * | |
88 | * Return: 1 if locked | |
89 | * -1 if couldn't unlock | |
90 | * 0 if was able to lock | |
91 | */ | |
92 | ||
93 | ||
94 | ||
95 | static int | |
96 | LockedFile(const char *filename) | |
97 | ||
98 | { | |
99 | ||
100 | char buffer[1024]; | |
101 | FILE *fileptr; | |
102 | int killret; | |
103 | int fd; | |
104 | ||
105 | if (!filename) | |
106 | return (0); | |
107 | ||
108 | sprintf(lockpath, "%s.lock", filename); | |
109 | ||
110 | if ((fileptr = fopen(lockpath, "r")) != NULL) | |
111 | { | |
112 | if (fgets(buffer, sizeof(buffer) - 1, fileptr)) | |
113 | { | |
114 | /* | |
115 | * If it is a valid lockfile, 'buffer' should now | |
116 | * contain the pid number of the editing process. | |
117 | * Send the pid a SIGCHLD to see if it is a valid | |
118 | * pid - it could be a remnant left over from a | |
119 | * crashed editor or system reboot etc. | |
120 | */ | |
121 | ||
122 | killret = kill(atoi(buffer), SIGCHLD); | |
123 | if (killret == 0) | |
124 | { | |
125 | fclose(fileptr); | |
126 | return (1); | |
127 | } | |
128 | ||
129 | /* | |
130 | * killret must be -1, which indicates an error (most | |
131 | * likely ESRCH - No such process), so it is ok to | |
132 | * proceed writing klines. | |
133 | */ | |
134 | } | |
135 | fclose(fileptr); | |
136 | } | |
137 | ||
138 | /* | |
139 | * Delete the outdated lock file | |
140 | */ | |
141 | unlink(lockpath); | |
142 | ||
143 | /* create exclusive lock */ | |
144 | if((fd = open(lockpath, O_WRONLY|O_CREAT|O_EXCL, 0666)) < 0) | |
145 | { | |
146 | fprintf(stderr, "ircd config file locked\n"); | |
147 | return (-1); | |
148 | } | |
149 | ||
150 | fileptr = fdopen(fd,"w"); | |
151 | fprintf(fileptr,"%d\n",(int)getpid()); | |
152 | fclose(fileptr); | |
153 | return (0); | |
154 | } /* LockedFile() */ |