Home | History | Annotate | Download | only in examples
      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