summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKostyantyn Ovechko <fastinetserver@gmail.com>2010-06-28 15:27:43 +0300
committerKostyantyn Ovechko <fastinetserver@gmail.com>2010-06-28 15:27:43 +0300
commit52c55b11d27e0f6f9ee89abee930deee12aa30d3 (patch)
treea1ded635d8a5dea4670952d1593096cfdc04c0e9
parentAdd option [connections].current_speed_time_interval_msecs to segget.conf (diff)
downloadidfetch-52c55b11d27e0f6f9ee89abee930deee12aa30d3.tar.gz
idfetch-52c55b11d27e0f6f9ee89abee930deee12aa30d3.tar.bz2
idfetch-52c55b11d27e0f6f9ee89abee930deee12aa30d3.zip
Add avg speed measurement for connections.
connection->avg_speed=connection->total_dld_bytes/time_left_from(connection->start_time);
-rw-r--r--segget/connection.cpp64
-rw-r--r--segget/connection.h61
-rw-r--r--segget/mirror.cpp2
-rw-r--r--segget/segget.conf12
-rw-r--r--segget/segget.cpp10
-rw-r--r--segget/segment.cpp95
-rw-r--r--segget/segment.h93
-rw-r--r--segget/stats.cpp10
-rw-r--r--segget/tui.cpp25
-rw-r--r--segget/utils.cpp42
-rw-r--r--segget/utils.h32
11 files changed, 313 insertions, 133 deletions
diff --git a/segget/connection.cpp b/segget/connection.cpp
index c9eaf6e..4014749 100644
--- a/segget/connection.cpp
+++ b/segget/connection.cpp
@@ -23,27 +23,49 @@
* License along with Segget; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef __CONNECTION_H__
-#define __CONNECTION_H__
+#include "connection.h"
-#include <time.h>
+void Tconnection::start(){
+ try{
+ total_dld_bytes=0;
+ bytes_per_last_interval=0;
+ gettimeofday(&start_time,NULL);
+ active=true;
+ }catch(...){
+ error_log("Error in connection.cpp: start()");
+ }
+}
-class Tconnection{
- private:
- ulong bytes_per_last_interval;
- public:
- time_t start_time;
- void *segment;
- Tconnection():
- bytes_per_last_interval(0),
- start_time(0),
- segment(0){};
- void inc_bytes_per_last_interval(ulong new_bytes_count){bytes_per_last_interval+=new_bytes_count;};
- ulong get_bytes_per_last_interval(){return bytes_per_last_interval;};
- void reset_bytes_per_last_interval(){bytes_per_last_interval=0;};
-};
+void Tconnection::stop(){
+ try{
+ active=false;
+ }catch(...){
+ error_log("Error in connection.cpp: stop()");
+ }
+}
-#define MAX_CONNECTS 6 /* number of simultaneous transfers */
-time_t prev_time;
-Tconnection connection_array[MAX_CONNECTS];
-#endif \ No newline at end of file
+void Tconnection::inc_bytes_per_last_interval(ulong new_bytes_count){
+ try{
+ total_dld_bytes+=new_bytes_count;
+ bytes_per_last_interval+=new_bytes_count;
+ }catch(...){
+ error_log("Error in connection.cpp: inc_bytes_per_last_interval()");
+ }
+}
+
+void Tconnection::show_connection_progress(ulong time_diff){
+ try{
+ if (active){
+ stats.total_bytes_per_last_interval+=bytes_per_last_interval;
+ msg_segment_progress(segment->connection_num,
+ segment->segment_num, segment->try_num,
+ segment->downloaded_bytes,
+ segment->segment_size,
+ (bytes_per_last_interval*1000)/time_diff,
+ (total_dld_bytes*1000)/time_left_from(start_time));
+ bytes_per_last_interval=0;
+ }
+ }catch(...){
+ error_log("Error in connection.cpp: show_connection_progress()");
+ }
+} \ No newline at end of file
diff --git a/segget/connection.h b/segget/connection.h
new file mode 100644
index 0000000..f9bf314
--- /dev/null
+++ b/segget/connection.h
@@ -0,0 +1,61 @@
+/*
+* Copyright (C) 2010 Robin H.Johnson, Ovechko Kostyantyn <fastinetserver@gmail.com>.
+*
+* Project: IDFetch.
+* Developer: Ovechko Kostyantyn Olexandrovich (Kharkiv State Technical University of Construction and Architecture, Ukraine).
+* Mentor: Robin H. Johnson (Gentoo Linux: Developer, Trustee & Infrastructure Lead).
+* Mentoring organization: Gentoo Linux.
+* Sponsored by GSOC 2010.
+*
+* This file is part of Segget.
+*
+* Segget is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* Segget is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with Segget; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef __CONNECTION_H__
+#define __CONNECTION_H__
+
+#include <time.h>
+class Tsegment;
+#include "segment.h"
+#include "utils.h"
+
+using namespace std;
+
+class Tconnection{
+ private:
+ bool active;
+ ulong total_dld_bytes;
+ ulong bytes_per_last_interval;
+ public:
+ timeval start_time;
+ Tsegment *segment;
+ Tconnection():
+ active(0),
+ total_dld_bytes(0),
+ bytes_per_last_interval(0),
+ start_time(),
+ segment(0){};
+ void start();
+ void stop();
+ void inc_bytes_per_last_interval(ulong new_bytes_count);
+ void show_connection_progress(ulong time_diff);
+};
+
+#define MAX_CONNECTS 6 /* number of simultaneous transfers */
+time_t prev_time;
+
+Tconnection connection_array[MAX_CONNECTS];
+#endif \ No newline at end of file
diff --git a/segget/mirror.cpp b/segget/mirror.cpp
index 8ef8c92..4d66ea8 100644
--- a/segget/mirror.cpp
+++ b/segget/mirror.cpp
@@ -77,7 +77,7 @@ void Tmirror::start(){
void Tmirror::stop(ulong time, uint size){
try{
- dld_time+=time;
+ dld_time+=time/1000;
dld_size+=size;
honesty=1;
debug(toString(time)+"---"+toString(size));
diff --git a/segget/segget.conf b/segget/segget.conf
index 6f10e25..2218cec 100644
--- a/segget/segget.conf
+++ b/segget/segget.conf
@@ -28,7 +28,7 @@ max_connection_num_per_distfile=3
# Define maximum segment size in bytes.
# Default:
# max_segment_size=500000
-max_segment_size=adf500000
+max_segment_size=500000
# SYNOPSIS: resume_on=0 | 1
# - If resume_on set to 1:
@@ -40,7 +40,7 @@ max_segment_size=adf500000
# is downloaded or not.
# Default:
# resume_on=1
-resume_on=false
+resume_on=1
# MAX_TRIES
# If segment download was unsuccessful, new attempts are made. When attempts
@@ -111,13 +111,13 @@ max_connection_speed=3000
# CURRENT_SPEED_TIME_INTERVAL_MSECS
# segget transfers may have bursty nature of their traffic. Therefore, while
-# measuring current speed segget actually calculates average speed during
-# current_speed_time_interval_msecs, defined in milliseconds.
+# measuring current speed, segget actually calculates average speed during
+# current_speed_time_interval_msecs time interval, defined in milliseconds.
# Min limit:100
# Max limit: 60000
# Default:
# current_speed_time_interval_msecs=1000
-current_speed_time_interval_msecs=3000
+current_speed_time_interval_msecs=1000
# NOT IMPLEMENTED YET: max_total_speed=50000
@@ -150,7 +150,7 @@ bind_interface=none
# max_connections_num_per_mirror active downloads.
# Default:
# max_connections_num_per_mirror=1
-max_connections_num_per_mirror=1
+max_connections_num_per_mirror=2
# SYNOPSIS: collect_benchmark_stats_on=0 | 1
# - If set to 1, stats on mirrors performance will be collected.
diff --git a/segget/segget.cpp b/segget/segget.cpp
index c6aa8ab..5fcc987 100644
--- a/segget/segget.cpp
+++ b/segget/segget.cpp
@@ -31,6 +31,8 @@
#include <json/json.h>
#include <ncurses.h>
#include "pkg.cpp"
+#include "connection.cpp"
+#include "utils.cpp"
//#include "settings.cpp"
using namespace std;
@@ -213,15 +215,17 @@ int download_pkgs(){
curl_multi_remove_handle(cm, e);
current_segment->segment_file.close();
Tmirror *Pcurr_mirror=find_mirror(strip_mirror_name(current_segment->url));
- time_t now_time = time((time_t *)NULL);
+ timeval now_time;
+ gettimeofday(&now_time,NULL);
Tdistfile* prnt_distfile;
prnt_distfile=(Tdistfile*)current_segment->parent_distfile;
+ connection_array[current_segment->connection_num].stop();
prnt_distfile->active_connections_num--;
if (result!=0){
// error -> start downloading again
msg_status2(current_segment->connection_num, toString(result)+"]- Failed download "+current_segment->file_name);
debug(toString(result)+"]- Failed download "+current_segment->url);
- Pcurr_mirror->stop(now_time-connection_array[current_segment->connection_num].start_time,0);
+ Pcurr_mirror->stop(time_left_from(connection_array[current_segment->connection_num].start_time),0);
if (current_segment->try_num>=settings.max_tries){
current_segment->status=FAILED;
error_log("Segment:"+current_segment->file_name+" has reached max_tries limit - segment.status set to FAILED");
@@ -234,7 +238,7 @@ int download_pkgs(){
// no error => count this one and start new
log("Succesfully downloaded "+current_segment->file_name+" on connection#"+toString(current_segment->connection_num));
debug(" Successful download "+current_segment->url);
- Pcurr_mirror->stop(now_time-connection_array[current_segment->connection_num].start_time,current_segment->segment_size);
+ Pcurr_mirror->stop(time_left_from(connection_array[current_segment->connection_num].start_time),current_segment->segment_size);
current_segment->status=DOWNLOADED;
prnt_distfile->inc_dld_segments_count(current_segment);
};
diff --git a/segget/segment.cpp b/segget/segment.cpp
index 08ab575..d70d226 100644
--- a/segget/segment.cpp
+++ b/segget/segment.cpp
@@ -24,69 +24,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef __SEGMENT_H__
-#define __SEGMENT_H__
-#include <sstream>
-#include <fstream>
-#include <cstring>
-#include <string>
-#include <iostream>
-#include <stdio.h>
-#include <cstdio>
-#include <ncurses.h>
-#include <curl/curl.h>
-#include "settings.h"
-#include "stats.cpp"
-
-using namespace std;
-
-extern Tsettings settings;
-unsigned long downloaded_bytes=0;
-size_t write_data(void *buffer, size_t size, size_t nmemb, void *cur_segment);
-
-enum Tstatus{WAITING, DOWNLOADING, DOWNLOADED, FAILED};
-
-class Tsegment{
- private:
- CURL *easyhandle;
- char* urllist;
- public:
- string file_name;
- Tstatus status;
- uint try_num;
- void* parent_distfile;
- uint connection_num;
- uint segment_num;
- uint segment_size;
- unsigned long downloaded_bytes;
- string url;
- string range;
- ofstream segment_file;
- Tsegment():
- easyhandle(0),
- urllist(0),
- file_name(""),
- status(WAITING),
- try_num(0),
- parent_distfile(0),
- connection_num(0),
- segment_num(0),
- segment_size(1000),
- downloaded_bytes(0),
- url(""),
- range(""),
- segment_file(0)
- {};
- Tsegment(const Tsegment &L); // copy constructor
- Tsegment & operator=(const Tsegment &L);
- ~Tsegment();
- void set_segment(void *prnt_distfile, uint seg_num, string distfile_name, ulong default_seg_size, ulong range_end);
- void prepare_for_connection(CURLM *cm, uint con_num, uint distfile_num, string segment_url);
- string get_file_name(){return file_name;};
- int add_easy_handle_to_multi(CURLM *cm);
-};
-
-Tsegment *segments_in_progress[MAX_CONNECTS]={0};
+#include "segment.h"
void Tsegment::set_segment(void *prnt_distfile, uint seg_num, string distfile_name, ulong default_seg_size, ulong range_end){
try{
@@ -125,7 +63,7 @@ void Tsegment::prepare_for_connection(CURLM *cm, uint con_num, uint distfile_num
status=DOWNLOADING;
downloaded_bytes=0;
connection_num=con_num;
- connection_array[con_num].start_time=time((time_t *)NULL);
+ connection_array[con_num].start();
url=segment_url;
try_num++;
add_easy_handle_to_multi(cm);
@@ -198,14 +136,7 @@ void show_progress(double time_diff){
for (uint con_num=0; con_num<MAX_CONNECTS; con_num++){
// ulong speed=bytes_written*1000/(diff_sec+diff_milli);
//if connection is not NULL
- if (connection_array[con_num].segment){
- Tsegment* segment=(Tsegment*)connection_array[con_num].segment;
- stats.total_bytes_per_last_interval+=connection_array[con_num].get_bytes_per_last_interval();
- msg_segment_progress(con_num,segment->segment_num, segment->try_num,
- segment->downloaded_bytes,segment->segment_size,
- (connection_array[con_num].get_bytes_per_last_interval()*1000)/time_diff);
- connection_array[con_num].reset_bytes_per_last_interval();
- }
+ connection_array[con_num].show_connection_progress(time_diff);
}
stats.last_time_interval=time_diff;
stats.show_totals();
@@ -221,7 +152,6 @@ size_t write_data(void *buffer, size_t size, size_t nmemb, void *cur_segment){
Tsegment *segment;
segment =(Tsegment*)cur_segment;
segment->downloaded_bytes+=nmemb;
-
try{
segment->segment_file.write((char*)buffer,nmemb*size);
}
@@ -229,27 +159,14 @@ size_t write_data(void *buffer, size_t size, size_t nmemb, void *cur_segment){
error_log("Can't write segment file:"+segment->file_name);
}
connection_array[segment->connection_num].inc_bytes_per_last_interval(bytes_written);
-
- timeval now_time;
- gettimeofday(&now_time,NULL);
-// ulong diff_sec = difftime(now_time.tv_sec, prev_time.tv_sec) * 1000000;
-// ulong diff_milli = difftime(now_time.tv_usec, prev_time.tv_usec) + diff_sec;
-
- double time_diff_msecs=(now_time.tv_sec-stats.previous_time.tv_sec)*1000+(now_time.tv_usec-stats.previous_time.tv_usec)/1000;
-// debug(segment->file_name+"==="+toString((ulong)now_time)+"=="+toString(now_time));
+ ulong time_diff_msecs=time_left_from(stats.previous_time);
if (time_diff_msecs >= settings.current_speed_time_interval_msecs){
-// debug(segment->file_name+"--->"+toString((ulong)()));
show_progress(time_diff_msecs);
- stats.previous_time=now_time;
+ stats.reset_previous_time();
};
-// else
-// debug(segment->file_name+"==="+toString(prev_time.tv_sec)+"=="+toString(prev_time.tv_usec)+"==="+toString((ulong)(diff_milli)));
- //toString(diff_milli));
- //refresh();
}
catch(...){
error_log("Error in segment.cpp: write_data()");
}
return bytes_written;
-}
-#endif \ No newline at end of file
+} \ No newline at end of file
diff --git a/segget/segment.h b/segget/segment.h
new file mode 100644
index 0000000..34ca383
--- /dev/null
+++ b/segget/segment.h
@@ -0,0 +1,93 @@
+/*
+* Copyright (C) 2010 Robin H.Johnson, Ovechko Kostyantyn <fastinetserver@gmail.com>.
+*
+* Project: IDFetch.
+* Developer: Ovechko Kostyantyn Olexandrovich (Kharkiv State Technical University of Construction and Architecture, Ukraine).
+* Mentor: Robin H. Johnson (Gentoo Linux: Developer, Trustee & Infrastructure Lead).
+* Mentoring organization: Gentoo Linux.
+* Sponsored by GSOC 2010.
+*
+* This file is part of Segget.
+*
+* Segget is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* Segget is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with Segget; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef __SEGMENT_H__
+#define __SEGMENT_H__
+#include <sstream>
+#include <fstream>
+#include <cstring>
+#include <string>
+#include <iostream>
+#include <stdio.h>
+#include <cstdio>
+#include <ncurses.h>
+#include <curl/curl.h>
+#include "settings.h"
+#include "stats.cpp"
+
+using namespace std;
+
+extern Tsettings settings;
+unsigned long downloaded_bytes=0;
+size_t write_data(void *buffer, size_t size, size_t nmemb, void *cur_segment);
+
+enum Tstatus{WAITING, DOWNLOADING, DOWNLOADED, FAILED};
+
+class Tsegment{
+ private:
+ CURL *easyhandle;
+ char* urllist;
+ public:
+ string file_name;
+ Tstatus status;
+ uint try_num;
+ void* parent_distfile;
+ uint connection_num;
+ uint segment_num;
+ uint segment_size;
+ unsigned long downloaded_bytes;
+ string url;
+ string range;
+ ofstream segment_file;
+ Tsegment():
+ easyhandle(0),
+ urllist(0),
+ file_name(""),
+ status(WAITING),
+ try_num(0),
+ parent_distfile(0),
+ connection_num(0),
+ segment_num(0),
+ segment_size(1000),
+ downloaded_bytes(0),
+ url(""),
+ range(""),
+ segment_file(0)
+ {};
+ Tsegment(const Tsegment &L); // copy constructor
+ Tsegment & operator=(const Tsegment &L);
+ ~Tsegment();
+ void set_segment(void *prnt_distfile, uint seg_num, string distfile_name, ulong default_seg_size, ulong range_end);
+ void prepare_for_connection(CURLM *cm, uint con_num, uint distfile_num, string segment_url);
+ string get_file_name(){return file_name;};
+ int add_easy_handle_to_multi(CURLM *cm);
+};
+
+Tsegment *segments_in_progress[MAX_CONNECTS]={0};
+
+void show_progress(double time_diff);
+size_t write_data(void *buffer, size_t size, size_t nmemb, void *cur_segment);
+#endif \ No newline at end of file
diff --git a/segget/stats.cpp b/segget/stats.cpp
index 0fb61c7..f6b0ec5 100644
--- a/segget/stats.cpp
+++ b/segget/stats.cpp
@@ -27,7 +27,7 @@
#ifndef __STATS_H__
#define __STATS_H__
-#include "connection.cpp"
+#include "connection.h"
#include "tui.h"
#include <sys/time.h>
using namespace std;
@@ -60,6 +60,7 @@ class Tstats{
void inc_total_size(ulong more_bytes){ total_size+=more_bytes;};
ulong get_total_size(){return total_size;};
void show_totals();
+ void reset_previous_time();
};
void Tstats::show_totals(){
@@ -93,5 +94,12 @@ void Tstats::show_totals(){
}
}
+void Tstats::reset_previous_time(){
+ try{
+ gettimeofday(&previous_time,NULL);
+ }catch(...){
+ error_log_no_msg("Error in stats.cpp: reset_previous_time()");
+ }
+}
Tstats stats;
#endif \ No newline at end of file
diff --git a/segget/tui.cpp b/segget/tui.cpp
index d2a4646..1ddf42a 100644
--- a/segget/tui.cpp
+++ b/segget/tui.cpp
@@ -63,27 +63,28 @@ void msg_connecting(uint connection_num, uint distfile_num, uint segment_num, st
}
}
-void msg_segment_progress(uint connection_num, uint segment_num, uint try_num, ulong dld_bytes, ulong total_bytes, ulong speed){
+void msg_segment_progress(uint connection_num, uint segment_num, uint try_num, ulong dld_bytes, ulong total_bytes, ulong speed, ulong avg_speed){
try{
- int percent=dld_bytes*100/total_bytes;
+ string speed_str;
+ string avg_speed_str;
if (speed<1000)
- msg(connection_num*CONNECTION_LINES,0,
- field("[",connection_num,2)+"]"
- +field(" Segment:",segment_num, 5)
- +field(" Try:",try_num,4)
- +field(" Bytes:",dld_bytes,7)
- +field(" / ",total_bytes,7)
- +field(" = ",percent,3)+"%%"
- +field(" Speed:",speed,7)+" b/s");
+ speed_str=field(" Speed:",speed,7)+" b/s";
else
- msg(connection_num*CONNECTION_LINES,0,
+ speed_str=field(" Speed:",speed/1000,7)+" Kb/s";
+ if (avg_speed<1000)
+ avg_speed_str=field(" AVG speed:",avg_speed,7)+" b/s";
+ else
+ avg_speed_str=field(" AVG speed:",avg_speed/1000,7)+" Kb/s";
+ int percent=dld_bytes*100/total_bytes;
+ msg(connection_num*CONNECTION_LINES,0,
field("[",connection_num,2)+"]"
+field(" Segment:",segment_num, 5)
+field(" Try:",try_num,4)
+field(" Bytes:",dld_bytes,7)
+field(" / ",total_bytes,7)
+field(" = ",percent,3)+"%%"
- +field(" Speed:",speed/1000,7)+" Kb/s");
+ +speed_str
+ +avg_speed_str);
}
catch(...)
{
diff --git a/segget/utils.cpp b/segget/utils.cpp
new file mode 100644
index 0000000..cdc2dc8
--- /dev/null
+++ b/segget/utils.cpp
@@ -0,0 +1,42 @@
+/*
+* Copyright (C) 2010 Robin H.Johnson, Ovechko Kostyantyn <fastinetserver@gmail.com>.
+*
+* Project: IDFetch.
+* Developer: Ovechko Kostyantyn Olexandrovich (Kharkiv State Technical University of Construction and Architecture, Ukraine).
+* Mentor: Robin H. Johnson (Gentoo Linux: Developer, Trustee & Infrastructure Lead).
+* Mentoring organization: Gentoo Linux.
+* Sponsored by GSOC 2010.
+*
+* This file is part of Segget.
+*
+* Segget is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* Segget is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with Segget; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "utils.h"
+#include "sys/time.h"
+ulong time_left_from(timeval from_time){
+ try{
+ timeval now_time;
+ gettimeofday(&now_time,NULL);
+ ulong timeleft=(now_time.tv_sec-from_time.tv_sec)*1000+(now_time.tv_usec-from_time.tv_usec)/1000;
+ if (timeleft<1)
+ timeleft=1;
+ return timeleft;
+ }catch(...){
+ error_log("Error in utils.cpp: time_left_from()");
+ return 1;
+ }
+}
+
diff --git a/segget/utils.h b/segget/utils.h
new file mode 100644
index 0000000..60fd70c
--- /dev/null
+++ b/segget/utils.h
@@ -0,0 +1,32 @@
+/*
+* Copyright (C) 2010 Robin H.Johnson, Ovechko Kostyantyn <fastinetserver@gmail.com>.
+*
+* Project: IDFetch.
+* Developer: Ovechko Kostyantyn Olexandrovich (Kharkiv State Technical University of Construction and Architecture, Ukraine).
+* Mentor: Robin H. Johnson (Gentoo Linux: Developer, Trustee & Infrastructure Lead).
+* Mentoring organization: Gentoo Linux.
+* Sponsored by GSOC 2010.
+*
+* This file is part of Segget.
+*
+* Segget is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* Segget is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with Segget; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef __UTILS_H__
+#define __UTILS_H__
+
+ulong time_left_from(timeval from_time);
+
+#endif \ No newline at end of file