1 /*********************************************************************/
2 // dar - disk archive - a backup/restoration program
3 // Copyright (C) 2002-2052 Denis Corbin
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 //
19 // to contact the author : http://dar.linux.free.fr/email.html
20 /*********************************************************************/
21 
22 #include "../my_config.h"
23 
24 extern "C"
25 {
26 #if HAVE_STRING_H
27 #include <string.h>
28 #endif
29 
30 #if HAVE_STRINGS_H
31 #include <strings.h>
32 #endif
33 
34 #if STDC_HEADERS
35 # include <string.h>
36 #else
37 # if !HAVE_STRCHR
38 #  define strchr index
39 #  define strrchr rindex
40 # endif
41     char *strchr (), *strrchr ();
42 # if !HAVE_MEMCPY
43 #  define memcpy(d, s, n) bcopy ((s), (d), (n))
44 #  define memmove(d, s, n) bcopy ((s), (d), (n))
45 # endif
46 #endif
47 
48 #if HAVE_UNISTD_H
49 #include <unistd.h>
50 #endif
51 
52 #if HAVE_SYS_STAT_H
53 #include <sys/stat.h>
54 #endif
55 
56 #if HAVE_SYS_TYPES_H
57 #include <sys/types.h>
58 #endif
59 
60 #if HAVE_FCNTL_H
61 #include <fcntl.h>
62 #endif
63 
64 #if HAVE_ERRNO_H
65 #include <errno.h>
66 #endif
67 } // end extern "C"
68 
69 #include "sar_tools.hpp"
70 #include "erreurs.hpp"
71 #include "user_interaction.hpp"
72 #include "sar.hpp"
73 #include "tools.hpp"
74 #include "tuyau.hpp"
75 #include "cygwin_adapt.hpp"
76 #include "deci.hpp"
77 
78 using namespace std;
79 
80 namespace libdar
81 {
82 
sar_tools_make_filename(const string & base_name,const infinint & num,const infinint & min_digits,const string & ext)83     string sar_tools_make_filename(const string & base_name,
84 				   const infinint & num,
85 				   const infinint & min_digits,
86 				   const string & ext)
87     {
88         deci conv = num;
89 	string digits = conv.human();
90 
91         return base_name + '.' + sar_tools_make_padded_number(digits, min_digits) + '.' + ext;
92     }
93 
sar_tools_extract_num(const string & filename,const string & base_name,const infinint & min_digits,const string & ext,infinint & ret)94     bool sar_tools_extract_num(const string & filename,
95 			       const string & base_name,
96 			       const infinint & min_digits,
97 			       const string & ext,
98 			       infinint & ret)
99     {
100         try
101         {
102 	    U_I min_size = base_name.size() + ext.size() + 2; // 2 for two dot characters
103 	    if(filename.size() <= min_size)
104 		return false; // filename is too short
105 
106             if(infinint(filename.size() - min_size) < min_digits && !min_digits.is_zero())
107                 return false; // not enough room for all digits
108 
109             if(filename.find(base_name) != 0) // checking that base_name is present at the beginning
110                 return false;
111 
112             if(filename.rfind(ext) != filename.size() - ext.size()) // checking that extension is at the end
113                 return false;
114 
115             deci conv = string(filename.begin()+base_name.size()+1, filename.begin() + (filename.size() - ext.size()-1));
116             ret = conv.computer();
117             return true;
118         }
119 	catch(Ethread_cancel & e)
120 	{
121 	    throw;
122 	}
123         catch(Egeneric &e)
124         {
125             return false;
126         }
127     }
128 
sar_tools_get_higher_number_in_dir(entrepot & entr,const string & base_name,const infinint & min_digits,const string & ext,infinint & ret)129     bool sar_tools_get_higher_number_in_dir(entrepot & entr,
130 					    const string & base_name,
131 					    const infinint & min_digits,
132 					    const string & ext,
133 					    infinint & ret)
134     {
135         infinint cur;
136         bool somme = false;
137 	string entry;
138 
139 	try
140 	{
141 	    entr.read_dir_reset();
142 	}
143 	catch(Erange & e)
144 	{
145 	    return false;
146 	}
147 
148 	ret = 0;
149 	somme = false;
150 	while(entr.read_dir_next(entry))
151 	    if(sar_tools_extract_num(entry, base_name, min_digits, ext, cur))
152 	    {
153 		if(cur > ret)
154 		    ret = cur;
155 		somme = true;
156 	    }
157 
158         return somme;
159     }
160 
sar_tools_make_padded_number(const string & num,const infinint & min_digits)161     string sar_tools_make_padded_number(const string & num,
162 					const infinint & min_digits)
163     {
164 	string ret = num;
165 
166 	while(infinint(ret.size()) < min_digits)
167 	    ret = string("0") + ret;
168 
169 	return ret;
170     }
171 
172 } // end of namespace
173