示例#1
0
void getfield(std::ifstream &infile, std::map <std::string, std::string> &var)
{
    std::string line, vname, value;
    while (getline(infile, line))
    {
        if (line.empty()) continue;
        trimline(line);
        if (line[0] == '#' || line[0] == '!' || line[0] == '/' || line[0] == '%') continue;
        std::istringstream sline(line);
        getline(sline, vname, '=');
        getline(sline, value, '=');
        trimline(vname);
        trimline(value);
        var[vname] = value.c_str();
    }
}
示例#2
0
文件: setup.c 项目: cammill/cammill
void SetupLoad (void) {
	char cfgfile[PATH_MAX];
	char line2[2048];
	FILE *cfg_fp;
	int n = 0;
	for (n = 0; n < G_LAST; n++) {
		ExpanderStat[n] = 0;
	}
	char homedir[PATH_MAX];
	get_home_dir(homedir);
	setlocale(LC_NUMERIC, "C");
	snprintf(cfgfile, PATH_MAX, "%s%s.cammill.cfg", homedir, DIR_SEP);
	cfg_fp = fopen(cfgfile, "r");
	if (cfg_fp == NULL) {
//		fprintf(stderr, "Can not read Setup: %s\n", cfgfile);
	} else {
		char *line = NULL;
		size_t len = 0;
		ssize_t read;
		while ((read = getline(&line, &len, cfg_fp)) != -1) {
			trimline(line2, 1024, line);
			if (strncmp(line2, "GUI|PANED|Position", 18) == 0) {
				PannedStat = atoi(strstr(line2, "=") + 1);
			} else if (strncmp(line2, "GUI|EXPANDER|", 13) == 0) {
				int gn = 0;
				for (gn = 0; gn < G_LAST; gn++) {
					if (strncmp(line2 + 13, GROUPS[gn].name, strlen(GROUPS[gn].name)) == 0) {
						ExpanderStat[gn] = atoi(strstr(line2, "=") + 1);
					}
				}
			} else {
				for (n = 0; n < P_LAST; n++) {
					char name_str[1024];
					if (strcmp(PARAMETER[n].group, "Objects") != 0) {
						snprintf(name_str, sizeof(name_str), "%s|%s=", PARAMETER[n].group, PARAMETER[n].name);
						if (strncmp(line2, name_str, strlen(name_str)) == 0) {
							if (PARAMETER[n].type == T_FLOAT) {
								PARAMETER[n].vfloat = atof(line2 + strlen(name_str));
							} else if (PARAMETER[n].type == T_DOUBLE) {
								PARAMETER[n].vdouble = atof(line2 + strlen(name_str));
							} else if (PARAMETER[n].type == T_INT) {
								PARAMETER[n].vint = atoi(line2 + strlen(name_str));
							} else if (PARAMETER[n].type == T_SELECT) {
								PARAMETER[n].vint = atoi(line2 + strlen(name_str));
							} else if (PARAMETER[n].type == T_BOOL) {
								PARAMETER[n].vint = atoi(line2 + strlen(name_str));
							} else if (PARAMETER[n].type == T_STRING) {
								strncpy(PARAMETER[n].vstr, line2 + strlen(name_str), sizeof(PARAMETER[n].vstr));
							} else if (PARAMETER[n].type == T_FILE) {
								strncpy(PARAMETER[n].vstr, line2 + strlen(name_str), sizeof(PARAMETER[n].vstr));
							}
						}
					}
				}
			}
		}
		fclose(cfg_fp);
	}
}
main()
{
    int len;
    char line[MAXLINE];

    while ((len = trimline(line, MAXLINE)) > 0)
        if (len > 0)        /* \n lines will have a length of 1 */
            printf("Trimmed: %s\n", line);
}
示例#4
0
文件: setup.c 项目: cammill/cammill
void SetupLoadFromGcodeObjects (char *cfgfile) {
	char line2[2048];
	FILE *cfg_fp;
	int n = 0;
	setlocale(LC_NUMERIC, "C");
	cfg_fp = fopen(cfgfile, "r");
	if (cfg_fp == NULL) {
		fprintf(stderr, "Can not read Setup: %s\n", cfgfile);
	} else {
		char *line = NULL;
		size_t len = 0;
		ssize_t read;
		while ((read = getline(&line, &len, cfg_fp)) != -1) {
			trimline(line2, 1024, line);
			if (line2[0] != '(') {
				continue;
			}
			line2[strlen(line2) - 1] = 0;

			if (strncmp(line2, "(cfg:object-", 12) == 0) {
				n = atoi(line2 + 12);
				char *p = strstr(line2 + 12, ":");
				if (strstr(line2, "-use:") > 0) {
					myOBJECTS[n].use = atoi(p + 2);
				} else if (strstr(line2, "-closed:") > 0) {
					myOBJECTS[n].closed = atoi(p + 2);
//				} else if (strstr(line2, "-force:") > 0) {
//					myOBJECTS[n].force = atoi(p + 2);
//				} else if (strstr(line2, "-order:") > 0) {
//					myOBJECTS[n].order = atoi(p + 2);
//				} else if (strstr(line2, "-climb:") > 0) {
//					myOBJECTS[n].climb = atoi(p + 2);
//				} else if (strstr(line2, "-offset:") > 0) {
//					myOBJECTS[n].offset = atoi(p + 2);
//				} else if (strstr(line2, "-overcut:") > 0) {
//					myOBJECTS[n].overcut = atoi(p + 2);
//				} else if (strstr(line2, "-pocket:") > 0) {
//					myOBJECTS[n].pocket = atoi(p + 2);
//				} else if (strstr(line2, "-helix:") > 0) {
//					myOBJECTS[n].helix = atoi(p + 2);
//				} else if (strstr(line2, "-roughfine:") > 0) {
//					myOBJECTS[n].roughfine = atoi(p + 2);
//				} else if (strstr(line2, "-roughoff:") > 0) {
//					myOBJECTS[n].roughoff = atof(p + 2);
//				} else if (strstr(line2, "-laser:") > 0) {
//					myOBJECTS[n].laser = atoi(p + 2);
//				} else if (strstr(line2, "-tabs:") > 0) {
//					myOBJECTS[n].tabs = atoi(p + 2);
//				} else if (strstr(line2, "-depth:") > 0) {
//					myOBJECTS[n].PARAMETER[P_M_DEPTH].vdouble = atof(p + 2);
				}
			}
		}
		fclose(cfg_fp);
	}
}
示例#5
0
文件: setup.c 项目: cammill/cammill
void SetupLoadFromGcode (char *cfgfile) {
	char line2[2048];
	FILE *cfg_fp;
	int n = 0;
	setlocale(LC_NUMERIC, "C");
	cfg_fp = fopen(cfgfile, "r");
	if (cfg_fp == NULL) {
		fprintf(stderr, "Can not read Setup: %s\n", cfgfile);
	} else {
		char *line = NULL;
		size_t len = 0;
		ssize_t read;
		while ((read = getline(&line, &len, cfg_fp)) != -1) {
			trimline(line2, 1024, line);
			if (line2[0] != '(') {
				continue;
			}
			line2[strlen(line2) - 1] = 0;
			if (strncmp(line2, "(cfg:object-", 12) == 0) {
			} else {
				for (n = 0; n < P_LAST; n++) {
					char name_str[1024];
					if (strcmp(PARAMETER[n].group, "Objects") != 0) {
						snprintf(name_str, sizeof(name_str), "(cfg:%s-%s: ", PARAMETER[n].group, PARAMETER[n].name);
						if (strncmp(line2, name_str, strlen(name_str)) == 0) {
							if (PARAMETER[n].type == T_FLOAT) {
								PARAMETER[n].vfloat = atof(line2 + strlen(name_str));
							} else if (PARAMETER[n].type == T_DOUBLE) {
								PARAMETER[n].vdouble = atof(line2 + strlen(name_str));
							} else if (PARAMETER[n].type == T_INT) {
								PARAMETER[n].vint = atoi(line2 + strlen(name_str));
							} else if (PARAMETER[n].type == T_SELECT) {
								PARAMETER[n].vint = atoi(line2 + strlen(name_str));
							} else if (PARAMETER[n].type == T_BOOL) {
								PARAMETER[n].vint = atoi(line2 + strlen(name_str));
							} else if (PARAMETER[n].type == T_STRING) {
								strncpy(PARAMETER[n].vstr, line2 + strlen(name_str), sizeof(PARAMETER[n].vstr));
							} else if (PARAMETER[n].type == T_FILE) {
								strncpy(PARAMETER[n].vstr, line2 + strlen(name_str), sizeof(PARAMETER[n].vstr));
							}
						}
					}
				}
			}
		}
		fclose(cfg_fp);
	}
}
示例#6
0
void fillstruct(CURL *handle, HeaderStruct *head, struct block *dest)
{
    char *ct = NULL;
    char *ft;
    dest->size = DFOUND;

    if(CURLE_OK == curl_easy_getinfo(curl_handle, CURLINFO_CONTENT_TYPE, &ct) && ct)
    {
        findChr(ct, ';');
        strcpy(dest->type, ct);
    }

    if((ft = strstr(head->filename, "filename=")))
    {
        trimline(ft+9, dest);
    }
    else dest->data = NULL;
}
main()
{
  int initlen,trimlen;     /* current line lengths        */
  int max = 0;             /* maximum length seen so far  */
  char initline[MAXLINE];  /* current input line as typed */
  char revline[MAXLINE];   /* current input line reversed */
  char longline[MAXLINE];  /* longest line saved here     */

  while ((trimlen = initlen = Getline(initline, MAXLINE)) > 0) {
    trimlen = trimline(initline, initlen);
    reverseline(initline, revline, trimlen);
    if (trimlen > max) {
      max = trimlen;
      copyline(longline, revline);
    }

    if (trimlen >= MINPRINT) {
      printf("\n\nThe trimmed & reversed line : \n%s\nwas long enough to print (>= %d characters)\n"
             "specifically %d characters.\n\n", revline, MINPRINT, trimlen);
      if (initlen > MAXLINE)
        printf("Maximum untrimmed line length exceeded (%d charaters), excess "
               "input lost.\n\n", MAXLINE);
    }

    if (trimlen < initlen)
      printf("Initial line trimmed & reversed from %d to %d characters by removal of trailing white space\n\n",initlen,trimlen);

    if (trimlen == 0)
      printf("Line rejected. Nothing other than whitespace characters\n\n");
  }

  if (max > 0) {
    printf("\n\nThe line : \n%s\nwas the longest (%d characters).\n\n", longline, max);
    if (max > MAXLINE) printf("Maximum line length exceeded (%d charaters), excess input lost.\n\n", MAXLINE);
  }
  else printf("\n\nNo input???? So no maxline to print.\n\n");

  return 0;
}
示例#8
0
//
// Must be called holding the ReadLock.
//
void ShibINI::refresh(void)
{
  saml::NDC ndc("refresh");

  // check if we need to refresh
#ifdef _WIN32
  struct _stat stat_buf;
  if (_stat (m_priv->file.c_str(), &stat_buf) < 0)
#else
  struct stat stat_buf;
  if (stat (m_priv->file.c_str(), &stat_buf) < 0)
#endif
    m_priv->log->error("stat failed: %s", m_priv->file.c_str());

#ifdef DEBUG
  m_priv->log->info("refresh: last modtime at %d; file is %d; iters: %d",
		    m_priv->modtime, stat_buf.st_mtime, m_priv->iterators);
#endif

  if (m_priv->modtime >= stat_buf.st_mtime || m_priv->iterators > 0)
    return;

  // Release the read lock -- grab the write lock.  Don't worry if
  // this is non-atomic -- we'll recheck the status.
  m_priv->rwlock->unlock();
  m_priv->rwlock->wrlock();

  // Recheck the modtime
  if (m_priv->modtime >= stat_buf.st_mtime) {
    // Yep, another thread got to it.  We can exit now...  Release
    // the write lock and reaquire the read-lock.

    m_priv->rwlock->unlock();
    m_priv->rwlock->rdlock();
    return;
  }

  // Ok, we've got the write lock.  Let's update our state.

  m_priv->modtime = stat_buf.st_mtime;

  // clear the existing maps
  m_priv->table.clear();

  m_priv->log->info("reading %s", m_priv->file.c_str());
  
  // read the file
  try
  {
    ifstream infile (m_priv->file.c_str());
    if (!infile) {
      m_priv->log->warn("cannot open file: %s", m_priv->file.c_str());
      m_priv->rwlock->unlock();
      m_priv->rwlock->rdlock();
      return;
    }

    const int MAXLEN = 1024;
    char linebuffer[MAXLEN];
    string current_header;
    bool have_header = false;

    while (infile) {
      infile.getline (linebuffer, MAXLEN);
      string line (linebuffer);

      if (line[0] == '#') continue;

      trimline (line);
      if (line.size() <= 1) continue;

      if (line[0] == '[') {
	// this is a header

#ifdef DEBUG
	m_priv->log->info("Found what appears to be a header line");
#endif

	have_header = false;

	// find the end of the header
	int endpos = line.find (']');
	if (endpos == line.npos) {
#ifdef DEBUG
	  m_priv->log->info("Weird: no end found.. punting");
#endif
	  continue; // HUH?  No end?
	}

	// found it
	current_header = line.substr (1, endpos-1);
	trimline (current_header);

	if (!m_priv->cs) to_lowercase (current_header);

	m_priv->table[current_header] = map<string,string>();
	have_header = true;
#ifdef DEBUG
	m_priv->log->info("current header: \"%s\"", current_header.c_str());
#endif

      } else if (have_header) {
	// this is a tag

#ifdef DEBUG
	m_priv->log->info("Found what appears to be a tag line");
#endif

	string tag, setting;
	int mid = line.find ('=');

	if (mid == line.npos) {
#ifdef DEBUG
	  m_priv->log->info("Weird: no '=' found.. punting");
#endif
	  continue; // Can't find the value's setting
	}

	tag = line.substr (0,mid);
	setting = line.substr (mid+1, line.size()-mid);

	trimline (tag);
	trimline (setting);

	if (!m_priv->cs) to_lowercase (tag);

	// If it already exists, log an error and do not save it
	if (m_priv->exists (current_header, tag))
	  m_priv->log->error("Duplicate tag found in section %s: \"%s\"",
			     current_header.c_str(), tag.c_str());
	else
	  (m_priv->table[current_header])[tag] = setting;

#ifdef DEBUG
	m_priv->log->info("new tag: \"%s\" = \"%s\"",
			  tag.c_str(), setting.c_str());
#endif

      }

    } // until the file ends

  } catch (...) {
    // In case there are exceptions.
  }

  // Now release the write lock and reaquire the read lock
  m_priv->rwlock->unlock();
  m_priv->rwlock->rdlock();
}
示例#9
0
void loadInput(Object *obj)
{
	// load the OBJ file here
	char buffer[MAX_BUFFER_SIZE];
	bool has_normal=false, has_texture = false,has_group = false;  
	string matlFileName;
	
	
	while(cin.getline(buffer, MAX_BUFFER_SIZE)!=0)
	{
		stringstream ss(buffer);
		std::string line = ss.str();
		
		// empty line stream
		if(line.empty()){
			continue; //skip blank lines
			//cout<<"this is empty"<<endl;
		}
		trimline(line);
		std::vector < std::string > values = splitline(line, ' ');
		Vector3f v;
		
		//skipping comments
		if(values[0] == "#"){
			continue;
		}
		
		//mtlib file name
		
		else if(values[0] == "mtllib"){
			matlFileName = values[1];
			readMaterial(matlFileName);
			continue;
		}
		
		//groups / objects
		else if(values[0] == "g"){
			has_group = true;
			obj = new Object;
			
			Model.push_back(obj);
			
			obj->obj_name = values[1];
			
			
		}
		//usemtl 
		
		//Reading Vertices
		
		else if(values[0] == "v"){
			//std::cout << "Reading Vertices :" << '\t' << values[1] << '\t'<< values[2]<< '\t' <<
		//values[3]
		//<< std::endl;
			v[0] = std::atof(values[1].c_str());
			v[1] = std::atof(values[2].c_str());
			v[2] = std::atof(values[3].c_str());
			
			if(v[0]<xmin)
				xmin=v[0];
			if(v[0]>xmax)
				xmax=v[0];

			if(v[1]<ymin)
				ymin=v[1];
			if(v[1]>ymax)
				ymax=v[1];

			if(v[2]<zmin)
				zmin=v[2];
			if(v[2]>zmax)
				zmax=v[2];
			//cout << v[0] << endl;
			vecv.push_back(v);
			
			//cout << obj->vecv[0] << endl;
		}
		
		//Reading texture
		else if(values[0] == "vt"){
			
			has_texture = true;
			if(values.size() == 4){
				v[0] = std::atof(values[1].c_str());
				v[1] = std::atof(values[2].c_str());
				v[2] = std::atof(values[3].c_str());
			}
			else if(values.size() == 3){
				v[0] = std::atof(values[1].c_str());
				v[1] = std::atof(values[2].c_str());
				v[2] = 0;
			}
			else{
				v[0] = std::atof(values[1].c_str());
				v[1] = 0;
				v[2] = 0;
			}
			
			
			vec_tex.push_back(v);
			
		}
		
		//Reading Normals
		else if(values[0] == "vn"){
			has_normal = true;
			if(values.size() == 4){
				v[0] = std::atof(values[1].c_str());
				v[1] = std::atof(values[2].c_str());
				v[2] = std::atof(values[3].c_str());
			//	std::cout << "Reading Vertex Normal :" << '\t'<< values[1] << '\t'<< values[2]<< '\t' <<
		//values[3]
		//<< std::endl;
			}
			// for less than two  need to add
			vecn.push_back(v);
		}
		
		//Reading Faces (f v/vt/vn v/vt/vn v/vt/vn v/vt/vn  a/b/c d/e/f g/h/i)
		else if(values[0] == "f"){
			//for triangles 
			if(!has_group){
				obj = new Object;
				Model.push_back(obj);
				obj->obj_name = "group_default";
				has_group = true;
			}
			vector<unsigned> face;
			//with both texture and normal variables
			if(has_normal == true && has_texture == true){
				vector<string> flds1 = splitline(values[1],'/');
				vector<string> flds2 = splitline(values[2],'/');
				vector<string> flds3 = splitline(values[3],'/');
				face.push_back(atoi(flds1[0].c_str()));face.push_back(atoi(flds1[1].c_str()));face.push_back(atoi(flds1[2].c_str()));
				face.push_back(atoi(flds2[0].c_str()));face.push_back(atoi(flds2[1].c_str()));face.push_back(atoi(flds2[2].c_str()));
				face.push_back(atoi(flds3[0].c_str()));face.push_back(atoi(flds3[1].c_str()));face.push_back(atoi(flds3[2].c_str()));
				
				
				obj->vecf.push_back(face);
				//cout << "1st loop" <<endl;
			}
			else if(has_normal == true && has_texture == false){    //b e and h are absent 
				//cout << "2nd loop" <<endl;
				vector<string> flds1 = splitline(values[1],'/');
				vector<string> flds2 = splitline(values[2],'/');
				vector<string> flds3 = splitline(values[3],'/');
				//cout << flds1.size() << endl;
				face.push_back(atoi(flds1[0].c_str()));face.push_back(0);face.push_back(atoi(flds1[1].c_str()));
				face.push_back(atoi(flds2[0].c_str()));face.push_back(0);face.push_back(atoi(flds2[1].c_str()));
				face.push_back(atoi(flds3[0].c_str()));face.push_back(0);face.push_back(atoi(flds3[1].c_str()));
				obj->vecf.push_back(face);
				
			}
			else if(has_normal == false && has_texture == true){    //c f and i are absent
				
				vector<string> flds1 = splitline(values[1],'/');
				vector<string> flds2 = splitline(values[2],'/');
				vector<string> flds3 = splitline(values[3],'/');
				face.push_back(atoi(flds1[0].c_str()));face.push_back(atoi(flds1[1].c_str()));face.push_back(0);
				face.push_back(atoi(flds2[0].c_str()));face.push_back(atoi(flds2[1].c_str()));face.push_back(0);
				face.push_back(atoi(flds3[0].c_str()));face.push_back(atoi(flds3[1].c_str()));face.push_back(0);
				obj->vecf.push_back(face);
				//cout << "3rd loop" <<endl;
			}
			
			else if(has_normal == false && has_texture == false){
				
				std::size_t found = values[1].find_first_of('/');
				if(found != std::string::npos){
					vector<string> flds1 = splitline(values[1],'/');
					vector<string> flds2 = splitline(values[2],'/');
					vector<string> flds3 = splitline(values[3],'/');
					face.push_back(atoi(flds1[0].c_str()));face.push_back(0);face.push_back(0);
					face.push_back(atoi(flds2[0].c_str()));face.push_back(0);face.push_back(0);
					face.push_back(atoi(flds3[0].c_str()));face.push_back(0);face.push_back(0);
					obj->vecf.push_back(face);
				}
				else{
					//cout << values[1] << '\t' << values[2] << '\t' << values[3] << endl;
					
					face.push_back(atoi(values[1].c_str()));face.push_back(atoi("0"));face.push_back(atoi("0"));
					face.push_back(atoi(values[2].c_str()));face.push_back(atoi("0"));face.push_back(atoi("0"));
					face.push_back(atoi(values[3].c_str()));face.push_back(atoi("0"));face.push_back(atoi("0"));
					obj->vecf.push_back(face);
				}
				
			}
			
			
			
			
		} //face loop ends
		
		
		
		
		
		

	}
	for(unsigned int i=0; i< Model.size(); i++){
		if(Model[i]->vecf.size() == 0)
			Model.erase(Model.begin()+i);
	}
	
		
	
	cout<<vecv.size()<<"\t"<<vecn.size() <<"\t"  << vec_tex.size()<<endl;
	cout <<"Model Size \t" << Model.size() << endl;
	//cout << "Model Name \t" << Model[0]->obj_name << endl;
	//cout << "Face Index \t" << Model[0]->vecf[0][3] << Model[0]->vecf[0][4] << Model[0]->vecf[0][5]  << endl;
	cout << "Vecf size\t" << Model[0]->vecf.size() << endl;
}
static void *
replay_thread(void *arg)
{
	struct iovec iov[6];
	char space[1] = " ", crlf[2] = "\r\n";
	struct replay_thread *thr = arg;
	struct message *msg;
	enum shmlogtag tag;
	size_t len;
	char *ptr;
	const char *next;

	int i;

	int reopen = 1;

	while ((msg = mailbox_get(&thr->mbox)) != NULL) {
		tag = msg->tag;
		len = msg->len;
		ptr = msg->ptr;

		thread_log(2, 0, "%s(%s)", VSL_tags[tag], msg->ptr);

		switch (tag) {
		case SLT_RxRequest:
			if (thr->method != NULL)
				thr->bogus = 1;
			else
				thr->method = trimline(thr, ptr);
			break;

		case SLT_RxURL:
			if (thr->url != NULL)
				thr->bogus = 1;
			else
				thr->url = trimline(thr, ptr);
			break;

		case SLT_RxProtocol:
			if (thr->proto != NULL)
				thr->bogus = 1;
			else
				thr->proto = trimline(thr, ptr);
			break;

		case SLT_RxHeader:
			if (thr->nhdr >= sizeof thr->hdr / sizeof *thr->hdr) {
				thr->bogus = 1;
			} else {
				thr->hdr[thr->nhdr++] = trimline(thr, ptr);
				if (isprefix(ptr, "connection:", &next))
					thr->conn = trimline(thr, next);
			}
			break;

		default:
			break;
		}

		freez(msg->ptr);
		freez(msg);

		if (tag != SLT_ReqEnd)
			continue;

		if (!thr->method || !thr->url || !thr->proto) {
			thr->bogus = 1;
		} else if (strcmp(thr->method, "GET") != 0 &&
		    strcmp(thr->method, "HEAD") != 0) {
			thr->bogus = 1;
		} else if (strcmp(thr->proto, "HTTP/1.0") == 0) {
			reopen = !(thr->conn &&
			    strcasecmp(thr->conn, "keep-alive") == 0);
		} else if (strcmp(thr->proto, "HTTP/1.1") == 0) {
			reopen = (thr->conn &&
			    strcasecmp(thr->conn, "close") == 0);
		} else {
			thr->bogus = 1;
		}

		if (thr->bogus) {
			thread_log(1, 0, "bogus");
			goto clear;
		}

		if (thr->sock == -1) {
			for (;;) {
				thread_log(1, 0, "sleeping before connect...");
				usleep(1000 * (thr->fd % 3001));
				if ((thr->sock = VSS_connect(addr_info)) >= 0)
					break;
				thread_log(0, errno, "connect failed");
			}
		}

		thread_log(1, 0, "%s %s %s", thr->method, thr->url, thr->proto);

		iov[0].iov_base = thr->method;
		iov[0].iov_len = strlen(thr->method);
		iov[2].iov_base = thr->url;
		iov[2].iov_len = strlen(thr->url);
		iov[4].iov_base = thr->proto;
		iov[4].iov_len = strlen(thr->proto);
		iov[1].iov_base = iov[3].iov_base = space;
		iov[1].iov_len = iov[3].iov_len = 1;
		iov[5].iov_base = crlf;
		iov[5].iov_len = 2;
		if (writev(thr->sock, iov, 6) == -1) {
			thread_log(0, errno, "writev()");
			goto close;
		}

		for (i = 0; i < thr->nhdr; ++i) {
			thread_log(2, 0, "%d %s", i, thr->hdr[i]);
			iov[0].iov_base = thr->hdr[i];
			iov[0].iov_len = strlen(thr->hdr[i]);
			iov[1].iov_base = crlf;
			iov[1].iov_len = 2;
			if (writev(thr->sock, iov, 2) == -1) {
				thread_log(0, errno, "writev()");
				goto close;
			}
		}
		if (write(thr->sock, crlf, 2) == -1) {
			thread_log(0, errno, "writev()");
			goto close;
		}
		if (receive_response(thr) || reopen) {
close:
			thread_log(1, 0, "close");
			assert(thr->sock != -1);
			close(thr->sock);
			thr->sock = -1;
		}

		sleep(1);
clear:
		/* clean up */
		thread_clear(thr);
	}

	/* leftovers */
	thread_clear(thr);

	return (0);
}