libextractor

GNU libextractor
Log | Files | Refs | Submodules | README | LICENSE

extractor_ipc.c (4436B)


      1 /*
      2      This file is part of libextractor.
      3      Copyright (C) 2012 Vidyut Samanta and Christian Grothoff
      4 
      5      libextractor is free software; you can redistribute it and/or modify
      6      it under the terms of the GNU General Public License as published
      7      by the Free Software Foundation; either version 3, or (at your
      8      option) any later version.
      9 
     10      libextractor is distributed in the hope that it will be useful, but
     11      WITHOUT ANY WARRANTY; without even the implied warranty of
     12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13      General Public License for more details.
     14 
     15      You should have received a copy of the GNU General Public License
     16      along with libextractor; see the file COPYING.  If not, write to the
     17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     18      Boston, MA 02110-1301, USA.
     19  */
     20 /**
     21  * @file main/extractor_ipc.c
     22  * @brief IPC with plugin (OS-independent parts)
     23  * @author Christian Grothoff
     24  */
     25 #include "platform.h"
     26 #include "extractor_logging.h"
     27 #include "extractor_ipc.h"
     28 #include "extractor_plugins.h"
     29 
     30 
     31 /**
     32  * Process a reply from channel (seek request, metadata and done message)
     33  *
     34  * @param plugin plugin this communication is about
     35  * @param buf buffer with data from IPC channel
     36  * @param size number of bytes in buffer
     37  * @param proc metadata callback
     38  * @param proc_cls callback cls
     39  * @return number of bytes processed, -1 on error
     40  */
     41 ssize_t
     42 EXTRACTOR_IPC_process_reply_ (struct EXTRACTOR_PluginList *plugin,
     43                               const void *data,
     44                               size_t size,
     45                               EXTRACTOR_ChannelMessageProcessor proc,
     46                               void *proc_cls)
     47 {
     48   const char *cdata;
     49   unsigned char code;
     50   struct SeekRequestMessage seek;
     51   struct MetaMessage meta;
     52   const char *mime_type;
     53   const char *value;
     54   ssize_t ret;
     55 
     56   ret = 0;
     57   while (size > 0)
     58   {
     59     cdata = data;
     60     code = (unsigned char) cdata[0];
     61     switch (code)
     62     {
     63     case MESSAGE_DONE: /* Done */
     64       plugin->seek_request = -1;
     65       plugin->round_finished = 1;
     66       ret++;
     67       size--;
     68       data++;
     69       continue;
     70     case MESSAGE_ALIVE: /* still busy; receiving it was the point */
     71       ret++;
     72       size--;
     73       data++;
     74       continue;
     75     case MESSAGE_SEEK: /* Seek */
     76       if (size < sizeof (struct SeekRequestMessage))
     77       {
     78         plugin->seek_request = -1;
     79         return ret;
     80       }
     81       memcpy (&seek, cdata, sizeof (seek));
     82       plugin->seek_request = (int64_t) seek.file_offset;
     83       plugin->seek_whence = seek.whence;
     84       ret += sizeof (struct SeekRequestMessage);
     85       data += sizeof (struct SeekRequestMessage);
     86       size -= sizeof (struct SeekRequestMessage);
     87       continue;
     88     case MESSAGE_META: /* Meta */
     89       if (size < sizeof (struct MetaMessage))
     90       {
     91         plugin->seek_request = -1;
     92         return ret;
     93       }
     94       memcpy (&meta, cdata, sizeof (meta));
     95       /* check hdr for sanity */
     96       if (meta.value_size > MAX_META_DATA)
     97       {
     98         LOG ("Meta data exceeds size limit\n");
     99         return -1; /* not allowing more than MAX_META_DATA meta data */
    100       }
    101       if (size < sizeof (meta) + meta.mime_length + meta.value_size)
    102       {
    103         plugin->seek_request = -1;
    104         return ret;
    105       }
    106       if (0 == meta.mime_length)
    107       {
    108         mime_type = NULL;
    109       }
    110       else
    111       {
    112         mime_type = &cdata[sizeof (struct MetaMessage)];
    113         if ('\0' != mime_type[meta.mime_length - 1])
    114         {
    115           LOG ("Mime type not 0-terminated\n");
    116           return -1;
    117         }
    118       }
    119       if (0 == meta.value_size)
    120         value = NULL;
    121       else
    122         value = &cdata[sizeof (struct MetaMessage) + meta.mime_length];
    123       if (meta.meta_type >= EXTRACTOR_metatype_get_max ())
    124         meta.meta_type = EXTRACTOR_METATYPE_UNKNOWN;
    125       proc (proc_cls,
    126             plugin,
    127             (enum EXTRACTOR_MetaType) meta.meta_type,
    128             (enum EXTRACTOR_MetaFormat) meta.meta_format,
    129             mime_type, value, meta.value_size);
    130       ret += sizeof (struct MetaMessage) + meta.mime_length + meta.value_size;
    131       size -= sizeof (struct MetaMessage) + meta.mime_length + meta.value_size;
    132       data += sizeof (struct MetaMessage) + meta.mime_length + meta.value_size;
    133       continue;
    134     default:
    135       LOG ("Invalid message type %d\n", (int) code);
    136       return -1;
    137     }
    138   }
    139   return ret;
    140 }
    141 
    142 
    143 /* end of extractor_ipc.c */