2 * Name: Shared functions
4 * Purpose: Functions that are used various times in cas
6 * Author: Pedro de Oliveira <falso@rdk.homeip.net>
8 * Copyright (c) 2004-2008 Pedro de Oliveira
10 * This file is part of aMule.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the
24 * Free Software Foundation, Inc.,
25 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
34 /* XXX This needs to be replaced so that we use
35 * autoconf to detect the target OS -- As of now
36 * it should compile fine in other non UNIX-like
37 * platforms, at the expense of only being sure
38 * that UNIX-specific code will be compiled if
39 * using GCC (which defines those __unix__ macros)
40 * autoconf defines should be in place to test for
41 * functions like getpwuid() in UNIX-like systems
42 * instead of doing this...
46 #include <CoreServices/CoreServices.h>
47 #define CAS_DIR_SEPARATOR "/"
48 #elif defined(__WIN32__)
53 #define CAS_DIR_SEPARATOR "\\"
55 #define CAS_DIR_SEPARATOR "/"
56 #if defined(unix) || defined(__unix__) || defined(__unix)
64 /* try (hard) to get correct path for aMule signature
65 * !! it's caller's responsibility to free return value
68 char *get_path(const char *file
)
70 char *ret
; /* caller should free return value */
71 static char *saved_home
= NULL
;
72 static size_t home_len
= 0;
74 if (saved_home
== NULL
) {
81 if (FSFindFolder(kUserDomain
, kApplicationSupportFolderType
, kCreateFolder
, &fsRef
) == noErr
) {
82 CFURLRef urlRef
= CFURLCreateFromFSRef(NULL
, &fsRef
);
84 if (CFURLGetFileSystemRepresentation(urlRef
, true, home
, sizeof(home
))) {
85 strcat(home
, CAS_DIR_SEPARATOR
"aMule");
91 #elif defined(__WIN32__)
97 HRESULT hr
= SHGetSpecialFolderLocation(NULL
, CSIDL_APPDATA
, &pidl
);
100 if (SHGetPathFromIDList(pidl
, home
)) {
101 strcat(home
, CAS_DIR_SEPARATOR
"aMule");
107 SHGetMalloc(&pMalloc
);
109 IMalloc_Free(pMalloc
, pidl
);
110 IMalloc_Release(pMalloc
);
118 /* get home directory */
119 if ( (home
= getenv("HOME")) == NULL
) {
123 /* if $HOME is not available try user database */
132 * Section 6.5.14 of ANSI C specs (grab C99 at http://www.nirvani.net/docs/ansi_c.pdf)
134 * "Unlike the bitwise | operator, the || operator _guarantees_ left-to-right
135 * evaluation; there is a sequence point after the evaluation of the first
136 * operand. If the first operand compares unequal to 0, the second operand
137 * _is not evaluated_."
139 * I'm going to revert it and wait until Jacobo or whoever changed it
140 * screams loudly, tries to kill me, and explains why this has to be
141 * this way. Maybe pre-ansi compilers? Doubtful.
145 if (pwd
== NULL
|| pwd
->pw_dir
== NULL
)
149 #endif /* CAS_UNIX */
151 strcat(home
, CAS_DIR_SEPARATOR
".aMule");
153 #endif /* !__APPLE__ && !__WIN32__ */
155 /* save the result for future calls */
156 home_len
= strlen(home
);
157 if ( (saved_home
= strdup(home
)) == NULL
)
161 /* get full path space */
163 /* Unleashed - Guys... you broke this and it was OK
164 * "+ 2" means "plus '/' and '\0'"
166 ret
= malloc((home_len
+ strlen(file
) + 2) * sizeof(char));
170 strcpy(ret
, saved_home
);
171 ret
[home_len
] = CAS_DIR_SEPARATOR
[0];
172 ret
[home_len
+1] = '\0';
174 /* the string is guaranteed to be null-terminated
175 * so no need to do this...
176 * ret[total_len] = '\0';
182 char *get_amule_path(const char *file
, int force_directory
, const char *cmdline_path
)
187 return get_path(file
);
190 if ((path
= malloc(strlen(cmdline_path
) + strlen(file
) + 2)) == NULL
) {
194 strcpy(path
, cmdline_path
);
195 if (force_directory
) {
196 if (path
[strlen(path
) - 1] != CAS_DIR_SEPARATOR
[0]) {
197 strcat(path
, CAS_DIR_SEPARATOR
);
201 if (path
[strlen(path
) - 1] == CAS_DIR_SEPARATOR
[0]) {
210 * this function is used to convert bytes to any other unit
213 * return "Bad format" if could not convert string
215 char *convbytes(char *input
)
217 char *units
[] = { "Bytes", "KB", "MB", "GB", "TB", "PB" };
219 static char output
[50];
223 /* do proper conversion and check for errors */
225 bytes
= (float) strtod(input
, &endptr
);
227 /* check bad string conversion or value out of range */
228 if (*endptr
!= '\0' || errno
== ERANGE
)
231 /* this loop converts bytes and sets i to the appropriate
232 * index in 'units' array
233 * note: sizeof(units) / sizeof(char*) is the number of
234 * elements in 'units' array
236 for (; i
< (sizeof(units
) / sizeof(char *)) - 1; i
++) {
242 snprintf(output
, 50, "%.2f %s", bytes
, units
[i
]);
247 void replace(char *tmpl
, const char *search
, const char *to_replace
)
251 int befLen
,srchLen
,repLen
,totLen
;
253 /* returning the 'tmpl' if 'search' is NULL */
254 if (NULL
== tmpl
|| NULL
== search
) /* || NULL == to_replace) */
261 /* if 'search' is found in 'tmpl' */
262 retStr
= strstr(tmpl
, search
);
268 totLen
= strlen(tmpl
);
269 befLen
= (int)(retStr
- tmpl
);
270 srchLen
= strlen(search
);
271 repLen
= strlen(to_replace
);
273 /* dynamic buffer creation... */
274 dest
= (char*)malloc(totLen
+ 1 + repLen
- srchLen
);
278 /* copy the before buffer */
279 strncpy(dest
, tmpl
, befLen
);
280 /* copy the replace string */
281 memcpy((dest
+befLen
), to_replace
, repLen
); /* strcat(dest, to_replace); */
282 /* copy the after buffer */
283 memcpy((dest
+befLen
+repLen
), &tmpl
[befLen
+ srchLen
], strlen(&tmpl
[befLen
+ srchLen
])); /*strcat(dest, &tmpl[befLen + repLen]); */
285 /* now replace the template string with the resulting and search it again */
287 /* we need this, because we're modifying the 'tmpl' instead of creating a new one (so we need to update the position of the null char) */
288 tmpl
[totLen
- srchLen
+ repLen
] = '\0';
294 char *timeconv(char *input
)
296 int count
= atoi(input
);
300 snprintf (ret
,50,"?");
302 snprintf (ret
,50,"%02i %s", count
, "secs" );
303 else if (count
< 3600)
304 snprintf (ret
,50,"%i:%02i %s", count
/60, (count
% 60), "mins" );
305 else if (count
< 86400)
306 snprintf (ret
,50,"%i:%02i %s", count
/3600, (count
% 3600)/60, "h" );
308 snprintf (ret
,50,"%i %s %02i %s", count
/86400, "D" , (count
% 86400) / 3600, "h" );