]>
Commit | Line | Data |
---|---|---|
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 | ||
48 | if(strcmp(p, "vimotd") == 0) | |
49 | filename = MPATH; | |
50 | ||
51 | if(LockedFile(filename)) | |
52 | { | |
53 | fprintf(stderr,"Can't lock %s\n", filename); | |
54 | exit(errno); | |
55 | } | |
56 | ||
57 | /* ed config file */ | |
58 | switch(fork()) | |
59 | { | |
60 | case -1: | |
61 | fprintf(stderr, "error forking, %d\n", errno); | |
62 | exit(errno); | |
63 | case 0: /* Child */ | |
64 | if((ed = getenv("EDITOR")) == NULL) | |
65 | ed = "vi"; | |
66 | execlp(ed, ed, filename, NULL); | |
67 | fprintf(stderr, "error running editor, %d\n", errno); | |
68 | exit(errno); | |
69 | default: | |
70 | wait(0); | |
71 | } | |
72 | ||
73 | unlink(lockpath); | |
74 | return 0; | |
75 | } | |
76 | ||
77 | /* | |
78 | * LockedFile() (copied from m_kline.c in ircd) | |
79 | * Determine if 'filename' is currently locked. If it is locked, | |
80 | * there should be a filename.lock file which contains the current | |
81 | * pid of the editing process. Make sure the pid is valid before | |
82 | * giving up. | |
83 | * | |
84 | * Return: 1 if locked | |
85 | * -1 if couldn't unlock | |
86 | * 0 if was able to lock | |
87 | */ | |
88 | ||
89 | ||
90 | ||
91 | static int | |
92 | LockedFile(const char *filename) | |
93 | ||
94 | { | |
95 | ||
96 | char buffer[1024]; | |
97 | FILE *fileptr; | |
98 | int killret; | |
99 | int fd; | |
100 | ||
101 | if (!filename) | |
102 | return (0); | |
103 | ||
104 | sprintf(lockpath, "%s.lock", filename); | |
105 | ||
106 | if ((fileptr = fopen(lockpath, "r")) != NULL) | |
107 | { | |
108 | if (fgets(buffer, sizeof(buffer) - 1, fileptr)) | |
109 | { | |
110 | /* | |
111 | * If it is a valid lockfile, 'buffer' should now | |
112 | * contain the pid number of the editing process. | |
113 | * Send the pid a SIGCHLD to see if it is a valid | |
114 | * pid - it could be a remnant left over from a | |
115 | * crashed editor or system reboot etc. | |
116 | */ | |
117 | ||
118 | killret = kill(atoi(buffer), SIGCHLD); | |
119 | if (killret == 0) | |
120 | { | |
121 | fclose(fileptr); | |
122 | return (1); | |
123 | } | |
124 | ||
125 | /* | |
126 | * killret must be -1, which indicates an error (most | |
127 | * likely ESRCH - No such process), so it is ok to | |
128 | * proceed writing klines. | |
129 | */ | |
130 | } | |
131 | fclose(fileptr); | |
132 | } | |
133 | ||
134 | /* | |
135 | * Delete the outdated lock file | |
136 | */ | |
137 | unlink(lockpath); | |
138 | ||
139 | /* create exclusive lock */ | |
140 | if((fd = open(lockpath, O_WRONLY|O_CREAT|O_EXCL, 0666)) < 0) | |
141 | { | |
142 | fprintf(stderr, "ircd config file locked\n"); | |
143 | return (-1); | |
144 | } | |
145 | ||
146 | fileptr = fdopen(fd,"w"); | |
147 | fprintf(fileptr,"%d\n",(int)getpid()); | |
148 | fclose(fileptr); | |
149 | return (0); | |
150 | } /* LockedFile() */ |