//doUpdate adds remote node to searchlist and lookuptable with datfile specified in url.
//if stamp is in range of defaultUpdateRange adds to updateque.
func doUpdate(w http.ResponseWriter, r *http.Request) {
	s, err := new(w, r)
	if err != nil {
		log.Println(err)
		log.Println("failed to create cgi struct")
		return
	}
	reg := regexp.MustCompile(`^update/(\w+)/(\d+)/(\w+)/([^\+]*)(\+.*)`)
	m := reg.FindStringSubmatch(s.Path())
	if m == nil {
		log.Println("illegal url")
		return
	}
	datfile, stamp, id, hostport, path := m[1], m[2], m[3], m[4], m[5]
	host, portstr, err := net.SplitHostPort(hostport)
	if err != nil {
		log.Println(err)
		return
	}
	port, err := strconv.Atoi(portstr)
	if err != nil {
		log.Println(err)
		return
	}
	host = s.remoteIP(host)
	if host == "" {
		log.Println("host is null")
		return
	}

	n, err := node.MakeNode(host, path, port)
	if err != nil || !n.IsAllowed() {
		log.Println("detects spam")
		return
	}
	manager.AppendToTable(datfile, n)
	nstamp, err := strconv.ParseInt(stamp, 10, 64)
	if err != nil {
		log.Println(err)
		return
	}

	if !recentlist.IsInUpdateRange(nstamp) {
		return
	}
	rec := record.New(datfile, id, nstamp)
	go updateque.UpdateNodes(rec, n)
	fmt.Fprintln(w, "OK")
}
//postComment creates a record from args and adds it to thread.Cache.
//also adds tag if not tag!=""
func (m *mchCGI) postComment(threadKey, name, mail, body, passwd, tag string) error {
	stamp := time.Now().Unix()
	recbody := make(map[string]string)
	recbody["body"] = html.EscapeString(body)
	recbody["name"] = html.EscapeString(name)
	recbody["mail"] = html.EscapeString(mail)

	c := thread.NewCache(threadKey)
	rec := record.New(c.Datfile, "", 0)
	rec.Build(stamp, recbody, passwd)
	if rec.IsSpam() {
		return errSpamM
	}
	rec.Sync()
	if tag != "" {
		user.Set(c.Datfile, []string{tag})
	}
	go updateque.UpdateNodes(rec, nil)
	return nil
}
//doPost parses multipart form ,makes record of it and adds to cache.
//if form dopost=yes broadcasts it.
func (t *threadCGI) doPost() string {
	attached, attachedErr := t.parseAttached()
	if attachedErr != nil {
		log.Println(attachedErr)
	}
	suffix := t.guessSuffix(attached)
	ca := thread.NewCache(t.Req.FormValue("file"))
	rec, err := t.makeRecord(attached, suffix, ca)
	if err != nil {
		return ""
	}
	proxyClient := t.Req.Header.Get("X_FORWARDED_FOR")
	log.Printf("post %s/%d_%s from %s/%s\n", ca.Datfile, ca.Stamp(), rec.ID, t.Req.RemoteAddr, proxyClient)

	if len(rec.Recstr()) > cfg.RecordLimit<<10 {
		t.Header(t.M["big_file"], "", nil, true)
		t.Footer(nil)
		return ""
	}
	if rec.IsSpam() {
		t.Header(t.M["spam"], "", nil, true)
		t.Footer(nil)
		return ""
	}

	if ca.Exists() {
		rec.Sync()
	} else {
		t.Print404(nil, "")
		return ""
	}

	if t.Req.FormValue("dopost") != "" {
		log.Println(rec.Datfile, rec.ID, "is queued")
		go updateque.UpdateNodes(rec, nil)
	}

	return rec.ID[:8]

}