/* Copyright (C) 2000-2003 Markus Lausser (sgop@users.sf.net) This is free software distributed under the terms of the GNU Public License. See the file COPYING for details. */ #include #include #include #include #include "utils.h" #include "string.h" unsigned long extract_bytes(char* string) { char* pos; unsigned long result = 0; if (!string) return 0; if (!isdigit(*string)) return 0; pos = string; while (isdigit(*pos)) { result *= 10; result += *pos -'0'; pos++; } if (*pos == ' ') pos++; switch (*pos) { case 'g': case 'G': result *= 1024*1024*1024; break; case 'm': case 'M': result *= 1024*1024; break; case 'k': case 'K': result *= 1024; break; case 'b': case 'B': case ' ': case 0: default: break; } return result; } int extract_duration(char* string) { char* pos; unsigned long result = 0; if (!string) return 0; if (!isdigit(*string)) return 0; pos = string; while (isdigit(*pos)) { result *= 10; result += *pos -'0'; pos++; } if (*pos == ' ') pos++; switch (*pos) { case 'h': case 'H': result *= 3600; break; case 'm': case 'M': result *= 60; break; case 's': case 'S': case ' ': case 0: default: break; } return result; } // dont pass str == NULL ! char* print_bytes(char *str, unsigned long bytes) { if (bytes == 0) sprintf(str, "0B"); else if (bytes%(1024*1024*1024) == 0) sprintf(str, "%luG", bytes/1024/1024/1024); else if (bytes%(1024*1024) == 0) sprintf(str, "%luM", bytes/1024/1024); else if (bytes%1024 == 0) sprintf(str, "%luK", bytes/1024); else sprintf(str, "%luB", bytes); return str; } // dont pass str == NULL ! char* print_duration(char* str, int seconds) { if (seconds == 0) sprintf(str, "0s"); else if (seconds%(60*60) == 0) sprintf(str, "%dh", seconds/60/60); else if (seconds%60 == 0) sprintf(str, "%dm", seconds/60); else sprintf(str, "%ds", seconds); return str; } char* print_size(char *str, double bytes) { if (bytes < 1024) sprintf(str, "%ld B", (long) bytes); else if (bytes < 1024 * 128) sprintf(str, "%.2f kB", bytes / 1024.0); else if (bytes < 1024 * 1024) sprintf(str, "%.1f kB", bytes / 1024.0); else if (bytes < 1024 * 1024 * 128) sprintf(str, "%.2f MB", bytes / 1024.0 / 1024.0); else if (bytes < 1024 * 1024 * 1024) sprintf(str, "%.1f MB", bytes / 1024.0 / 1024.0); else sprintf(str, "%.1f GB", bytes / 1024.0 / 1024.0 / 1024.0); return str; } char* print_time_short(char *str, int secs) { int min = secs / 60; int sec = secs % 60; int hour = min / 60; min = min % 60; *str = 0; if (hour) { sprintf(str, "%02d:%02d:%02d", hour, min, sec); } else { sprintf(str, "%02d:%02d", min, sec); } return str; } // format hours:minutes:seconds char* print_time(char *str, int secs) { int min = secs / 60; int sec = secs % 60; int hour = min / 60; min = min % 60; *str = 0; sprintf(str, "%02d:%02d:%02d", hour, min, sec); return str; } /* format: 1:23 d 2:59 h 3:59 m 59 s */ char* print_time_unit(char *str, int secs) { int day, hour, min, sec; char pfx = ' '; if (secs < 0) { secs = -secs; pfx = '-'; } sec = secs % 60; min = secs / 60; hour = min / 60; day = hour / 24; min = min % 60; hour = hour % 24; if (day) { sprintf(str, "%c%d:%02d d", pfx, day, hour); } else if (hour) { sprintf(str, "%c%02d:%02d h", pfx, hour, min); } else if (min) { sprintf(str, "%c%02d:%02d m", pfx, min, sec); } else { sprintf(str, "%c%02d s", pfx, sec); } return str; } char* print_speed(char *str, long bytes, int withdot) { if (withdot) { if (bytes < 1024) sprintf(str, "%ld B/s", bytes); else if (bytes < 1024 * 128) sprintf(str, "%.2f kB/s", (double) bytes / 1024.0); else if (bytes < 1024 * 1024) sprintf(str, "%.1f kB/s", (double) bytes / 1024.0); else sprintf(str, "%.1f MB/s", (double) bytes / 1024.0 / 1024.0); } else { if (bytes < 1024) sprintf(str, "%ld B/s", bytes); else if (bytes < 1024 * 8) sprintf(str, "%.1f kB/s", (double) bytes / 1024.0); else if (bytes < 1024 * 1024) sprintf(str, "%ld kB/s", bytes / 1024); else if (bytes < 1024 * 1024 * 8) sprintf(str, "%.1f MB/s", (double) bytes / 1024.0 / 1024.0); else sprintf(str, "%ld MB/s", bytes / 1024 / 1024); } return str; } // returns static! char* get_last_dir(char *filename) { static char dir[2048]; char *pos1; char *pos2; pos1 = strchr(filename, DIR_SEP); pos2 = strrchr(filename, DIR_SEP); if (!pos1) return NULL; if (pos1 == pos2) return NULL; pos2[0] = 0; pos1 = strrchr(filename, DIR_SEP) + 1; strcpy(dir, pos1); pos2[0] = DIR_SEP; return dir; } // returns pointer! char* get_file_name(char *filename) { char *pos1; pos1 = strrchr(filename, DIR_SEP); if (!pos1) return filename; else return (pos1 + 1); } // returns pointer! char* get_short_name(char *longname) { char *pos1; char *pos2; // extracting short name pos1 = strchr(longname, DIR_SEP); pos2 = strrchr(longname, DIR_SEP); if (pos1 == pos2) { // none or only one sep found return longname; } else { pos2[0] = 'Q'; pos1 = strrchr(longname, DIR_SEP); pos2[0] = DIR_SEP; pos1++; return pos1; } } char* local_to_napster(char *name) { char *ptr; if (DIR_SEP == '\\') return name; // no conversion needed ptr = name; if (!ptr || !*ptr) return NULL; while (*ptr) { if (*ptr == DIR_SEP) *ptr = '\\'; else if (*ptr == '\"') *ptr = '\''; ptr++; } return ptr; } char* unix_to_win(char *name) { char *ptr; ptr = name; if (!ptr || !*ptr) return NULL; while (*ptr) { if (*ptr == '/') *ptr = '\\'; ptr++; } return ptr; } char* local_to_napster_hide(char *name) { char *ptr; char* start; // hide the home dir if (!strncmp(name, "/home/", 6)) { start = strchr(name+6, '/'); if (!start) start = name+5; } else { start = name; } ptr = name; while (1) { if (*start == '/') *ptr++ = '\\'; else if (*start == '\"') *ptr++ = '\''; else *ptr++ = *start; if (*start == 0) break; start++; } return name; } char* napster_to_local(char *name) { char *ptr; if (DIR_SEP == '\\') return name; // no conversion needed ptr = name; if (!ptr || !*ptr) return NULL; while (*ptr) { if (*ptr == '\\') *ptr = DIR_SEP; ptr++; } return ptr; } void convert_local_name(char *fname) { if (!fname) return; while (*fname) { if (*fname == '?') *fname = '_'; else if (*fname == '*') *fname = '_'; else if (*fname == ':') *fname = '_'; fname++; } } void convert_quotes(char *string) { while ((string = strchr(string, '\"'))) *string = '\''; } char* rename_file(char *filename) { struct stat st; char* result; char* pos; pos = strstr(filename, "_L"); if (pos && pos[2] >= '0' && pos[2] <= '9' && pos[3] >= '0' && pos[3] <= '9' && ((pos[4] >= '0' && pos[4] <= '9') || pos[4] == 0)) { result = filename; pos += 2; } else { pos = strrchr(filename, '.'); if (pos) { *pos = 0; result = g_strdup_printf("%s_L000.%s", filename, pos+1); *pos = '.'; pos = strrchr(result, '.') - 3; } else { result = g_strdup_printf("%s_L000", filename); pos = result+strlen(result)-3; } g_free(filename); } while (1) { if (pos[2] == '9') { pos[2] = '0'; if (pos[1] == '9') { pos[1] = '0'; if (pos[1] == '9') { return NULL; } else { pos[1] += 1; } } else { pos[1] += 1; } } else { pos[2] += 1; } if (stat(result, &st) < 0) break; } return result; } char* arg(char *data, int flags) { static char *string; char *pos; char *pos2; if (data) string = data; if (!string) return NULL; if (flags & 1) { pos = string; string = NULL; if (*pos == 0) return NULL; else return pos; } while (isspace(*string)) string++; if (*string == '"') { pos = pos2 = ++string; if (flags & 2) { for (;;) { char c = *string++; if (c == '\\') c = *string++; else if (c == '"') break; if (!c) { string = NULL; return NULL; } *pos2++ = c; } *pos2 = 0; if (*string == ' ') string++; else string = NULL; return pos; } else { int cnt = 1; char* last_pos = NULL; while (1) { pos2 = strchr(pos2, '"'); if (!pos2) break; if (pos2[1] == ' ' || pos2[1] == 0 || pos2[1] == '\n') { cnt--; last_pos = pos2; if (cnt == 0) break; } else if (pos2[1] == '"') { if (cnt > 1) cnt--; else cnt++; } else { cnt++; pos2 = pos2+1; } pos2 = pos2+1; } if (!pos2) pos2 = last_pos; // end quote found? if (pos2) { *pos2 = 0; string = pos2 + 1; if (*string == ' ') string++; return pos; } else { printf("** unterminated quoted string **\n"); string = NULL; return NULL; } } } else { pos = string; pos2 = strchr(string, ' '); if (pos2) { *pos2 = 0; string = pos2 + 1; } else { string = NULL; } if (*pos == 0) return NULL; else return pos; } return NULL; } #define pchar(c) do { \ if (bp == sizeof(buf)) { \ fwrite(buf, 1, sizeof(buf), f); \ bp = 0; \ } \ buf[bp++] = c; \ } while(0) void qfprintf(FILE *f, const char *fmt, ...) { va_list args; char *str; long num; unsigned long unum; int bp, sign, place; char c, convert[20], buf[1024]; bp = 0; va_start(args, fmt); while ((c = *fmt++)) if (c == '%') { if (!(c = *fmt++)) break; if (c == '%') pchar('%'); else if (c == 's') { str = va_arg(args, char *); if (!str) str = "(null)"; while((c = *str++)) pchar(c); } else if (c == 'S') { str = va_arg(args, char *); if (!str) str = "(null)"; pchar('"'); while((c = *str++)) { if (c == '\\' || c == '"') pchar('\\'); pchar(c); } pchar('"'); } else { if (c == 'l') { if (!(c = *fmt++)) break; if (c == 'd') { sign = 1; num = va_arg(args, long); } else if (c == 'u') { sign = 0; num = va_arg(args, unsigned long); } else continue; } else if (c == 'd') { sign = 1; num = va_arg(args, int); } else if (c == 'u') { sign = 0; num = va_arg(args, unsigned int); } else continue; if (sign && num < 0) { pchar('-'); unum = -num; } else unum = num; place = 0; do { convert[place++] = unum % 10 + '0'; unum /= 10; } while (unum); while (place > 0) pchar(convert[--place]); } } else pchar(c); va_end(args); fwrite(buf, 1, bp, f); } char* mfgets(char *buf, int size, FILE *f) { if (fgets(buf, size, f)) { int len = strlen(buf); if (len && buf[len-1] == '\n') buf[len-1] = 0; else if (!feof(f)) { printf("Error: line too long\n"); } return buf; } return 0; } static int directory_exists(char *dir) { struct stat st; if (stat(dir, &st) < 0) return 0; else return 1; } int create_dir(char *dir) { char *pos; char *slash; if (!dir) return 0; if (directory_exists(dir)) return 1; slash = dir; while ((pos = strchr(slash + 1, DIR_SEP)) != NULL) { pos[0] = 0; if (!directory_exists(dir)) { if (mkdir(dir, 7 * 64 + 5 * 8 + 5)) { printf("Could not create folder [%s]\n", dir); return 0; } } pos[0] = DIR_SEP; slash = pos; } if (!directory_exists(dir)) { if (mkdir(dir, 7 * 64 + 5 * 8 + 5)) { printf("Could not create folder [%s]\n", dir); return 0; } } return 1; }