Exemplo n.º 1
0
void pdb2top(FILE *top_file, char *posre_fn, char *molname,
             t_atoms *atoms, rvec **x, gpp_atomtype_t atype, t_symtab *tab,
             int nrtp, t_restp rtp[],
             t_restp *restp, t_hackblock *hb,
             int nterpairs,t_hackblock **ntdb, t_hackblock **ctdb,
             gmx_bool bAllowMissing,
             gmx_bool bVsites, gmx_bool bVsiteAromatics,
             const char *ff, const char *ffdir,
             real mHmult,
             int nssbonds, t_ssbond *ssbonds,
             real long_bond_dist, real short_bond_dist,
             gmx_bool bDeuterate, gmx_bool bChargeGroups, gmx_bool bCmap,
             gmx_bool bRenumRes,gmx_bool bRTPresname)
{
    /*
  t_hackblock *hb;
  t_restp  *restp;
    */
  t_params plist[F_NRE];
  t_excls  *excls;
  t_nextnb nnb;
  int      *cgnr;
  int      *vsite_type;
  int      i,nmissat;
  int      bts[ebtsNR];
  
  init_plist(plist);

  if (debug) {
    print_resall(debug, atoms->nres, restp, atype);
    dump_hb(debug, atoms->nres, hb);
  }
  
  /* Make bonds */
  at2bonds(&(plist[F_BONDS]), hb, 
           atoms->nr, atoms->atom, atoms->atomname, atoms->nres, *x, 
           long_bond_dist, short_bond_dist, bAllowMissing);
  
  /* specbonds: disulphide bonds & heme-his */
  do_ssbonds(&(plist[F_BONDS]),
	     atoms->nr, atoms->atom, atoms->atomname, nssbonds, ssbonds,
	     bAllowMissing);
  
  nmissat = name2type(atoms, &cgnr, atype, restp);
  if (nmissat) {
    if (bAllowMissing)
      fprintf(stderr,"There were %d missing atoms in molecule %s\n",
	      nmissat,molname);
    else
      gmx_fatal(FARGS,"There were %d missing atoms in molecule %s, if you want to use this incomplete topology anyhow, use the option -missing",
		  nmissat,molname);
  }
  
  /* Cleanup bonds (sort and rm doubles) */ 
  clean_bonds(&(plist[F_BONDS]));
  
  snew(vsite_type,atoms->nr);
  for(i=0; i<atoms->nr; i++)
    vsite_type[i]=NOTSET;
  if (bVsites) {
    /* determine which atoms will be vsites and add dummy masses 
       also renumber atom numbers in plist[0..F_NRE]! */
    do_vsites(nrtp, rtp, atype, atoms, tab, x, plist, 
              &vsite_type, &cgnr, mHmult, bVsiteAromatics, ffdir);
  }
  
  /* Make Angles and Dihedrals */
  fprintf(stderr,"Generating angles, dihedrals and pairs...\n");
  snew(excls,atoms->nr);
  init_nnb(&nnb,atoms->nr,4);
  gen_nnb(&nnb,plist);
  print_nnb(&nnb,"NNB");
  gen_pad(&nnb,atoms,restp[0].nrexcl,restp[0].HH14,
          plist,excls,hb,restp[0].bAlldih,restp[0].bRemoveDih,
          bAllowMissing);
  done_nnb(&nnb);
  
    /* Make CMAP */
    if (TRUE == bCmap)
    {
		gen_cmap(&(plist[F_CMAP]), restp, atoms->nr, atoms->atom, atoms->atomname, atoms->nres);
        if (plist[F_CMAP].nr > 0)
        {
            fprintf(stderr, "There are %4d cmap torsion pairs\n",
                    plist[F_CMAP].nr);
        }
    }

  /* set mass of all remaining hydrogen atoms */
  if (mHmult != 1.0)
    do_h_mass(&(plist[F_BONDS]),vsite_type,atoms,mHmult,bDeuterate);
  sfree(vsite_type);
  
  /* Cleanup bonds (sort and rm doubles) */ 
  /* clean_bonds(&(plist[F_BONDS]));*/
   
  fprintf(stderr,
	  "There are %4d dihedrals, %4d impropers, %4d angles\n"
	  "          %4d pairs,     %4d bonds and  %4d virtual sites\n",
	  plist[F_PDIHS].nr, plist[F_IDIHS].nr, plist[F_ANGLES].nr,
	  plist[F_LJ14].nr, plist[F_BONDS].nr,
	  plist[F_VSITE2].nr +
	  plist[F_VSITE3].nr +
	  plist[F_VSITE3FD].nr +
	  plist[F_VSITE3FAD].nr +
	  plist[F_VSITE3OUT].nr +
      plist[F_VSITE4FD].nr +
      plist[F_VSITE4FDN].nr );
  
  print_sums(atoms, FALSE);
  
  if (FALSE == bChargeGroups)
  {
	  scrub_charge_groups(cgnr, atoms->nr);
  }

    if (bRenumRes)
    {
        for(i=0; i<atoms->nres; i++) 
        {
            atoms->resinfo[i].nr = i + 1;
            atoms->resinfo[i].ic = ' ';
        }
    }
	
  if (top_file) {
    fprintf(stderr,"Writing topology\n");
    /* We can copy the bonded types from the first restp,
     * since the types have to be identical for all residues in one molecule.
     */
    for(i=0; i<ebtsNR; i++) {
        bts[i] = restp[0].rb[i].type;
    }
    write_top(top_file, posre_fn, molname,
              atoms, bRTPresname, 
              bts, plist, excls, atype, cgnr, restp[0].nrexcl);
  }
  
  /* cleaning up */
  free_t_hackblock(atoms->nres, &hb);
  free_t_restp(atoms->nres, &restp);
    
  /* we should clean up hb and restp here, but that is a *L*O*T* of work! */
  sfree(cgnr);
  for (i=0; i<F_NRE; i++)
    sfree(plist[i].param);
  for (i=0; i<atoms->nr; i++)
    sfree(excls[i].e);
  sfree(excls);
}
Exemplo n.º 2
0
int gmx_x2top(int argc, char *argv[])
{
    const char        *desc[] = {
        "[THISMODULE] generates a primitive topology from a coordinate file.",
        "The program assumes all hydrogens are present when defining",
        "the hybridization from the atom name and the number of bonds.",
        "The program can also make an [TT].rtp[tt] entry, which you can then add",
        "to the [TT].rtp[tt] database.[PAR]",
        "When [TT]-param[tt] is set, equilibrium distances and angles",
        "and force constants will be printed in the topology for all",
        "interactions. The equilibrium distances and angles are taken",
        "from the input coordinates, the force constant are set with",
        "command line options.",
        "The force fields somewhat supported currently are:[PAR]",
        "G53a5  GROMOS96 53a5 Forcefield (official distribution)[PAR]",
        "oplsaa OPLS-AA/L all-atom force field (2001 aminoacid dihedrals)[PAR]",
        "The corresponding data files can be found in the library directory",
        "with name [TT]atomname2type.n2t[tt]. Check Chapter 5 of the manual for more",
        "information about file formats. By default, the force field selection",
        "is interactive, but you can use the [TT]-ff[tt] option to specify",
        "one of the short names above on the command line instead. In that",
        "case [THISMODULE] just looks for the corresponding file.[PAR]",
    };
    const char        *bugs[] = {
        "The atom type selection is primitive. Virtually no chemical knowledge is used",
        "Periodic boundary conditions screw up the bonding",
        "No improper dihedrals are generated",
        "The atoms to atomtype translation table is incomplete ([TT]atomname2type.n2t[tt] file in the data directory). Please extend it and send the results back to the GROMACS crew."
    };
    FILE              *fp;
    t_params           plist[F_NRE];
    t_excls           *excls;
    t_atoms           *atoms; /* list with all atoms */
    gpp_atomtype_t     atype;
    t_nextnb           nnb;
    t_nm2type         *nm2t;
    t_mols             mymol;
    int                nnm;
    char               title[STRLEN], forcefield[32], ffdir[STRLEN];
    rvec              *x; /* coordinates? */
    int               *nbonds, *cgnr;
    int                bts[] = { 1, 1, 1, 2 };
    matrix             box;    /* box length matrix */
    int                natoms; /* number of atoms in one molecule  */
    int                nres;   /* number of molecules? */
    int                i, j, k, l, m, ndih;
    int                epbc;
    gmx_bool           bRTP, bTOP, bOPLS;
    t_symtab           symtab;
    real               cutoff, qtot, mtot;
    char               n2t[STRLEN];
    output_env_t       oenv;

    t_filenm           fnm[] = {
        { efSTX, "-f", "conf", ffREAD  },
        { efTOP, "-o", "out",  ffOPTWR },
        { efRTP, "-r", "out",  ffOPTWR }
    };
#define NFILE asize(fnm)
    static real        scale = 1.1, kb = 4e5, kt = 400, kp = 5;
    static t_restp     rtp_header_settings;
    static gmx_bool    bRemoveDihedralIfWithImproper = FALSE;
    static gmx_bool    bGenerateHH14Interactions     = TRUE;
    static gmx_bool    bKeepAllGeneratedDihedrals    = FALSE;
    static int         nrexcl                        = 3;
    static gmx_bool    bParam                        = TRUE, bRound = TRUE;
    static gmx_bool    bPairs                        = TRUE, bPBC = TRUE;
    static gmx_bool    bUsePDBcharge                 = FALSE, bVerbose = FALSE;
    static const char *molnm                         = "ICE";
    static const char *ff                            = "oplsaa";
    t_pargs            pa[]                          = {
        { "-ff",     FALSE, etSTR, {&ff},
          "Force field for your simulation. Type \"select\" for interactive selection." },
        { "-v",      FALSE, etBOOL, {&bVerbose},
          "Generate verbose output in the top file." },
        { "-nexcl", FALSE, etINT,  {&nrexcl},
          "Number of exclusions" },
        { "-H14",    FALSE, etBOOL, {&bGenerateHH14Interactions},
          "Use 3rd neighbour interactions for hydrogen atoms" },
        { "-alldih", FALSE, etBOOL, {&bKeepAllGeneratedDihedrals},
          "Generate all proper dihedrals" },
        { "-remdih", FALSE, etBOOL, {&bRemoveDihedralIfWithImproper},
          "Remove dihedrals on the same bond as an improper" },
        { "-pairs",  FALSE, etBOOL, {&bPairs},
          "Output 1-4 interactions (pairs) in topology file" },
        { "-name",   FALSE, etSTR,  {&molnm},
          "Name of your molecule" },
        { "-pbc",    FALSE, etBOOL, {&bPBC},
          "Use periodic boundary conditions." },
        { "-pdbq",  FALSE, etBOOL, {&bUsePDBcharge},
          "Use the B-factor supplied in a [TT].pdb[tt] file for the atomic charges" },
        { "-param", FALSE, etBOOL, {&bParam},
          "Print parameters in the output" },
        { "-round",  FALSE, etBOOL, {&bRound},
          "Round off measured values" },
        { "-kb",    FALSE, etREAL, {&kb},
          "Bonded force constant (kJ/mol/nm^2)" },
        { "-kt",    FALSE, etREAL, {&kt},
          "Angle force constant (kJ/mol/rad^2)" },
        { "-kp",    FALSE, etREAL, {&kp},
          "Dihedral angle force constant (kJ/mol/rad^2)" }
    };

    if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa,
                           asize(desc), desc, asize(bugs), bugs, &oenv))
    {
        return 0;
    }
    bRTP = opt2bSet("-r", NFILE, fnm);
    bTOP = opt2bSet("-o", NFILE, fnm);
    /* C89 requirements mean that these struct members cannot be used in
     * the declaration of pa. So some temporary variables are needed. */
    rtp_header_settings.bRemoveDihedralIfWithImproper = bRemoveDihedralIfWithImproper;
    rtp_header_settings.bGenerateHH14Interactions     = bGenerateHH14Interactions;
    rtp_header_settings.bKeepAllGeneratedDihedrals    = bKeepAllGeneratedDihedrals;
    rtp_header_settings.nrexcl = nrexcl;

    if (!bRTP && !bTOP)
    {
        gmx_fatal(FARGS, "Specify at least one output file");
    }

    /* Force field selection, interactive or direct */
    choose_ff(strcmp(ff, "select") == 0 ? NULL : ff,
              forcefield, sizeof(forcefield),
              ffdir, sizeof(ffdir));

    bOPLS = (strcmp(forcefield, "oplsaa") == 0);


    mymol.name = strdup(molnm);
    mymol.nr   = 1;

    /* Init parameter lists */
    init_plist(plist);

    /* Read coordinates */
    get_stx_coordnum(opt2fn("-f", NFILE, fnm), &natoms);
    snew(atoms, 1);

    /* make space for all the atoms */
    init_t_atoms(atoms, natoms, TRUE);
    snew(x, natoms);

    read_stx_conf(opt2fn("-f", NFILE, fnm), title, atoms, x, NULL, &epbc, box);

    sprintf(n2t, "%s", ffdir);
    nm2t = rd_nm2type(n2t, &nnm);
    if (nnm == 0)
    {
        gmx_fatal(FARGS, "No or incorrect atomname2type.n2t file found (looking for %s)",
                  n2t);
    }
    else
    {
        printf("There are %d name to type translations in file %s\n", nnm, n2t);
    }
    if (debug)
    {
        dump_nm2type(debug, nnm, nm2t);
    }
    printf("Generating bonds from distances...\n");
    snew(nbonds, atoms->nr);
    mk_bonds(nnm, nm2t, atoms, x, &(plist[F_BONDS]), nbonds, bPBC, box);

    open_symtab(&symtab);
    atype = set_atom_type(&symtab, atoms, &(plist[F_BONDS]), nbonds, nnm, nm2t);

    /* Make Angles and Dihedrals */
    snew(excls, atoms->nr);
    printf("Generating angles and dihedrals from bonds...\n");
    init_nnb(&nnb, atoms->nr, 4);
    gen_nnb(&nnb, plist);
    print_nnb(&nnb, "NNB");
    gen_pad(&nnb, atoms, &rtp_header_settings, plist, excls, NULL, TRUE);
    done_nnb(&nnb);

    if (!bPairs)
    {
        plist[F_LJ14].nr = 0;
    }
    fprintf(stderr,
            "There are %4d %s dihedrals, %4d impropers, %4d angles\n"
            "          %4d pairs,     %4d bonds and  %4d atoms\n",
            plist[F_PDIHS].nr,
            bOPLS ? "Ryckaert-Bellemans" : "proper",
            plist[F_IDIHS].nr, plist[F_ANGLES].nr,
            plist[F_LJ14].nr, plist[F_BONDS].nr, atoms->nr);

    calc_angles_dihs(&plist[F_ANGLES], &plist[F_PDIHS], x, bPBC, box);

    set_force_const(plist, kb, kt, kp, bRound, bParam);

    cgnr = set_cgnr(atoms, bUsePDBcharge, &qtot, &mtot);
    printf("Total charge is %g, total mass is %g\n", qtot, mtot);
    if (bOPLS)
    {
        bts[2] = 3;
        bts[3] = 1;
    }

    if (bTOP)
    {
        fp = ftp2FILE(efTOP, NFILE, fnm, "w");
        print_top_header(fp, ftp2fn(efTOP, NFILE, fnm), TRUE, ffdir, 1.0);

        write_top(fp, NULL, mymol.name, atoms, FALSE, bts, plist, excls, atype,
                  cgnr, rtp_header_settings.nrexcl);
        print_top_mols(fp, mymol.name, ffdir, NULL, 0, NULL, 1, &mymol);

        ffclose(fp);
    }
    if (bRTP)
    {
        print_rtp(ftp2fn(efRTP, NFILE, fnm), "Generated by x2top",
                  atoms, plist, atype, cgnr);
    }

    if (debug)
    {
        dump_hybridization(debug, atoms, nbonds);
    }
    close_symtab(&symtab);
    free(mymol.name);

    printf("\nWARNING: topologies generated by %s can not be trusted at face value.\n",
           ShortProgram());
    printf("         Please verify atomtypes and charges by comparison to other\n");
    printf("         topologies.\n");

    return 0;
}
Exemplo n.º 3
0
int main(int argc, char *argv[])
{
	int c; /* used to parse arguments */
	char *cur_entry; /* Entry we are benchmarking */

	char *distrib = NULL; /* distribution to use. */
	char *mirror_list = D_MIRROR; /* mirror list file */
	char *config_file = D_CONFIG; /* configuration file */
	char *proxy = NULL; /* Proxy server to use */
	char *infile = NULL; /* optional infile */
	char *outfile = D_OUT; /* outfile name */
	char *topfile = NULL;
	char *area = strdup(D_AREA); /* Area to test */
	char *grab_file = D_FILE; /* File to grab */
	char *update_url = D_UPDATE_URL; /* URL to use for updating */
	char *country_list = NULL; /* List of countries to b/m */
	char *section_list = NULL; /* List of section to include */
	FILE *infile_p, *outfile_p;	/* input/output file pointers */
	FILE *config_p; /* config file pointer */
	FILE *mirror_p; /* mirror list pointer */
	FILE *topfile_p;
	int timeout = 15; /* time to benchmark each server */
	/* int toplist = 0; *//* Whether to write toplist. *//* UNUSED */
	int argsCount = 0; /* persistent counter for args */
	char *args[100]; /* persistent args array */
	/* char str[100] = ""; *//* We don't need to put optarg in str */
	char str[4] = "-? "; /* short option string */
	/* int i; *//* UNUSED */
	char *end;
	struct stat buf;
	
	/* Number of servers to test. If negative, test them all. */
	int test_number = -1;		

	/* Server information structures. */
	server_t current;
	server_t *best = NULL;

	/* Parse options... */
	while((c = getopt(argc, argv, "y:a:c:d:e:f:i:m:o:p:s:t:u:w:n:vh")) != -1)
	{
		if (optarg)
		{ /* not set with -h */
			str[1] = c;
			/* args[argsCount] = (char*)malloc(strlen(str)); *//* BAD: it should be malloc(strlen(str)+1) */
			/* strcat(str, optarg); *//* BAD: optarg may be too long */
			args[argsCount] = malloc(strlen(str)+strlen(optarg)+1);
			memset(args[argsCount],0,strlen(str)+strlen(optarg)+1);
			strncpy(args[argsCount],str,strlen(str));
			strncat(args[argsCount],optarg,strlen(optarg));
			argsCount++;
		}
		
		switch(c) {
		 /* Sections to include into apt-source */
		case 'y':
			section_list = optarg;
			break;
		 /* Area to benchmark */
		case 'a':
			free(area); /* allocated by strdup */
			area = optarg;
			break;
		/* Distribution we'll write into apt-sources. */
		case 'd':
			distrib = optarg;
			break;
		/* Configuration file to use */
		case 'c':
			/* printf("Option: %c\n",c);
			printf("Option arg: %s\n", optarg); */
			/* config_file = (char *)malloc(25);
			strcpy(config_file, optarg);
			*/
			config_file = optarg;
			
			printf("Using configuration file: %s\n", config_file);
			break;
		/* Number of servers to benchmark */
		case 'e':
			test_number = strtol(optarg, &end, 10);
			if (!*optarg || end!=optarg+strlen(optarg)) {
				fprintf(stderr, "Error parsing number"
						" of servers to be"
						" benchmarked\n");
				exit(1);
			}
			break;
		/* File, relative to Debian base, to grab from server. */
		case 'f':
			grab_file = optarg;				
			break;
		/* User-specified list of servers to benchmark. */
		case 'i':
			infile = optarg;
			break;
		/* The list of mirrors */
		case 'm':
			mirror_list = optarg;
			break;
		/* The output file we use */
		case 'o':
			outfile = optarg;
			break;
		/* Proxy server we should use */
		case 'p':
			proxy = optarg;
			break;
		/* List of countries to benchmark */
		case 's':
			country_list = optarg;
			break;
		/* Time for which to benchmark each server. */
		case 't':
			timeout = strtol(optarg, &end, 10);
			if (!*optarg || end!=optarg+strlen(optarg)) {
				fprintf(stderr, "Error parsing server"
						" benchmark time"
						" interval\n");
				exit(1);
			}
			break;
		/* The URL we should update ourselves from */					
		case 'u':
			update_url = optarg;
			break;
		/* Should we write a list of the "top" servers? */
		case 'w':
			/* toplist = 1; *//* UNUSED */
			topfile = optarg;
			break;
		/* Number of servers to write in "top" server list */
		case 'n':
			bestnumber = strtol(optarg, &end, 10);
			if (!*optarg || end!=optarg+strlen(optarg)) {
				fprintf(stderr, "Error parsing number"
						" of best servers to"
						" write\n");
				exit(1);
			}
			break;
		case 'v':
			version();
			break;			
		/* Help!! */
		case 'h':
		default:
			usage();			/* display help */
			break;
		}
	}	
	argc -= optind;
	argv += optind;

	/* Simple check for stupidity */
	if ((test_number >= 0) && (bestnumber > test_number))
		bestnumber = test_number;

	best = malloc(sizeof(server_t) * (bestnumber + 1)); 

	if (best == NULL) {
		perror("malloc");
		exit(1);
	}

	/* Zero the "best" structure (just after malloc for readability) */
	memset(best, 0, sizeof(server_t) * (bestnumber + 1));

	/* We require an area and distribution argument if we are not updating */
	if ((argc == 0) && (distrib == NULL))
		usage();

	/* Check for silly combination of country and area arguments */
/*	if ((area != NULL) && (country_list != NULL))
		usage();
*/
	/* Setup default area argument */
/*	if ((area == NULL) && (country_list == NULL))
		area = d_area;
*/
	/* Setup default file argument if none given */
/*	if (grab_file == NULL)
		grab_file = d_file;
*/

	if (strcmp(area, D_AREA) && (country_list != NULL))
		usage();

	/*
	 * if the use does not specify the mirror list file verify if
	 * there is the file and if not download it from main debian
	 * mirror
	 */
	if (strcmp(mirror_list, D_MIRROR) == 0) {
		if (stat(mirror_list, &buf)!= 0) {
			mirror_p = select_mirror(mirror_list, -1);
			if (update(mirror_p, update_url, proxy) != 0) {
				fprintf(stderr, "Failed to download mirror list. Exiting.\n");
				exit(1);
			}
		}
	}

	/* Open mirror file. We pass argc so it can tell if we're updating 
	   or not */
	mirror_p = select_mirror(mirror_list, argc);
	if (mirror_p == NULL) {
		perror("fopen");
		fprintf(stderr, "Error opening mirror file. Exiting.\n");
		exit(1);
	}

	/* the only possible argument now is "update", for updating the 
	   mirrors list */
	if (argc == 1) {
		if (strcmp(argv[0], "update") != 0)
			usage();
/* If necessary, set update_url to default */
		/*	if (update_url == NULL)
			update_url = d_update_url;
		*/
		if (update(mirror_p, update_url, proxy) != 0) {
			fprintf(stderr, "Update failed. Exiting.\n");
			exit(1);
		}
		printf("Update complete. Exiting.\n");
		exit(0);
	}
	
	/* argc should be 0. If not, there's something wrong. */
	if (argc != 0)
		usage();
	                                

	/* We open the infile. Either a temporary file, or a user-specified 
	   one. */
	infile_p = select_infile(infile);
	if (infile_p == NULL) {
		perror("tmpfile");
		fprintf(stderr, "Failed to open infile. Exiting.\n");
		exit(1);
	}

	/* Set up default if user hasn't specified an outfile */
/*	if (outfile == NULL)
		outfile = d_out;
*/
	/* Open the output file... */
	outfile_p = select_outfile(outfile);
	if (outfile_p == NULL) {
		perror("fopen");
		fprintf(stderr, "Error opening output file. Exiting.\n");
		exit(1);
	}

	/* Open the topfile */
	if (topfile) {
		topfile_p = select_outfile(topfile);
		if (topfile_p == NULL) {
			perror("fopen");
			fprintf(stderr, "Error opening topfile. Exiting.\n");
			exit(1);
		}
	}

	/* Open config file */
	config_p = select_config(config_file);
	if (config_p == NULL) {
		perror("fopen");
		fprintf(stderr, "Error opening config file. Exiting.\n");
		exit(1);
	}

	/* Fill temporary file with useful stuff if it's not user-specified. */
	if (infile == NULL) {
/*		if (area != NULL) {
			if (build_area_file(config_p, infile_p, mirror_p, area) != 0) {
				fprintf(stderr, 
				"Error building area file. Exiting.\n");
				exit(1);
			}
		} else {
*/
		if (country_list) {
			if (build_country_file(config_p, infile_p, mirror_p,
			    country_list) != 0) {
				fprintf(stderr,
				"Error building country file. Exiting.\n");
				exit(1);
			}

		} else {
			if (build_area_file(config_p, infile_p, mirror_p, area) != 0) {
				fprintf(stderr, 
						"Error building area file. Exiting.\n");
				exit(1);
			}
		}		
	}
	
	/* Make sure we're at the beginning... */
	rewind(infile_p);

	/* This is the main loop. It'll exit when we've exhausted the URL 
	   list or test_number is 0 */

	while (((cur_entry = next_entry(infile_p)) != NULL) && test_number != 0) {
		if (ferror(infile_p) != 0) {
			fprintf(stderr, "Error while reading input file\n");
			exit(1);
		}

		/* Turn entry into a pretty structure */
		tokenise(&current, cur_entry);

		/* Do the benchmark */
		if (benchmark(&current, proxy, timeout, grab_file) != 0) {
			fprintf(stderr, 
			"Error while performing benchmark. Exiting.\n");
			exit(1);
		}

		decide_best(&current, best);
		free(cur_entry);

		if (test_number > 0)
			--test_number;
	}

	/* write the results */
        printf("Writing new sources.list file: %s \n", outfile);
	/*
	 * sc
	 */
/*	if (write_list(outfile_p, best, distrib) != 0) { */
	if (write_list(outfile_p, best, distrib, section_list, args, argsCount) != 0) {
	fprintf(stderr, "Error writing output file. Exiting.");
		exit(1);
	}
	/* close the file */
	fclose(outfile_p);

	/* We write out the top servers to a file if asked. Note there's no 
	   point in freeing the "best" structures. */
	if (topfile) {
	        printf("writing topfile: %s\n", topfile);

		if (write_top(infile_p, topfile_p, best) != 0) {
			fprintf(stderr, 
			"Error writing top servers list. Exiting.");
			exit(1);
		}
		/* close the file */
		fclose(topfile_p);
	}
	/* We're all done */
	/* free(best); */
	/* See above: 'there's no point in freeing the "best" structures' */
	/* Bis repetita placent */

	exit(0);
}