-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
…iles sequence size limit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,7 @@ | |
#include <string> | ||
#include <sstream> | ||
#include <netdb.h> | ||
#include <dirent.h> | ||
|
||
#include "output.h" | ||
#include "log.h" | ||
|
@@ -220,6 +221,7 @@ output_stream::output_stream() | |
, sock(-1) | ||
, mimetype(MIMETYPE_OCTET_STREAM) | ||
, target_file_size_limit(0) | ||
, target_fseq_size_limit(0) | ||
, ringbuffer() | ||
, stream_method(OUTPUT_STREAM_UDP) | ||
, count_in(0) | ||
|
@@ -506,7 +508,7 @@ int output_stream::stream(uint8_t* p_data, int size) | |
break; | ||
case OUTPUT_STREAM_FILE: | ||
//dprintf("(sock: %d, size: %d, filesize: %lu, limit: %lu)", sock, size, get_file_size(sock), target_file_size_limit); | ||
|
||
if ( | ||
This comment has been minimized.
Sorry, something went wrong. |
||
target_file_size_limit > 0 | ||
&& ((unsigned)get_file_size(sock) + size) >= target_file_size_limit | ||
|
@@ -576,27 +578,32 @@ int output_stream::change_file() | |
|
||
new_name = target_file_name; | ||
|
||
if (target_file_size_limit > 0){ | ||
if (detect_printf_seq(target_file_name)) { | ||
dprintf("sequence detected"); | ||
|
||
char buff[100]; | ||
snprintf(buff, sizeof(buff), target_file_name, target_file_name_index); | ||
new_name = buff; | ||
} else { | ||
dprintf("sequence not detected"); | ||
|
||
std::stringstream tmp_stream; | ||
tmp_stream << target_file_name << "_" << target_file_name_index; | ||
tmp_stream >> new_name; | ||
if (target_file_size_limit > 0) { | ||
dprintf("rotate detected"); | ||
struct stat s; | ||
|
||
//TODO: check only once | ||
if (stat(target_file_name, &s) != 0) { | ||
dprintf("Output directory not exists. Creating ..."); | ||
if (mkdir(target_file_name, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) { | ||
perror("Can't create output directory"); | ||
return -1; | ||
} | ||
} | ||
|
||
std::stringstream tmp_stream; | ||
tmp_stream << target_file_name << "/"; | ||
tmp_stream << target_file_name_index << ".ts"; | ||
tmp_stream >> new_name; | ||
} | ||
|
||
//dprintf("sock: %d, old: %s, new: %s", sock, target_file, new_name.c_str()); | ||
|
||
if (sock >= 0) { | ||
close(sock); | ||
//sock = -1; | ||
sock = -1; | ||
|
||
if (target_file_size_limit > 0) { | ||
cleanup_target_dir(); | ||
} | ||
} | ||
|
||
dprintf("opening file %s...", new_name.c_str()); | ||
|
@@ -668,6 +675,73 @@ long output_stream::get_file_size(int fd) | |
return rc == 0 ? stat_buf.st_size : -1; | ||
} | ||
|
||
int filter_dir(const struct dirent *d) | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
{ | ||
if ( | ||
strcmp(d->d_name, ".") == 0 | ||
|| strcmp(d->d_name, "..") == 0 | ||
) { | ||
return 0; | ||
} | ||
|
||
return 1; | ||
} | ||
|
||
void output_stream::cleanup_target_dir() | ||
This comment has been minimized.
Sorry, something went wrong.
mkrufky
|
||
{ | ||
if (target_fseq_size_limit == 0) { | ||
return; | ||
} | ||
|
||
struct dirent **namelist; | ||
int n, i; | ||
|
||
struct stat s; | ||
unsigned long total_size = 0; | ||
std::string path; | ||
|
||
n = scandir(target_file_name, &namelist, filter_dir, versionsort); | ||
|
||
if (n < 0) { | ||
perror("scandir"); | ||
return; | ||
}; | ||
|
||
// Calculating dir total ... | ||
for(i = 0;i < n; i++) { | ||
path.assign(target_file_name); | ||
path.append("/"); | ||
path.append(namelist[i]->d_name); | ||
|
||
if (stat(path.c_str(), &s) != 0) { | ||
continue; | ||
} | ||
|
||
total_size += s.st_size; | ||
} | ||
|
||
//Removing files ... | ||
i = 0; | ||
while(i < n && total_size >= target_fseq_size_limit) { | ||
path.assign(target_file_name); | ||
path.append("/"); | ||
path.append(namelist[i]->d_name); | ||
|
||
i++; | ||
|
||
if (stat(path.c_str(), &s) != 0 || remove(path.c_str()) != 0) { | ||
continue; | ||
} | ||
|
||
|
||
total_size -= s.st_size; | ||
|
||
dprintf("Removed %s, total: %lu", path.c_str(), total_size); | ||
} | ||
|
||
free(namelist); | ||
} | ||
|
||
int output_stream::add(void* priv, stream_callback callback, map_pidtype &pids) | ||
{ | ||
stream_cb = callback; | ||
|
@@ -763,7 +837,7 @@ int output_stream::add(char* target, map_pidtype &pids) | |
if (b_file) { | ||
target_file_name = ip; | ||
target_file_name_index = 0; | ||
|
||
This comment has been minimized.
Sorry, something went wrong. |
||
if (change_file() < 0) { | ||
return -1; | ||
} | ||
|
@@ -836,6 +910,7 @@ output::output() | |
, num_targets(0) | ||
, options(OUTPUT_NONE) | ||
, file_size_limit(0) | ||
, fseq_size_limit(0) | ||
, count_in(0) | ||
, count_out(0) | ||
{ | ||
|
@@ -1233,25 +1308,23 @@ int output::__add(char* target, map_pidtype &pids) | |
{ | ||
int search_id = search(target); | ||
if (search_id >= 0) { | ||
dprintf("target already exists #%d: %s", search_id, target); | ||
return search_id; | ||
dprintf("target already exists #%d: %s", search_id, target); | ||
return search_id; | ||
This comment has been minimized.
Sorry, something went wrong.
mkrufky
|
||
} | ||
int target_id = num_targets; | ||
|
||
dprintf("(%d->%s)", target_id, target); | ||
|
||
This comment has been minimized.
Sorry, something went wrong. |
||
/* push data into output buffer */ | ||
output_streams[target_id].rotate(file_size_limit, fseq_size_limit); | ||
|
||
int ret = output_streams[target_id].add(target, pids); | ||
|
||
|
||
if (ret == 0) { | ||
num_targets++; | ||
|
||
dprintf("Set file size limit to %lu", file_size_limit); | ||
|
||
output_streams[target_id].rotate(file_size_limit); | ||
} else | ||
dprintf("failed to add target #%d: %s", target_id, target); | ||
dprintf("failed to add target #%d: %s", target_id, target); | ||
|
||
dprintf("~(%d->%s)", target_id, target); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -89,8 +89,14 @@ class output_stream | |
void stop(); | ||
inline void stop_after_drain() { if (drain()) stop(); } | ||
int change_file(); | ||
void rotate(unsigned long int limit) { target_file_size_limit = limit; } | ||
|
||
void rotate(unsigned long int file, unsigned long int fseq) { | ||
target_file_size_limit = file; | ||
target_fseq_size_limit = fseq; | ||
} | ||
|
||
bool detect_printf_seq(const std::string&); | ||
void cleanup_target_dir(); | ||
void close_file(); | ||
|
||
bool push(uint8_t*, int); | ||
|
@@ -122,7 +128,7 @@ class output_stream | |
|
||
char* target_file_name; | ||
unsigned int target_file_name_index; | ||
unsigned long int target_file_size_limit; | ||
unsigned long int target_file_size_limit, target_fseq_size_limit; | ||
|
||
rbuf ringbuffer; | ||
|
||
|
@@ -197,7 +203,10 @@ class output : public socket_listen_iface | |
int add_http_server(int); | ||
|
||
void set_options(enum output_options opt = OUTPUT_NONE) { options = opt; } | ||
void rotate(unsigned long int limit) { file_size_limit = limit; } | ||
void rotate(unsigned long int file, unsigned long int fseq) { | ||
file_size_limit = file; | ||
fseq_size_limit = fseq; | ||
} | ||
|
||
bool check(); | ||
|
||
|
@@ -229,7 +238,7 @@ class output : public socket_listen_iface | |
|
||
enum output_options options; | ||
|
||
unsigned long int file_size_limit; | ||
unsigned long int file_size_limit, fseq_size_limit; | ||
This comment has been minimized.
Sorry, something went wrong.
mkrufky
|
||
|
||
unsigned long int count_in, count_out; | ||
|
||
|
what if the user wants to output a single file and cap it's size limit? perhaps we can make this feature work if the user specifies -ofilename and -lsizelimit but does not specify -r