Esempio n. 1
0
static int ipkg_conf_parse_file(ipkg_conf_t *conf, const char *filename,
				pkg_src_list_t *pkg_src_list,
				nv_pair_list_t *tmp_dest_nv_pair_list,
				char **lists_dir)
{
     int err;
     ipkg_option_t * options;
     FILE *file = fopen(filename, "r");
     regex_t valid_line_re, comment_re;
#define regmatch_size 12
     regmatch_t regmatch[regmatch_size];

     if (ipkg_init_options_array(conf, &options)<0)
        return ENOMEM;

     if (file == NULL) {
	  fprintf(stderr, "%s: failed to open %s: %s\n",
		  __FUNCTION__, filename, strerror(errno));
	  free(options);
	  return errno;
     }
     ipkg_message(conf, IPKG_NOTICE, "loading conf file %s\n", filename);

     err = xregcomp(&comment_re, 
		    "^[[:space:]]*(#.*|[[:space:]]*)$",
		    REG_EXTENDED);
     if (err) {
	  free(options);
	  return err;
     }
     err = xregcomp(&valid_line_re, "^[[:space:]]*(\"([^\"]*)\"|([^[:space:]]*))[[:space:]]*(\"([^\"]*)\"|([^[:space:]]*))[[:space:]]*(\"([^\"]*)\"|([^[:space:]]*))([[:space:]]+([^[:space:]]+))?[[:space:]]*$", REG_EXTENDED);
     if (err) {
	  free(options);
	  return err;
     }

     while(1) {
	  int line_num = 0;
	  char *line;
	  char *type, *name, *value, *extra;

	  line = file_read_line_alloc(file);
	  line_num++;
	  if (line == NULL) {
	       break;
	  }

	  str_chomp(line);

	  if (regexec(&comment_re, line, 0, 0, 0) == 0) {
	       goto NEXT_LINE;
	  }

	  if (regexec(&valid_line_re, line, regmatch_size, regmatch, 0) == REG_NOMATCH) {
	       str_chomp(line);
	       fprintf(stderr, "%s:%d: Ignoring invalid line: `%s'\n",
		       filename, line_num, line);
	       goto NEXT_LINE;
	  }

	  /* This has to be so ugly to deal with optional quotation marks */
	  if (regmatch[2].rm_so > 0) {
	       type = strndup(line + regmatch[2].rm_so,
			      regmatch[2].rm_eo - regmatch[2].rm_so);
	  } else {
	       type = strndup(line + regmatch[3].rm_so,
			      regmatch[3].rm_eo - regmatch[3].rm_so);
	  }
	  if (regmatch[5].rm_so > 0) {
	       name = strndup(line + regmatch[5].rm_so,
			      regmatch[5].rm_eo - regmatch[5].rm_so);
	  } else {
	       name = strndup(line + regmatch[6].rm_so,
			      regmatch[6].rm_eo - regmatch[6].rm_so);
	  }
	  if (regmatch[8].rm_so > 0) {
	       value = strndup(line + regmatch[8].rm_so,
			       regmatch[8].rm_eo - regmatch[8].rm_so);
	  } else {
	       value = strndup(line + regmatch[9].rm_so,
			       regmatch[9].rm_eo - regmatch[9].rm_so);
	  }
	  extra = NULL;
	  if (regmatch[11].rm_so > 0) {
	       extra = strndup (line + regmatch[11].rm_so,
				regmatch[11].rm_eo - regmatch[11].rm_so);
	  }

	  /* We use the tmp_dest_nv_pair_list below instead of
	     conf->pkg_dest_list because we might encounter an
	     offline_root option later and that would invalidate the
	     directories we would have computed in
	     pkg_dest_list_init. (We do a similar thing with
	     tmp_src_nv_pair_list for sake of symmetry.) */
	  if (strcmp(type, "option") == 0) {
	       ipkg_conf_set_option(options, name, value);
	  } else if (strcmp(type, "src") == 0) {
	       if (!nv_pair_list_find(pkg_src_list, name)) {
		    pkg_src_list_append (pkg_src_list, name, value, extra, 0);
	       } else {
		    ipkg_message(conf, IPKG_ERROR, "ERROR: duplicate src declaration.  Skipping:\n\t src %s %s\n",
				 name, value);
	       }
	  } else if (strcmp(type, "src/gz") == 0) {
	       if (!nv_pair_list_find(pkg_src_list, name)) {
		    pkg_src_list_append (pkg_src_list, name, value, extra, 1);
	       } else {
		    ipkg_message(conf, IPKG_ERROR, "ERROR: duplicate src declaration.  Skipping:\n\t src %s %s\n",
				 name, value);
	       }
	  } else if (strcmp(type, "dest") == 0) {
	       nv_pair_list_append(tmp_dest_nv_pair_list, name, value);
	  } else if (strcmp(type, "lists_dir") == 0) {
	       *lists_dir = realloc(*lists_dir,strlen(value)+1);
               if (*lists_dir == NULL) {
		    ipkg_message(conf, IPKG_ERROR, "ERROR: Not enough memory\n");
	            free(options);
	            return EINVAL;
               }
               sprintf (*lists_dir,"%s",value);
	  } else if (strcmp(type, "arch") == 0) {
	       ipkg_message(conf, IPKG_INFO, "supported arch %s priority (%s)\n", name, value);
	       if (!value) {
		    ipkg_message(conf, IPKG_NOTICE, "defaulting architecture %s priority to 10\n", name);
		    value = strdup("10");
	       }
	       nv_pair_list_append(&conf->arch_list, strdup(name), strdup(value));
	  } else {
	       fprintf(stderr, "WARNING: Ignoring unknown configuration "
		       "parameter: %s %s %s\n", type, name, value);
	       free(options);
	       return EINVAL;
	  }

	  free(type);
	  free(name);
	  free(value);
	  if (extra)
	       free (extra);

     NEXT_LINE:
	  free(line);
     }

     free(options);
     regfree(&comment_re);
     regfree(&valid_line_re);
     fclose(file);

     return 0;
}
Esempio n. 2
0
static int args_parse(int argc, char *argv[])
{
    int c;
    int option_index = 0;
    int parse_err = 0;
    char *tuple, *targ;

    while (1) {
        c = getopt_long_only(argc, argv, "Ad:f:no:p:t:vV::", long_options,
                             &option_index);
        if (c == -1)
            break;

        switch (c) {
        case 'A':
            opkg_config->query_all = 1;
            break;
        case 'd':
            opkg_config->dest_str = xstrdup(optarg);
            break;
        case 'f':
            opkg_config->conf_file = xstrdup(optarg);
            break;
        case 'o':
            opkg_config->offline_root = xstrdup(optarg);
            break;
        case 't':
            opkg_config->tmp_dir = xstrdup(optarg);
            break;
        case 'v':
            printf("opkg version %s\n", VERSION);
            exit(0);
        case 'V':
            opkg_config->verbosity = INFO;
            if (optarg != NULL)
                opkg_config->verbosity = atoi(optarg);
            break;
        case ARGS_OPT_AUTOREMOVE:
            opkg_config->autoremove = 1;
            break;
        case ARGS_OPT_FORCE_MAINTAINER:
            opkg_config->force_maintainer = 1;
            break;
        case ARGS_OPT_IGNORE_MAINTAINER:
            opkg_config->ignore_maintainer = 1;
            break;
        case ARGS_OPT_FORCE_DEPENDS:
            opkg_config->force_depends = 1;
            break;
        case ARGS_OPT_FORCE_OVERWRITE:
            opkg_config->force_overwrite = 1;
            break;
        case ARGS_OPT_FORCE_DOWNGRADE:
            opkg_config->force_downgrade = 1;
            break;
        case ARGS_OPT_FORCE_REINSTALL:
            opkg_config->force_reinstall = 1;
            break;
        case ARGS_OPT_FORCE_REMOVAL_OF_ESSENTIAL_PACKAGES:
            opkg_config->force_removal_of_essential_packages = 1;
            break;
        case ARGS_OPT_FORCE_REMOVAL_OF_DEPENDENT_PACKAGES:
            opkg_config->force_removal_of_dependent_packages = 1;
            break;
        case ARGS_OPT_FORCE_SPACE:
            opkg_config->force_space = 1;
            break;
        case ARGS_OPT_FORCE_POSTINSTALL:
            opkg_config->force_postinstall = 1;
            break;
        case ARGS_OPT_FORCE_REMOVE:
            opkg_config->force_remove = 1;
            break;
        case ARGS_OPT_PREFER_ARCH_TO_VERSION:
            opkg_config->prefer_arch_to_version = 1;
            break;
        case ARGS_OPT_NODEPS:
            opkg_config->nodeps = 1;
            break;
        case ARGS_OPT_ADD_ARCH:
        case ARGS_OPT_ADD_DEST:
            tuple = xstrdup(optarg);
            if ((targ = strchr(tuple, ':')) != NULL) {
                *targ++ = 0;
                if ((strlen(tuple) > 0) && (strlen(targ) > 0)) {
                    nv_pair_list_append((c == ARGS_OPT_ADD_ARCH) ? &opkg_config->arch_list : &opkg_config->tmp_dest_list,
                                        tuple, targ);
                }
            }
            free(tuple);
            break;
        case ARGS_OPT_ADD_EXCLUDE:
            str_list_append(&opkg_config->exclude_list, optarg);
            break;
        case ARGS_OPT_NOACTION:
            opkg_config->noaction = 1;
            break;
        case ARGS_OPT_DOWNLOAD_ONLY:
            opkg_config->download_only = 1;
            break;
        case ARGS_OPT_CACHE_DIR:
            opkg_config->cache_dir = xstrdup(optarg);
            break;
        case ARGS_OPT_HOST_CACHE_DIR:
            opkg_config->host_cache_dir = 1;
            break;
        case ARGS_OPT_VOLATILE_CACHE:
            opkg_config->volatile_cache = 1;
            break;
        case ARGS_OPT_NO_INSTALL_RECOMMENDS:
            opkg_config->no_install_recommends = 1;
            break;
        case ARGS_OPT_COMBINE:
            opkg_config->combine = 1;
            break;
        case ':':
            parse_err = -1;
            break;
        case '?':
            parse_err = -1;
            break;
        default:
            printf("Confusion: getopt_long returned %d\n", c);
        }
    }

    if (parse_err)
        return parse_err;
    else
        return optind;
}
Esempio n. 3
0
int ipkg_conf_init(ipkg_conf_t *conf, const args_t *args)
{
     int err;
     char *tmp_dir_base;
     nv_pair_list_t tmp_dest_nv_pair_list;
     char * lists_dir =NULL;
     glob_t globbuf;
     char *etc_ipkg_conf_pattern = "/etc/ipkg/*.conf";
     char *pending_dir  =NULL;

     memset(conf, 0, sizeof(ipkg_conf_t));

     pkg_src_list_init(&conf->pkg_src_list);

     nv_pair_list_init(&tmp_dest_nv_pair_list);
     pkg_dest_list_init(&conf->pkg_dest_list);

     nv_pair_list_init(&conf->arch_list);

     conf->restrict_to_default_dest = 0;
     conf->default_dest = NULL;


     if (args->tmp_dir)
	  tmp_dir_base = args->tmp_dir;
     else 
	  tmp_dir_base = getenv("TMPDIR");
     sprintf_alloc(&conf->tmp_dir, "%s/%s",
		   tmp_dir_base ? tmp_dir_base : IPKG_CONF_DEFAULT_TMP_DIR_BASE,
		   IPKG_CONF_TMP_DIR_SUFFIX);
     conf->tmp_dir = mkdtemp(conf->tmp_dir);
     if (conf->tmp_dir == NULL) {
	  fprintf(stderr, "%s: Failed to create temporary directory `%s': %s\n",
		  __FUNCTION__, conf->tmp_dir, strerror(errno));
	  return errno;
     }

     conf->force_depends = 0;
     conf->force_defaults = 0;
     conf->force_overwrite = 0;
     conf->force_downgrade = 0;
     conf->force_reinstall = 0;
     conf->force_space = 0;
     conf->force_removal_of_essential_packages = 0;
     conf->force_removal_of_dependent_packages = 0;
     conf->nodeps = 0;
     conf->verbose_wget = 0;
     conf->ipkg_libdir = NULL;
     conf->offline_root = NULL;
     conf->offline_root_pre_script_cmd = NULL;
     conf->offline_root_post_script_cmd = NULL;
     conf->multiple_providers = 0;
     conf->verbosity = 1;
     conf->noaction = 0;

     conf->http_proxy = NULL;
     conf->ftp_proxy = NULL;
     conf->no_proxy = NULL;
     conf->proxy_user = NULL;
     conf->proxy_passwd = NULL;

     pkg_hash_init("pkg-hash", &conf->pkg_hash, IPKG_CONF_DEFAULT_HASH_LEN);
     hash_table_init("file-hash", &conf->file_hash, IPKG_CONF_DEFAULT_HASH_LEN);
     hash_table_init("obs-file-hash", &conf->obs_file_hash, IPKG_CONF_DEFAULT_HASH_LEN);
     lists_dir=(char *)malloc(1);
     lists_dir[0]='\0';
     if (args->conf_file) {
	  struct stat stat_buf;
	  err = stat(args->conf_file, &stat_buf);
	  if (err == 0)
	       if (ipkg_conf_parse_file(conf, args->conf_file,
				    &conf->pkg_src_list, &tmp_dest_nv_pair_list,&lists_dir)<0) {
                   /* Memory leakage from ipkg_conf_parse-file */
                   return -1;
               }
                   
     }

     /* if (!lists_dir ){*/
     if (strlen(lists_dir)<=1 ){
	     if (args->ipkg_libdir) {
		     lists_dir = realloc(lists_dir,strlen(args->ipkg_libdir)+strlen("/lists")+2);
		     sprintf (lists_dir,"%s/lists",args->ipkg_libdir);
	     }else if (conf->ipkg_libdir) {
		     lists_dir = realloc(lists_dir,strlen(conf->ipkg_libdir)+strlen("/lists")+2);
		     sprintf (lists_dir,"%s/lists",conf->ipkg_libdir);
	     }else{
		     lists_dir = realloc(lists_dir,strlen(IPKG_CONF_LISTS_DIR)+2);
		     sprintf (lists_dir,"%s",IPKG_CONF_LISTS_DIR);
	     }
     }

     if (args->offline_root) {
            char *tmp = malloc(strlen(lists_dir) + strlen(args->offline_root) + 1);
            sprintf_alloc(&tmp, "%s/%s",args->offline_root,lists_dir);
            free(lists_dir);
            lists_dir = tmp;
     }

     pending_dir = malloc(strlen(lists_dir)+strlen("/pending")+5);
     snprintf(pending_dir,strlen(lists_dir)+strlen("/pending") ,"%s%s",lists_dir,"/pending");

     conf->lists_dir = strdup(lists_dir);
     conf->pending_dir = strdup(pending_dir);

     if (args->offline_root) 
	  sprintf_alloc(&etc_ipkg_conf_pattern, "%s/etc/ipkg/*.conf", args->offline_root);
     memset(&globbuf, 0, sizeof(globbuf));
     err = glob(etc_ipkg_conf_pattern, 0, NULL, &globbuf);
     if (!err) {
	  int i;
	  for (i = 0; i < globbuf.gl_pathc; i++) {
	       if (globbuf.gl_pathv[i]) 
		    if ( ipkg_conf_parse_file(conf, globbuf.gl_pathv[i], 
				         &conf->pkg_src_list, &tmp_dest_nv_pair_list,&lists_dir)<0) {
                        /* Memory leakage from ipkg_conf_parse-file */
                        return -1;
	            }
	  }
     }
     globfree(&globbuf);

     /* if no architectures were defined, then default all, noarch, and host architecture */
     if (nv_pair_list_empty(&conf->arch_list)) {
	  nv_pair_list_append(&conf->arch_list, "all", "1");
	  nv_pair_list_append(&conf->arch_list, "noarch", "1");
	  nv_pair_list_append(&conf->arch_list, HOST_CPU_STR, "10");
     }

     /* Even if there is no conf file, we'll need at least one dest. */
     if (tmp_dest_nv_pair_list.head == NULL) {
	  nv_pair_list_append(&tmp_dest_nv_pair_list,
			      IPKG_CONF_DEFAULT_DEST_NAME,
			      IPKG_CONF_DEFAULT_DEST_ROOT_DIR);
     }

     /* After parsing the file, set options from command-line, (so that
	command-line arguments take precedence) */
     /* XXX: CLEANUP: The interaction between args.c and ipkg_conf.c
	really needs to be cleaned up. There is so much duplication
	right now it is ridiculous. Maybe ipkg_conf_t should just save
	a pointer to args_t (which could then not be freed), rather
	than duplicating every field here? */
     if (args->force_depends) {
	  conf->force_depends = 1;
     }
     if (args->force_defaults) {
	  conf->force_defaults = 1;
     }
     if (args->force_overwrite) {
	  conf->force_overwrite = 1;
     }
     if (args->force_downgrade) {
	  conf->force_downgrade = 1;
     }
     if (args->force_reinstall) {
	  conf->force_reinstall = 1;
     }
     if (args->force_removal_of_dependent_packages) {
	  conf->force_removal_of_dependent_packages = 1;
     }
     if (args->force_removal_of_essential_packages) {
	  conf->force_removal_of_essential_packages = 1;
     }
     if (args->nodeps) {
	  conf->nodeps = 1;
     }
     if (args->noaction) {
	  conf->noaction = 1;
     }
     if (args->query_all) {
	  conf->query_all = 1;
     }
     if (args->verbose_wget) {
	  conf->verbose_wget = 1;
     }
     if (args->multiple_providers) {
	  conf->multiple_providers = 1;
     }
     if (args->verbosity != conf->verbosity) {
	  conf->verbosity = args->verbosity;
     } 

     ipkg_conf_override_string(&conf->ipkg_libdir, 
			       args->ipkg_libdir);
     ipkg_conf_override_string(&conf->offline_root, 
			       args->offline_root);
     ipkg_conf_override_string(&conf->offline_root_pre_script_cmd, 
			       args->offline_root_pre_script_cmd);
     ipkg_conf_override_string(&conf->offline_root_post_script_cmd, 
			       args->offline_root_post_script_cmd);

/* Pigi: added a flag to disable the checking of structures if the command does not need to 
         read anything from there.
*/
     if ( !(args->nocheckfordirorfile)){
        /* need to run load the source list before dest list -Jamey */
        if ( !(args->noreadfeedsfile))
           set_and_load_pkg_src_list(conf, &conf->pkg_src_list);
   
        /* Now that we have resolved conf->offline_root, we can commit to
	   the directory names for the dests and load in all the package
	   lists. */
        set_and_load_pkg_dest_list(conf, &tmp_dest_nv_pair_list,lists_dir);
   
        if (args->dest) {
	     err = ipkg_conf_set_default_dest(conf, args->dest);
	     if (err) {
	          return err;
	     }
        }
     }
     nv_pair_list_deinit(&tmp_dest_nv_pair_list);
     free(lists_dir);
     free(pending_dir);

     return 0;
}