]> jfr.im git - irc/rqf/shadowircd.git/blob - tools/viconf.c
d716d511e3425b219db6da3445770e9cccf2b157
[irc/rqf/shadowircd.git] / tools / viconf.c
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() */