version 1.1.2.1, 2010/09/28 15:02:55
|
version 1.1.2.8, 2010/09/30 11:39:08
|
Line 2
|
Line 2
|
#include "clog.h" |
#include "clog.h" |
|
|
|
|
|
int Verbose; |
extern char compiled[], compiledby[], compilehost[]; |
extern char compiled[], compiledby[], compilehost[]; |
|
|
|
|
Line 12 Usage()
|
Line 13 Usage()
|
printf( "cLOG is tool for managment syslogd operation with circular logs\n" |
printf( "cLOG is tool for managment syslogd operation with circular logs\n" |
"=== %s === %s@%s ===\n\n" |
"=== %s === %s@%s ===\n\n" |
" Syntax: clog [options] <file.log>\n\n" |
" Syntax: clog [options] <file.log>\n\n" |
|
"\t-v\t\tVerbose, more -vv more verbosity\n" |
"\t-i\t\tInit file.log, create and prepare for use\n" |
"\t-i\t\tInit file.log, create and prepare for use\n" |
"\t-s <size>\tUse with init for set needed file.log size\n" |
"\t-s <size>\tUse with init for set needed file.log size\n" |
"\t-f\t\tForce command\n" | "\t-m <perm>\tUse permissions with init for set file.log\n" |
| "\t-f\t\tRead and follow log file.log\n" |
"\n", compiled, compiledby, compilehost); |
"\n", compiled, compiledby, compilehost); |
} |
} |
|
|
|
static int |
|
initlog(const char *csLog, size_t size, int mode) |
|
{ |
|
int f, ret = -1, fill = size; |
|
struct clogFooter cf = { 0 }; |
|
char buffer[BUFLEN] = { 0 }; |
|
|
|
memcpy(&cf.cf_magic, MAGIC, sizeof cf.cf_magic); |
|
cf.cf_max = size - sizeof cf; |
|
|
|
f = open(csLog, O_WRONLY | O_CREAT | O_TRUNC, mode); |
|
if (f == -1) { |
|
printf("Error:: in open log %s #%d - %s\n", csLog, errno, strerror(errno)); |
|
return -1; |
|
} else |
|
VERB(1) printf("Verbose:: Create log %s\n", csLog); |
|
while (fill > BUFLEN) |
|
if (write(f, buffer, BUFLEN) == -1) { |
|
printf("Error:: in fill log %s #%d - %s\n", csLog, errno, strerror(errno)); |
|
goto end; |
|
} else |
|
fill -= BUFLEN; |
|
if (fill > BUFLEN) { |
|
printf("Error:: in fill log %s uninspected result!!!\n", csLog); |
|
goto end; |
|
} else if (fill && write(f, buffer, fill) == -1) { |
|
printf("Error:: in last fill log %s #%d - %s\n", csLog, errno, strerror(errno)); |
|
goto end; |
|
} |
|
// return to write cfooter |
|
if (lseek(f, -(off_t)(sizeof cf), SEEK_END) == -1) { |
|
printf("Error:: can`t set position for write footer #%d - %s\n", errno, strerror(errno)); |
|
goto end; |
|
} |
|
if (write(f, &cf, sizeof cf) == -1) { |
|
printf("Error:: in footer log %s #%d - %s\n", csLog, errno, strerror(errno)); |
|
goto end; |
|
} |
|
|
|
ret = 0; |
|
VERB(1) printf("Verbose:: Init done.\n"); |
|
end: |
|
close(f); |
|
return ret; |
|
} |
|
|
|
static int |
|
readlog(const char *csLog, char m) |
|
{ |
|
int f, cx; |
|
size_t end; |
|
struct clogFooter *cf; |
|
char *buffer = NULL; |
|
uint32_t next, start = 0; |
|
struct iovec iov[2]; |
|
struct pollfd pfd = { 0 }; |
|
|
|
f = open(csLog, O_RDONLY); |
|
if (f == -1) { |
|
printf("Error:: in open read %s #%d - %s\n", csLog, errno, strerror(errno)); |
|
return -1; |
|
} else |
|
VERB(1) printf("Verbose:: Opened log %s\n", csLog); |
|
end = lseek(f, 0, SEEK_END); |
|
if (end == -1) { |
|
printf("Error:: in get size %s #%d - %s\n", csLog, errno, strerror(errno)); |
|
close(f); |
|
return -1; |
|
} else |
|
lseek(f, 0, SEEK_SET); |
|
VERB(2) printf("Verbose(2):: Get file size %u\n", end); |
|
buffer = mmap(NULL, end, PROT_READ, MAP_SHARED, f, 0); |
|
if (!buffer) { |
|
printf("Error:: in map %s #%d - %s\n", csLog, errno, strerror(errno)); |
|
close(f); |
|
return -1; |
|
} else { |
|
close(f); |
|
|
|
cf = (struct clogFooter*) (buffer + end - sizeof(struct clogFooter)); |
|
VERB(3) printf("Verbose(3):: Map file to address %p and footer %p\n", buffer, cf); |
|
} |
|
|
|
if (cf->cf_wrap == 1) |
|
start = cf->cf_next + 1; |
|
VERB(3) printf("Verbose(3):: wrapped log? %d\n", cf->cf_wrap); |
|
do { |
|
cx = 0; |
|
while (cf->cf_lock == 1) |
|
sched_yield(); |
|
next = cf->cf_next; |
|
|
|
if (start > next) { |
|
iov[cx].iov_base = buffer + start; |
|
iov[cx++].iov_len = cf->cf_max - start; |
|
start = 0; |
|
} |
|
iov[cx].iov_base = buffer + start; |
|
iov[cx++].iov_len = next - start; |
|
start = next; |
|
writev(1, iov, cx); |
|
if (!(m & 2)) |
|
break; |
|
if (poll(&pfd, 1, 50) == -1) { |
|
printf("Error:: in poll %s #%d - %s\n", csLog, errno, strerror(errno)); |
|
munmap(buffer, end); |
|
return -1; |
|
} |
|
} while (42); |
|
|
|
munmap(buffer, end); |
|
VERB(1) printf("Verbose:: Read done.\n"); |
|
return 0; |
|
} |
|
|
|
|
int |
int |
main(int argc, char **argv) |
main(int argc, char **argv) |
{ |
{ |
char ch; | char ch, m = 0, szLog[MAXPATHLEN]; |
| size_t siz = 0; |
| int mode = 0644; |
|
|
while ((ch = getopt(argc, argv, "hfis:")) != -1) | while ((ch = getopt(argc, argv, "hm:vfis:")) != -1) |
switch (ch) { |
switch (ch) { |
|
case 'm': |
|
mode = strtol(optarg, NULL, 0); |
|
break; |
|
case 'v': |
|
Verbose++; |
|
break; |
|
case 'i': |
|
m |= 1; |
|
break; |
|
case 'f': |
|
m |= 2; |
|
break; |
|
case 's': |
|
siz = strtol(optarg, NULL, 0); |
|
if (siz < 1) { |
|
printf("Error:: size is invalid %u!\n", siz); |
|
Usage(); |
|
return 1; |
|
} |
|
break; |
case 'h': |
case 'h': |
default: |
default: |
Usage(); |
Usage(); |
Line 33 main(int argc, char **argv)
|
Line 173 main(int argc, char **argv)
|
} |
} |
argc -= optind; |
argc -= optind; |
argv += optind; |
argv += optind; |
|
if (m & 1 && !siz) { |
|
printf("Error:: not specified size when use with init log!\n"); |
|
Usage(); |
|
return 1; |
|
} |
|
if (m == 3) { |
|
printf("Error:: can`t in same time init and force!\n"); |
|
Usage(); |
|
return 1; |
|
} |
|
if (!argc) { |
|
printf("Error:: not specified log file!\n"); |
|
Usage(); |
|
return 1; |
|
} else |
|
strlcpy(szLog, *argv, MAXPATHLEN); |
|
|
|
if (m & 1 && initlog(szLog, siz, mode) == -1) |
|
return 2; |
|
if (readlog(szLog, m) == -1) |
|
return 3; |
|
|
return 0; |
return 0; |
} |
} |