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