1 /** 2 * \file pathutils.c 3 * 4 * Copyright (C) 2005-2008 Linus Walleij <triad (at) df.lth.se> 5 * Copyright (C) 2006 Chris A. Debenham <chris (at) adebenham.com> 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the 19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 20 * Boston, MA 02111-1307, USA. 21 */ 22 #include "common.h" 23 #include "pathutils.h" 24 #include <stdlib.h> 25 #include <limits.h> 26 #include <string.h> 27 #include <libgen.h> 28 29 /* Find the folder_id of a given path 30 * Runs by walking through folders structure */ 31 static uint32_t 32 lookup_folder_id (LIBMTP_folder_t * folder, char * path, char * parent) 33 { 34 char * current; 35 uint32_t ret = (uint32_t) -1; 36 37 if (strcmp(path,"/")==0) 38 return 0; 39 40 if (folder == NULL) { 41 return ret; 42 } 43 44 current = malloc (strlen(parent) + strlen(folder->name) + 2); 45 sprintf(current,"%s/%s",parent,folder->name); 46 if (strcasecmp (path, current) == 0) { 47 free (current); 48 return folder->folder_id; 49 } 50 if (strncasecmp (path, current, strlen (current)) == 0) { 51 ret = lookup_folder_id (folder->child, path, current); 52 } 53 free (current); 54 if (ret != (uint32_t) (-1)) { 55 return ret; 56 } 57 ret = lookup_folder_id (folder->sibling, path, parent); 58 return ret; 59 } 60 61 /* Parses a string to find item_id */ 62 int 63 parse_path (char * path, LIBMTP_file_t * files, LIBMTP_folder_t * folders) 64 { 65 char *rest; 66 uint32_t item_id; 67 68 // Check if path is an item_id 69 if (*path != '/') { 70 item_id = strtoul(path, &rest, 0); 71 // really should check contents of "rest" here... 72 /* if not number, assume a file name */ 73 if (item_id == 0) { 74 LIBMTP_file_t * file = files; 75 76 /* search for matching name */ 77 while (file != NULL) { 78 if (strcasecmp (file->filename, path) == 0) { 79 return file->item_id; 80 } 81 file = file->next; 82 } 83 } 84 return item_id; 85 } 86 // Check if path is a folder 87 item_id = lookup_folder_id(folders,path,""); 88 if (item_id == (uint32_t) -1) { 89 char * dirc = strdup(path); 90 char * basec = strdup(path); 91 char * parent = dirname(dirc); 92 char * filename = basename(basec); 93 uint32_t parent_id = lookup_folder_id(folders,parent,""); 94 LIBMTP_file_t * file; 95 96 file = files; 97 while (file != NULL) { 98 if (file->parent_id == parent_id) { 99 if (strcasecmp (file->filename, filename) == 0) { 100 free(dirc); 101 free(basec); 102 return file->item_id; 103 } 104 } 105 file = file->next; 106 } 107 free(dirc); 108 free(basec); 109 } else { 110 return item_id; 111 } 112 113 return -1; 114 } 115 116 int progress (const uint64_t sent, const uint64_t total, void const * const data) 117 { 118 int percent = (sent*100)/total; 119 #ifdef __WIN32__ 120 printf("Progress: %I64u of %I64u (%d%%)\r", sent, total, percent); 121 #else 122 printf("Progress: %llu of %llu (%d%%)\r", sent, total, percent); 123 #endif 124 fflush(stdout); 125 return 0; 126 } 127 128 /* Find the file type based on extension */ 129 LIBMTP_filetype_t 130 find_filetype (const char * filename) 131 { 132 char *ptype; 133 LIBMTP_filetype_t filetype; 134 135 #ifdef __WIN32__ 136 ptype = strrchr(filename, '.'); 137 #else 138 ptype = rindex(filename,'.'); 139 #endif 140 // This accounts for the case with a filename without any "." (period). 141 if (!ptype) { 142 ptype = ""; 143 } else { 144 ++ptype; 145 } 146 147 /* This need to be kept constantly updated as new file types arrive. */ 148 if (!strcasecmp (ptype, "wav")) { 149 filetype = LIBMTP_FILETYPE_WAV; 150 } else if (!strcasecmp (ptype, "mp3")) { 151 filetype = LIBMTP_FILETYPE_MP3; 152 } else if (!strcasecmp (ptype, "wma")) { 153 filetype = LIBMTP_FILETYPE_WMA; 154 } else if (!strcasecmp (ptype, "ogg")) { 155 filetype = LIBMTP_FILETYPE_OGG; 156 } else if (!strcasecmp (ptype, "mp4")) { 157 filetype = LIBMTP_FILETYPE_MP4; 158 } else if (!strcasecmp (ptype, "wmv")) { 159 filetype = LIBMTP_FILETYPE_WMV; 160 } else if (!strcasecmp (ptype, "avi")) { 161 filetype = LIBMTP_FILETYPE_AVI; 162 } else if (!strcasecmp (ptype, "mpeg") || !strcasecmp (ptype, "mpg")) { 163 filetype = LIBMTP_FILETYPE_MPEG; 164 } else if (!strcasecmp (ptype, "asf")) { 165 filetype = LIBMTP_FILETYPE_ASF; 166 } else if (!strcasecmp (ptype, "qt") || !strcasecmp (ptype, "mov")) { 167 filetype = LIBMTP_FILETYPE_QT; 168 } else if (!strcasecmp (ptype, "wma")) { 169 filetype = LIBMTP_FILETYPE_WMA; 170 } else if (!strcasecmp (ptype, "jpg") || !strcasecmp (ptype, "jpeg")) { 171 filetype = LIBMTP_FILETYPE_JPEG; 172 } else if (!strcasecmp (ptype, "jfif")) { 173 filetype = LIBMTP_FILETYPE_JFIF; 174 } else if (!strcasecmp (ptype, "tif") || !strcasecmp (ptype, "tiff")) { 175 filetype = LIBMTP_FILETYPE_TIFF; 176 } else if (!strcasecmp (ptype, "bmp")) { 177 filetype = LIBMTP_FILETYPE_BMP; 178 } else if (!strcasecmp (ptype, "gif")) { 179 filetype = LIBMTP_FILETYPE_GIF; 180 } else if (!strcasecmp (ptype, "pic") || !strcasecmp (ptype, "pict")) { 181 filetype = LIBMTP_FILETYPE_PICT; 182 } else if (!strcasecmp (ptype, "png")) { 183 filetype = LIBMTP_FILETYPE_PNG; 184 } else if (!strcasecmp (ptype, "wmf")) { 185 filetype = LIBMTP_FILETYPE_WINDOWSIMAGEFORMAT; 186 } else if (!strcasecmp (ptype, "ics")) { 187 filetype = LIBMTP_FILETYPE_VCALENDAR2; 188 } else if (!strcasecmp (ptype, "exe") || !strcasecmp (ptype, "com") || 189 !strcasecmp (ptype, "bat") || !strcasecmp (ptype, "dll") || 190 !strcasecmp (ptype, "sys")) { 191 filetype = LIBMTP_FILETYPE_WINEXEC; 192 } else if (!strcasecmp (ptype, "aac")) { 193 filetype = LIBMTP_FILETYPE_AAC; 194 } else if (!strcasecmp (ptype, "mp2")) { 195 filetype = LIBMTP_FILETYPE_MP2; 196 } else if (!strcasecmp (ptype, "flac")) { 197 filetype = LIBMTP_FILETYPE_FLAC; 198 } else if (!strcasecmp (ptype, "m4a")) { 199 filetype = LIBMTP_FILETYPE_M4A; 200 } else if (!strcasecmp (ptype, "doc")) { 201 filetype = LIBMTP_FILETYPE_DOC; 202 } else if (!strcasecmp (ptype, "xml")) { 203 filetype = LIBMTP_FILETYPE_XML; 204 } else if (!strcasecmp (ptype, "xls")) { 205 filetype = LIBMTP_FILETYPE_XLS; 206 } else if (!strcasecmp (ptype, "ppt")) { 207 filetype = LIBMTP_FILETYPE_PPT; 208 } else if (!strcasecmp (ptype, "mht")) { 209 filetype = LIBMTP_FILETYPE_MHT; 210 } else if (!strcasecmp (ptype, "jp2")) { 211 filetype = LIBMTP_FILETYPE_JP2; 212 } else if (!strcasecmp (ptype, "jpx")) { 213 filetype = LIBMTP_FILETYPE_JPX; 214 } else if (!strcasecmp (ptype, "bin")) { 215 filetype = LIBMTP_FILETYPE_FIRMWARE; 216 } else if (!strcasecmp (ptype, "vcf")) { 217 filetype = LIBMTP_FILETYPE_VCARD3; 218 } else { 219 /* Tagging as unknown file type */ 220 filetype = LIBMTP_FILETYPE_UNKNOWN; 221 } 222 printf("type: %s, %d\n", ptype, filetype); 223 return filetype; 224 } 225 226 /* Function that compensate for missing libgen.h on Windows */ 227 #ifndef HAVE_LIBGEN_H 228 static char *basename(char *in) { 229 char *p; 230 231 if (in == NULL) 232 return NULL; 233 p = in + strlen(in) - 1; 234 while (*p != '\\' && *p != '/' && *p != ':') 235 { p--; } 236 return ++p; 237 } 238 #endif 239