1 /*
2  *  Copyright (C) 2004 Baris Simsek, EnderUNIX SDT @ Tr
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
17  *
18  *  $Id: toolkit.c,v 1.1.1.1 2006/07/21 08:59:27 simsek Exp $
19  *
20  */
21 
22 
23 #include "qsheff-config.h"
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <fcntl.h>
31 #include <time.h>
32 #include <sys/stat.h>
33 #include <sys/wait.h>
34 #include <sys/types.h>
35 #include <dirent.h>
36 
37 #include "log.h"
38 #include "djb.h"
39 #include "toolkit.h"
40 #include "loadconfig.h"
41 
42 extern int errno;
43 
gen_queue_id(char * qid,int len)44 int gen_queue_id(char *qid, int len)
45 {
46 	struct timeval time_str;
47 
48 	gettimeofday(&time_str,(struct timezone *) 0);
49 	snprintf(qid, len-1, "q%ld-%ld-%ld", time_str.tv_sec, time_str.tv_usec, (long int)getpid());
50 
51 	return 0;
52 }
53 
rm_dir(const char * dirname)54 int rm_dir(const char *dirname)
55 {
56 	if(chdir(QSHEFFDIR) != 0) {
57 		errlog(__FILE__, __LINE__, errno);
58 		return -1;
59 	}
60 
61 	if(rmdir(dirname) != 0) {
62 		errlog(__FILE__, __LINE__, errno);
63 		return -1;
64 	}
65 	else
66 		return 0;
67 }
68 
removespaces(char * buf)69 int removespaces(char *buf)
70 {
71 	char *cp = buf;
72 	char *sv = buf;
73 	int len;
74 
75 	len = strlen(buf);
76 
77 	for (; *buf != '\0' && *buf != '\r' && *buf != '\n' && ((buf - sv) < len); buf++)
78 		if (*buf == ' ')
79 			continue;
80 		else
81 			*cp++ = *buf;
82 	*cp = 0x0;
83 	return cp - sv;
84 }
85 
rrm_dir(const char * dirpath)86 int rrm_dir(const char *dirpath)
87 {
88 	char newpath[1024];
89 	DIR *dirp;
90 	struct dirent *direntp;
91 	struct stat sb;
92 
93 	#ifdef _DEBUG_
94 	printf("  . removing path %s\n", dirpath);
95 	#endif
96 
97 	if(chdir(QSHEFFDIR) != 0) errlog(__FILE__, __LINE__, errno);
98 
99 	if ((dirp = opendir(dirpath)) == NULL) {
100 		errlog(__FILE__, __LINE__, errno);
101 		return 2;
102 	}
103 
104 	while((direntp = readdir(dirp)) != NULL) {
105 		if(strcmp(direntp->d_name, ".") !=0 && strcmp(direntp->d_name, "..") != 0) {
106 			snprintf(newpath, sizeof(newpath)-1, "%s/%s", dirpath, direntp->d_name);
107 			if(lstat(newpath, &sb) == -1) {
108 				errlog(__FILE__, __LINE__, errno);
109 				closedir(dirp);
110 				return 2;
111 			}
112 			if(S_ISDIR(sb.st_mode)) {
113 				rrm_dir(newpath);
114 			}
115 			else {
116 				if(unlink(newpath) == -1) {
117 					errlog(__FILE__, __LINE__, errno);
118 				}
119 				else {
120 					#ifdef _DEBUG_
121 					printf("  . file %s is removed\n", newpath);
122 					#endif
123 				}
124 			}
125 		}
126 	}
127 
128 	closedir(dirp);
129 
130 	if(rmdir(dirpath) == -1) errlog(__FILE__, __LINE__, errno);
131 
132 	return 0;
133 }
134 
copy(char * src,char * dst)135 int copy(char *src, char *dst)
136 {
137 	static int blen = 1024;
138 	static char *bp;
139 	register int nread, from_fd, to_fd;
140 
141 	if ((from_fd = open(src, O_RDONLY, 0)) < 0) return -1;
142 
143 	if ((to_fd = open(dst, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0400)) < 0) return -1;
144 
145 	if((bp = malloc(blen)) == NULL) return -1;
146 	memset(bp, 0, 1024);
147 
148 	for(;;) {
149 		nread = read(from_fd, bp, (size_t)blen);
150 
151 		if (nread == -1) if (errno == error_intr) continue;
152 
153 		if (nread == -1) {
154 			close(from_fd); close(to_fd);
155 			free(bp);
156 			errlog(__FILE__, __LINE__, errno);
157 			return -1;
158 		}
159 
160 		if (nread == 0) break;
161 
162 		if (write(to_fd, bp, (size_t)nread) < nread) {
163 			close(from_fd); close(to_fd);
164 			free(bp);
165 			errlog(__FILE__, __LINE__, errno);
166 			return -1;
167 		}
168 		memset(bp, 0, 1024);
169 	}
170 
171 	free(bp);
172 
173 	close(from_fd); close(to_fd);
174 
175 	/* Check the last read. */
176 	if (nread < 0) return -1;
177 
178 	return 0;
179 }
180 
181 
ret_subdir(char * root)182 char ret_subdir(char *root)
183 {
184 	int i, j;
185 	struct stat sb;
186 	char HEX_TBL[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
187 	char *path;
188 
189 	i = 0;
190 	if ((path = (char *) malloc(1024)) == NULL) {
191 		errlog(__FILE__, __LINE__, errno);
192 		return 1;
193 	}
194 	memset(path, 0x0, 1024);
195 
196 	while (i < 16)
197 	{
198 		strncpy(path, root, 1000);
199 		j = strlen(path);
200 		path[j] = '/';
201 		path[j+1] = HEX_TBL[i];
202 		if (stat(path, &sb) == -1) {
203 			free(path);
204 			return 1;
205 		}
206 		/* Allow maximum MAX_FILES files in a sub dir. */
207 		if (sb.st_nlink < MAX_FILES) break;
208 		path[j] = '\0';
209 		path[j+1] = '\0';
210 		i++;
211 	}
212 
213 	if (i == 16) {
214 		free(path);
215 		return 'x'; /* Queue is full. */
216 	}
217 
218 	free(path);
219 
220 	return HEX_TBL[i];
221 }
222 
223 
backup(char * msgfile,char * bckdir)224 int backup(char *msgfile, char *bckdir)
225 {
226 	char subdir;
227 	char *dst;
228 
229 	if ((dst = (char *) malloc(1024)) != NULL ) {
230 		snprintf(dst, 1023, "%s/%s", QSHEFFDIR, bckdir);
231 		subdir = ret_subdir(dst);
232 		if(subdir > 2) {
233 			memset(dst, 0, 1024);
234 			snprintf(dst, 1023, "%s/%s/%c/%s", QSHEFFDIR, bckdir, subdir, qid);
235 			if (mkdir(dst, 0700) == -1) {
236 				free(dst);
237 				return -1;
238 			}
239 			snprintf(dst, 1023, "%s/%s/%c/%s/mesg", QSHEFFDIR, bckdir, subdir, qid);
240 			copy(msgfile, dst);
241 		}
242 		free(dst);
243 	}
244 	else return -1;
245 
246 	return 0;
247 }
248 
249