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