Пример #1
0
int cbparse_entry_devtype(void *pArg, const char *p) {
  int rc = 0;
  PARSE_ENTRY_DATA_T *pEntryData = (PARSE_ENTRY_DATA_T *) pArg;

  //fprintf(stderr, "entry '%s'\n", p);

  if(!strncasecmp(p, DEVFILE_KEY_DEVICE, strlen(DEVFILE_KEY_DEVICE))) {

    if((p = strutil_skip_key(p, strlen(DEVFILE_KEY_DEVICE)))) {
      p = avc_dequote(p, NULL, 0);
      strncpy(pEntryData->devname, p, sizeof(pEntryData->devname) - 1);
      pEntryData->flags |= PARSE_FLAG_HAVE_DEVNAME; 
    }

  } else if(!strncasecmp(p, DEVFILE_KEY_METHODS, strlen(DEVFILE_KEY_METHODS))) {

    if((p = strutil_skip_key(p, strlen(DEVFILE_KEY_METHODS)))) {
      p = avc_dequote(p, NULL, 0);

      if(strutil_parse_csv(cbparse_entry_devtype_method, pEntryData, p) < 0) {
        LOG(X_WARNING("Failed to parse device type method(s) '%s'"), p);
      }
      //fprintf(stderr, "%s %d %d %d %d\n", pEntryData->devname, pEntryData->methods[0], pEntryData->methods[1], pEntryData->methods[2], pEntryData->methods[3]);

      pEntryData->flags |= PARSE_FLAG_HAVE_METHOD; 
    }

  } else if(!strncasecmp(p, DEVFILE_KEY_METHOD, strlen(DEVFILE_KEY_METHOD))) {

    if((p = strutil_skip_key(p, strlen(DEVFILE_KEY_METHOD)))) {
      p = avc_dequote(p, NULL, 0);

      pEntryData->methods[0] = devtype_methodfromstr(p);
      pEntryData->flags |= PARSE_FLAG_HAVE_METHOD; 
    }

  } else if(!strncasecmp(p, DEVFILE_KEY_TYPE, strlen(DEVFILE_KEY_TYPE))) {

    if((p = strutil_skip_key(p, strlen(DEVFILE_KEY_TYPE)))) {
      p = avc_dequote(p, NULL, 0);
      pEntryData->devtype = devtype_typefromstr(p);
      pEntryData->flags |= PARSE_FLAG_HAVE_DEVTYPE; 
    }

  } else if(!strncasecmp(p, DEVFILE_KEY_MATCH, strlen(DEVFILE_KEY_MATCH))) {

    if((p = strutil_skip_key(p, strlen(DEVFILE_KEY_MATCH)))) {
      p = avc_dequote(p, NULL, 0);
      strncpy(pEntryData->strmatch, p, sizeof(pEntryData->strmatch) - 1);
      pEntryData->flags |= PARSE_FLAG_HAVE_MATCH; 
    }

  }

  return rc;
}
Пример #2
0
int metafile_open(const char *path, 
                  META_FILE_T *pMetaFile, 
                  int readIgnores,
                  int readTitles) {
 
  int rc = 0;
  FILE_HANDLE fp;
  char *p;
  int match = 0;
  PARSE_ENTRY_DATA_T parseData;
  ENTRY_IGNORE_T *pIgnore;
  ENTRY_IGNORE_T *pIgnorePrev = NULL;
  ENTRY_META_DESCRIPTION_T *pDesc;
  ENTRY_META_DESCRIPTION_T *pDescPrev = NULL;
  char buf[1024];

  if(!path || !pMetaFile) {
    return -1;
  }  

  if((fp = fileops_Open(path, O_RDONLY)) == FILEOPS_INVALID_FP) {
    LOG(X_ERROR("Unable to open metafile for reading: %s (ignore list:%d)"), 
        path, readIgnores);
    return -1;
  }

  VSX_DEBUG_METAFILE( LOG(X_DEBUG("META - metafile_open: '%s', readIgnores: %d, readTitles: %d"), 
                      path, readIgnores, readTitles));

  pMetaFile->filestr[0] = '\0';
  pMetaFile->linkstr[0] = '\0';
  pMetaFile->instr[0] = '\0';
  pMetaFile->xcodestr[0] = '\0';
  pMetaFile->userpass[0] = '\0';
  pMetaFile->methodBits = 0;

  memset(&parseData, 0, sizeof(parseData));
  parseData.path = path;

  while(fileops_fgets(buf, sizeof(buf) - 1, fp)) {

    parseData.linenum++;
    p = buf;
    while(*p == ' ' || *p == '\t') {
      p++;
    }

    if(*p == '#' || *p == '\r' || *p == '\n') {
      continue;
    } 

    //
    // Reset the parse context storage
    //
    reset_parsedata_ctxt(&parseData);

    //
    // We allow multiple configuration items on one line, separated by comma
    //
    rc = strutil_parse_csv(cbparse_entry_metafile, &parseData, p);

    if(parseData.flags == 0) {
      continue;
    }

    if(!(readIgnores || readTitles)) {
      handle_parsed_line(&parseData, pMetaFile, path, &match);
    }

    //
    // We're only interested in reading the ignore list
    //
    if(readIgnores && parseData.ignore[0] != '\0') {
      if(!(pIgnore = (ENTRY_IGNORE_T *) avc_calloc(1, sizeof(ENTRY_IGNORE_T)))) {
        rc = -1;
        break;
      }
      strncpy(pIgnore->filename, parseData.ignore, sizeof(pIgnore->filename));

      if(pIgnorePrev) {
        pIgnorePrev->pnext = pIgnore;
      } else {
        pMetaFile->pignoreList = pIgnore;
      }
      pIgnorePrev = pIgnore;
    }

    //
    // We're only interested in reading the resource title name
    //
    if(readTitles && parseData.title[0] != '\0' && parseData.filename[0] != '\0') {

      if(!(pDesc = (ENTRY_META_DESCRIPTION_T *) avc_calloc(1, sizeof(ENTRY_META_DESCRIPTION_T)))) {
        rc = -1;
        break;
      }

      strncpy(pDesc->title, parseData.title, sizeof(pDesc->title));
      strncpy(pDesc->filename, parseData.filename, sizeof(pDesc->filename));
      if(pDescPrev) {
        pDescPrev->pnext = pDesc;
      } else {
        pMetaFile->pDescriptionList = pDesc;
      }
      pDescPrev = pDesc;
    }

  }

  fileops_Close(fp);

  VSX_DEBUG_METAFILE( 
    LOG(X_DEBUG("META - metafile_open done '%s', meta-devicefilter:'%s', meta-profilefilter: '%s' returning rc: %d, "
                "file: '%s', link: '%s', input: '%s', xcode: '%s', digestauth: '%s', methods: '%s', id: '%s'" ), 
                 path, pMetaFile->devicefilterstr, pMetaFile->profilefilterstr, rc, pMetaFile->filestr, 
                 pMetaFile->linkstr, pMetaFile->instr, pMetaFile->xcodestr, pMetaFile->userpass,
                 devtype_dump_methods(pMetaFile->methodBits, buf, sizeof(buf)), pMetaFile->id));

  return rc;
}
Пример #3
0
int metafile_findprofs(const char *path, const char *devname, 
                      char profs[][META_FILE_PROFILESTR_MAX], unsigned int max) {
  int rc = 0;
  FILE_HANDLE fp;
  char *p;
  unsigned int idx = 0;
  PARSE_ENTRY_DATA_T parseData;
  char buf[2048];
  PROFILE_LIST_ALL_T foundProfs;

  if(!path || !profs) {
    return -1;
  }  

  if((fp = fileops_Open(path, O_RDONLY)) == FILEOPS_INVALID_FP) {
    LOG(X_ERROR("Unable to open metafile for reading profiles: %s"), path);
    return -1;
  }

  VSX_DEBUG_METAFILE( LOG(X_DEBUG("META - metafile_findprofs: '%s', devname: '%s'"), path, devname));

  memset(&foundProfs, 0, sizeof(foundProfs));
  memset(&parseData, 0, sizeof(parseData));
  parseData.path = path;

  while(fileops_fgets(buf, sizeof(buf) - 1, fp)) {

    parseData.linenum++;

    p = buf;
    while(*p == ' ' || *p == '\t') {
      p++;
    }

    if(*p == '#') {
      continue;
    } 

    //
    // Reset the parse context storage
    //
    reset_parsedata_ctxt(&parseData);

    strutil_parse_csv(cbparse_entry_metafile, &parseData, p);

    if(parseData.flags == 0) {
      continue;
    }

    check_profs(&parseData, devname, &foundProfs, path);

  }

  fileops_Close(fp);

  rc = 0;
  for(idx = 0; idx < foundProfs.profs_devmatch.count && idx < max; idx++) {
    if(!find_prof(foundProfs.profs_devmatch.profiles[idx], profs, rc)) { 
      strncpy(profs[rc], foundProfs.profs_devmatch.profiles[idx], 
            META_FILE_PROFILESTR_MAX);
//fprintf(stderr, "ADDING DEVMATCH[%d] '%s'\n", rc, profs[rc]);
      rc++;
    }
  }  

  if(foundProfs.profs_devmatch.count == 0 || !foundProfs.profs_devmatch.haveCatchAll) {
    for(idx = 0; idx < foundProfs.profs_nodevmatch.count && idx < max; idx++) {
      if(!find_prof(foundProfs.profs_nodevmatch.profiles[idx], profs, rc)) { 
        strncpy(profs[rc], foundProfs.profs_nodevmatch.profiles[idx], 
                META_FILE_PROFILESTR_MAX);
//fprintf(stderr, "ADDING NODEVMATCH[%d] '%s'\n", rc, profs[rc]);
        rc++;
      }  
    }
  }

  return rc;
}
Пример #4
0
int cbparse_entry_metafile(void *pArg, const char *p) {
  int rc = 0;
  PARSE_ENTRY_DATA_T *pEntryData = (PARSE_ENTRY_DATA_T *) pArg;
  
  if(!strncasecmp(p, METAFILE_KEY_FILE, strlen(METAFILE_KEY_FILE))) {

    store_parse_entry(p, METAFILE_KEY_FILE, &pEntryData->flags, PARSE_FLAG_HAVE_FILENAME,  
               pEntryData->filename, sizeof(pEntryData->filename));
  } else if(!strncasecmp(p, METAFILE_KEY_RTMP_PROXY, strlen(METAFILE_KEY_RTMP_PROXY))) {

    store_parse_entry(p, METAFILE_KEY_RTMP_PROXY, &pEntryData->flags, PARSE_FLAG_HAVE_RTMP_PROXY,  
               pEntryData->rtmpproxy, sizeof(pEntryData->rtmpproxy));

  } else if(!strncasecmp(p, METAFILE_KEY_RTSP_PROXY, strlen(METAFILE_KEY_RTSP_PROXY))) {

    store_parse_entry(p, METAFILE_KEY_RTSP_PROXY, &pEntryData->flags, PARSE_FLAG_HAVE_RTSP_PROXY,  
               pEntryData->rtspproxy, sizeof(pEntryData->rtspproxy));

  } else if(!strncasecmp(p, METAFILE_KEY_HTTP_PROXY, strlen(METAFILE_KEY_HTTP_PROXY))) {

    store_parse_entry(p, METAFILE_KEY_HTTP_PROXY, &pEntryData->flags, PARSE_FLAG_HAVE_HTTP_PROXY,  
               pEntryData->httpproxy, sizeof(pEntryData->httpproxy));

  } else if(!strncasecmp(p, METAFILE_KEY_HTTPLINK, strlen(METAFILE_KEY_HTTPLINK))) {

    store_parse_entry(p, METAFILE_KEY_HTTPLINK, &pEntryData->flags, PARSE_FLAG_HAVE_HTTPLINK,  
               pEntryData->link, sizeof(pEntryData->link));

  } else if(!strncasecmp(p, METAFILE_KEY_INPUT, strlen(METAFILE_KEY_INPUT))) {

    store_parse_entry(p, METAFILE_KEY_INPUT, &pEntryData->flags, PARSE_FLAG_HAVE_INPUT,  
               pEntryData->input, sizeof(pEntryData->input));

  } else if(!strncasecmp(p, METAFILE_KEY_DEVICE, strlen(METAFILE_KEY_DEVICE))) {

    store_parse_entry(p, METAFILE_KEY_DEVICE, &pEntryData->flags, PARSE_FLAG_HAVE_DEVNAME,  
               pEntryData->devname, sizeof(pEntryData->devname));

  } else if(!strncasecmp(p, METAFILE_KEY_PROFILE, strlen(METAFILE_KEY_PROFILE))) {

    store_parse_entry(p, METAFILE_KEY_PROFILE, &pEntryData->flags, PARSE_FLAG_HAVE_PROFILE,  
               pEntryData->profile, sizeof(pEntryData->profile));

  } else if(!strncasecmp(p, METAFILE_KEY_SHARED, strlen(METAFILE_KEY_SHARED))) {

    if((p = store_parse_entry(p, METAFILE_KEY_SHARED, &pEntryData->flags, PARSE_FLAG_HAVE_SHARED, NULL, 0))) {

      if(IS_CONF_VAL_TRUE(p)) {
        pEntryData->shared = BOOL_ENABLED_OVERRIDE;
      } else if(IS_CONF_VAL_FALSE(p)) {
        pEntryData->shared = BOOL_DISABLED_OVERRIDE;
      }
    }

  } else if(!strncasecmp(p, METAFILE_KEY_SECURE, strlen(METAFILE_KEY_SECURE))) {

    if((p = store_parse_entry(p, METAFILE_KEY_SECURE, &pEntryData->flags, PARSE_FLAG_HAVE_SECURE, NULL, 0))) {

      if(IS_CONF_VAL_TRUE(p)) {
        pEntryData->secure = BOOL_ENABLED_OVERRIDE;
      } else if(IS_CONF_VAL_FALSE(p)) {
        pEntryData->secure = BOOL_DISABLED_OVERRIDE;
      }
    }

  } else if(!strncasecmp(p, METAFILE_KEY_XCODEARGS, strlen(METAFILE_KEY_XCODEARGS))) {

    store_parse_entry(p, METAFILE_KEY_XCODEARGS, &pEntryData->flags, PARSE_FLAG_HAVE_XCODEARGS,  
               pEntryData->xcodestr, sizeof(pEntryData->xcodestr));

  } else if(!strncasecmp(p, METAFILE_KEY_DIGESTAUTH, strlen(METAFILE_KEY_DIGESTAUTH))) {

    store_parse_entry(p, METAFILE_KEY_DIGESTAUTH, &pEntryData->flags, PARSE_FLAG_HAVE_DIGESTAUTH,  
               pEntryData->userpass, sizeof(pEntryData->userpass));
    //TODO: verify ascii chars delimited by colon...

  } else if(!strncasecmp(p, METAFILE_KEY_TOKEN, strlen(METAFILE_KEY_TOKEN))) {

    store_parse_entry(p, METAFILE_KEY_TOKEN, &pEntryData->flags, PARSE_FLAG_HAVE_TOKEN,  
               pEntryData->tokenId, sizeof(pEntryData->tokenId));

  } else if(!strncasecmp(p, METAFILE_KEY_METHODS, strlen(METAFILE_KEY_METHODS))) {

    p = store_parse_entry(p, METAFILE_KEY_METHODS, &pEntryData->flags, PARSE_FLAG_HAVE_METHODS, NULL, 0);
    strutil_parse_csv(cbparse_methods_csv, pEntryData, p);

  } else if(!strncasecmp(p, METAFILE_KEY_ID, strlen(METAFILE_KEY_ID))) {

    store_parse_entry(p, METAFILE_KEY_ID, &pEntryData->flags, PARSE_FLAG_HAVE_ID,  
               pEntryData->id, sizeof(pEntryData->id));

  } else if(!strncasecmp(p, METAFILE_KEY_IGNORE, strlen(METAFILE_KEY_IGNORE))) {

    store_parse_entry(p, METAFILE_KEY_IGNORE, &pEntryData->flags, PARSE_FLAG_HAVE_IGNORE,  
               pEntryData->ignore, sizeof(pEntryData->ignore));

  } else if(!strncasecmp(p, METAFILE_KEY_TITLE, strlen(METAFILE_KEY_TITLE))) {

    store_parse_entry(p, METAFILE_KEY_TITLE, &pEntryData->flags, PARSE_FLAG_HAVE_TITLE,  
               pEntryData->title, sizeof(pEntryData->title));

  //
  // 'description' has been deprecated in favor of 'title'
  //
  } else if(!strncasecmp(p, METAFILE_KEY_DESCRIPTION, strlen(METAFILE_KEY_DESCRIPTION))) {

    store_parse_entry(p, METAFILE_KEY_DESCRIPTION, &pEntryData->flags, PARSE_FLAG_HAVE_TITLE,  
               pEntryData->title, sizeof(pEntryData->title));


  } else {

    LOG(X_WARNING("Unhandled metafile parameter '%s' in %s line:%d"), p, pEntryData->path, pEntryData->linenum);

  }

  return rc;
}
Пример #5
0
int rtspsrv_init(STREAM_RTSP_SESSIONS_T *pRtsp) {

  pthread_t ptdMonitor;
  struct sockaddr_storage sa;
  pthread_attr_t attrMonitor;
  RTSP_MONITOR_CTXT_T startCtxt;
  const char *s;

  if(!pRtsp || pRtsp->max <= 0) {
    return -1;
  }

  if(pRtsp->psessions) {
    avc_free((void *) &pRtsp->psessions);
  }

  destroy_rtspgetsessions(pRtsp);

  if(!(pRtsp->psessions = (RTSP_SESSION_T *)
                          avc_calloc(pRtsp->max, sizeof(RTSP_SESSION_T)))) {
    return -1;
  }

  pRtsp->numRtspGetSessions = pRtsp->max * 2;
  if(!(pRtsp->pRtspGetSessionsBuf = (RTSP_HTTP_SESSION_T *)
                          avc_calloc(pRtsp->numRtspGetSessions, sizeof(RTSP_HTTP_SESSION_T)))) {
    avc_free((void *) &pRtsp->psessions);
    pRtsp->numRtspGetSessions = 0;
    return -1;
  }

  pthread_mutex_init(&pRtsp->mtx, NULL);
 
  //
  // If all UDP / RTP sockets are bound to the same port then establish
  // the listener of this port prior to any RTSP interaction because some app
  // gateways may send some UDP polling data to the base port - and returning
  // an ICMP port unreachable would prevent such app gateways from allocating
  // UDP proxy ports
  //
  pRtsp->sockStaticLocalPort = INVALID_SOCKET;
  if(pRtsp->staticLocalPort > 0) {
    memset(&sa, 0, sizeof(sa));
    sa.ss_family = AF_INET;
    ((struct sockaddr_in *) &sa)->sin_addr.s_addr = INADDR_ANY;
    INET_PORT(sa) = htons(pRtsp->staticLocalPort);
    if((pRtsp->sockStaticLocalPort = net_opensocket(SOCK_DGRAM, 0, 0, (struct sockaddr *) &sa)) == INVALID_SOCKET) {
      LOG(X_ERROR("Failed to open RTSP static local RTP port %d"), pRtsp->staticLocalPort);
    } else {
      if(net_setsocknonblock(pRtsp->sockStaticLocalPort, 1) < 0) {
      LOG(X_ERROR("Failed to listen on RTSP static local RTP port %d"), pRtsp->staticLocalPort);
        net_closesocket(&pRtsp->sockStaticLocalPort);
      }
    }
    //if(pRtsp->sockStaticLocalPort != INVALID_SOCKET) {
    //  sain.sin_addr.s_addr = inet_addr("127.0.0.1");
    //  rc = sendto(pRtsp->sockStaticLocalPort, &sain, 1, 0, (struct sockaddr *) &sain, sizeof(sain));
    //  fprintf(stderr, "SENDTO:%d\n", rc);
    //}
  }

  //
  // Parse any CSV of quoted User-Agent matches which should try to force TCP interleaved mode
  //
  pRtsp->rtspForceTcpUAList.count = 0;
  if(pRtsp->rtspForceTcpUAList.str) {
    strutil_parse_csv(cbparse_entry_rtspua, pRtsp, pRtsp->rtspForceTcpUAList.str);
  }

  pRtsp->runMonitor = 2;
  memset(&startCtxt, 0, sizeof(startCtxt));
  startCtxt.pRtsp = pRtsp;
  if((s = logutil_tid_lookup(pthread_self(), 0)) && s[0] != '\0') {
    snprintf(startCtxt.tid_tag, sizeof(startCtxt.tid_tag), "%s-rtspmon", s);
  }
  pthread_attr_init(&attrMonitor);
  pthread_attr_setdetachstate(&attrMonitor, PTHREAD_CREATE_DETACHED);

  if(pthread_create(&ptdMonitor,
                    &attrMonitor,
                    (void *) rtsp_monitor_proc,
                    (void *) &startCtxt) != 0) {
    LOG(X_ERROR("Unable to create RTP monitor thread"));
    pRtsp->runMonitor = 0;
    if(pRtsp->psessions) {
      avc_free((void *) &pRtsp->psessions);
    }
    destroy_rtspgetsessions(pRtsp);
    pthread_mutex_destroy(&pRtsp->mtx);
  }

  while(pRtsp->runMonitor != 1 && pRtsp->runMonitor != -1) {
    usleep(5000);
  }

  return 0;
}
Пример #6
0
int devtype_loadcfg(const char *path) {
  STREAM_DEVICE_T *pdev = NULL;
  STREAM_DEVICE_T *pdevprev = NULL;
  FILE_HANDLE fp;
  char buf[1024];
  const char *p;
  int linenum = 1;
  int count = 0;
  PARSE_ENTRY_DATA_T parseData;

  if(!path) {
    return -1;
  }

  if(g_devtypes) {
    devtype_free(g_devtypes);
    g_devtypes = NULL;
  }

  if((fp = fileops_Open(path, O_RDONLY)) == FILEOPS_INVALID_FP) {
    LOG(X_ERROR("Unable to open metafile for reading: %s"), path);
    return -1;
  }

  while(fileops_fgets(buf, sizeof(buf) - 1, fp)) {

    p = buf;
    while(*p == ' ' || *p == '\t') {
      p++;
    }

    if(*p == '#') {
      continue;
    }

    memset(&parseData, 0, sizeof(parseData));
    if(strutil_parse_csv(cbparse_entry_devtype, &parseData, p) < 0) {
      LOG(X_ERROR("Failed to parse line %d in file %s"), linenum, path);
      devtype_free(g_devtypes);
      break;
    } else if((parseData.flags & PARSE_FLAG_HAVE_ALL)) { 
      if(!(pdev = create_device(parseData.devname, parseData.strmatch,
                           parseData.strmatch2, parseData.methods,
                           parseData.devtype))) {
        LOG(X_ERROR("Failed to create device config from line %d"), linenum);
        devtype_free(g_devtypes);
        break;
      } else if(pdevprev) {
        pdevprev->pnext = pdev;
      } else {
        g_devtypes = pdev;
      }
      pdevprev = pdev;
      count++;

    } else if(strlen(p) > 1) {
      LOG(X_WARNING("Incomplete line %d in file %s"), linenum, path);
    }

    

    linenum++;
  }

  fileops_Close(fp);

  LOG(X_DEBUG("Read %d device profiles from %s"), count, path);

  //devtype_dump(g_devtypes);

  return count;
}