Example #1
0
File: ftp.go Project: nieware/goftp
// Connect initializes the connection to the specified ftp server address.
//
// It is generally followed by a call to Login() as most FTP commands require
// an authenticated user.
func Connect(addr string) (*ServerConn, error) {
	conn, err := textproto.Dial("tcp", addr)
	if err != nil {
		return nil, err
	}

	host, _, err := net.SplitHostPort(addr)
	if err != nil {
		conn.Close()
		return nil, err
	}
	c := &ServerConn{
		conn:     conn,
		host:     host,
		features: make(map[string]string),
	}

	_, _, err = c.conn.ReadResponse(StatusReady)
	if err != nil {
		c.Quit()
		return nil, err
	}

	err = c.feat()
	if err != nil {
		c.Quit()
		return nil, err
	}

	return c, nil
}
Example #2
0
// Dial the beanstalkd server at remote address addr.
func Dial(addr string, onConnect func(*Conn)) (*Conn, os.Error) {
	textConn, err := textproto.Dial("tcp", addr)
	if err != nil {
		return nil, err
	}
	return newConn(addr, textConn, onConnect), nil
}
Example #3
0
File: ftp.go Project: darxen/goftp
// Connect initializes the connection to the specified ftp server address.
//
// It is generally followed by a call to Login() as most FTP commands require
// an authenticated user.
func Connect(addr string) (*ServerConn, error) {
	conn, err := textproto.Dial("tcp", addr)
	if err != nil {
		return nil, err
	}

	a := strings.SplitN(addr, ":", 2)
	c := &ServerConn{
		conn:     conn,
		host:     a[0],
		features: make(map[string]string),
	}

	_, _, err = c.conn.ReadResponse(StatusReady)
	if err != nil {
		c.Quit()
		return nil, err
	}

	err = c.feat()
	if err != nil {
		c.Quit()
		return nil, err
	}

	return c, nil
}
Example #4
0
File: ftp.go Project: juster/maw
func DialFtp(addr string) (*FtpConn, os.Error) {
	conn, err := proto.Dial("tcp", addr)
	if err != nil {
		return nil, err
	}
	return &FtpConn{PreLogin, 0, conn}, nil
}
Example #5
0
File: nntp.go Project: hobeone/nntp
// New connects to an NNTP server.
// The network and addr are passed to net.Dial to
// make the connection.
//
// Example:
//   conn, err := nntp.Dial("tcp", "my.news:nntp")
//
func New(network, addr string) (*Conn, error) {
	c, err := textproto.Dial(network, addr)
	if err != nil {
		return nil, err
	}
	return newClient(c)
}
Example #6
0
func (c *Conn) cmd(response, format string, a ...interface{}) *result {
	err := c.textConn.PrintfLine(format, a...)
	for tries := 0; err != nil && tries < retryCount; tries++ {
		c.textConn, err = textproto.Dial("tcp", c.Name)
		if err != nil {
			continue
		}
		if c.onConnect != nil {
			c.onConnect(c)
		}
		err = c.textConn.PrintfLine(format, a...)
	}
	if err != nil {
		return &result{err: err}
	}

	str, err := c.textConn.ReadLine()
	if err != nil {
		return &result{err: err}
	}

	var res result
	res.line = str
	args := strings.Fields(str)
	res.name = args[0]
	res.args = args[1:]
	res.setError(response)
	res.readBody(c.textConn.R)
	return &res
}
Example #7
0
func main() {

	// read log file todo: move in function
	cfgFile, _ := os.Open("bot.json")
	decoder := json.NewDecoder(cfgFile)
	cfg := Configuration{}
	err := decoder.Decode(&cfg)
	if err != nil {
		fmt.Println("ERROR cfg: ", err)
		return
	}
	// end config read

	// Build bot
	bot := new(Bot)
	bot.activeAdmins = make(map[string]bool)
	bot.voted = make(map[string]bool)
	bot.suggestions = make(map[int]Title)
	bot.writeChan = make(chan *IrcMessage)
	bot.config = &cfg
	// connect to the server
	bot.conn, err = textproto.Dial("tcp", cfg.Host+":"+cfg.Port)
	if err != nil {
		fmt.Printf("ERROR: %s\n", err)
		return
	}
	bot.startBot()
}
Example #8
0
// Dial connects to the address with the nickname
// and returns a Conn
func Dial(conf *Configuration) Context {
	initLogger(conf.Verbose)
	conn := &Connection{
		address:  fmt.Sprintf("%s:%d", conf.Hostname, conf.Port),
		nickname: conf.Nickname,

		ch: &Channels{m: make(map[string]*Channel)},
		ev: NewEvents(),

		done: make(chan struct{}),
	}

	log.Debugf("connecting to %s", conn.address)
	tp, err := textproto.Dial("tcp", conn.address)
	if err != nil {
		log.Fatalf(err.Error())
	}

	conn.conn = tp
	if conf.Password != "" {
		conn.Raw("PASS %s", conf.Password)
	}

	conn.Raw("NICK %s", conf.Nickname)
	conn.Raw("USER %s 0 * :%s", conf.Username, conf.Realname)

	log.Debugf("starting readLoop")
	go conn.readLoop()
	return conn
}
Example #9
0
File: conn.go Project: j6n/noye
// Dial uses a provided addr:port and opens a connection, returning any error
func (c *Connection) Dial(addr string) (err error) {
	tp, err := textproto.Dial("tcp", addr)
	if err != nil {
		return err
	}

	c.conn = tp
	return
}
Example #10
0
func (ep *endpoint) connect() error {
	conn, err := textproto.Dial("tcp", fmt.Sprintf("%s:%d", ep.Host, ep.Port))
	if err != nil {
		ep.Error = err
		return err
	}
	ep.Conn = conn
	log.Printf("Connected to endpoint")
	return nil
}
Example #11
0
func buildConnection(addr string, useTls bool) (*textproto.Conn, error) {
	if useTls == true {
		tls, err := tls.Dial("tcp", addr, nil)
		if err != nil {
			return nil, err
		}
		return textproto.NewConn(tls), nil
	} else {
		return textproto.Dial("tcp", addr)
	}
	return nil, errors.New("could not build connection")
}
Example #12
0
func (bot *Bot) Connect() {
	conn, err := textproto.Dial("tcp", bot.server+":"+bot.port)
	if err != nil {
		log.Fatal("unable to connect to IRC server", err)
	}
	bot.conn = conn
	log.Printf("Connected to IRC server %s:%s\n", bot.server, bot.port)

	userCommand := fmt.Sprintf("USER %s 8 * :%s\n", bot.user, bot.user)
	bot.conn.PrintfLine(userCommand)
	bot.conn.PrintfLine("NICK " + bot.nick)
}
Example #13
0
// Dial an APRS-IS service.
func Dial(prot, addr string) (rv *APRSIS, err error) {
	var conn *textproto.Conn
	conn, err = textproto.Dial(prot, addr)
	if err != nil {
		return
	}

	return &APRSIS{conn: conn,
		rawLog:      ioutil.Discard,
		infoHandler: dumbInfoHandler,
	}, nil
}
Example #14
0
File: dict.go Project: 2722/lantern
// Dial returns a new client connected to a dictionary server at
// addr on the given network.
func Dial(network, addr string) (*Client, error) {
	text, err := textproto.Dial(network, addr)
	if err != nil {
		return nil, err
	}
	_, _, err = text.ReadCodeLine(220)
	if err != nil {
		text.Close()
		return nil, err
	}
	return &Client{text: text}, nil
}
Example #15
0
File: nntp.go Project: yansal/nntp
func Dial(network, address string) (*Conn, error) {
	textprotoConn, err := textproto.Dial(network, address)
	if err != nil {
		return nil, err
	}

	conn := Conn{textprotoConn, ""}
	_, message, err := conn.ReadCodeLine(200)
	if err != nil {
		return nil, err
	}
	conn.message = message
	return &conn, nil
}
Example #16
0
// Dial connects to MPD listening on address addr (e.g. "127.0.0.1:6600")
// on network network (e.g. "tcp").
func Dial(network, addr string) (c *Client, err error) {
	text, err := textproto.Dial(network, addr)
	if err != nil {
		return nil, err
	}
	line, err := text.ReadLine()
	if err != nil {
		return nil, err
	}
	if line[0:6] != "OK MPD" {
		return nil, textproto.ProtocolError("no greeting")
	}
	return &Client{text: text}, nil
}
Example #17
0
func NewClient(server, nick string) (c *Client, err error) {
	conn, err := textproto.Dial("tcp", server)
	if err != nil {
		return
	}
	// RFC 2812, 3.1.2
	conn.Cmd("NICK %s", nick)
	// RFC 2812, 3.1.3
	conn.Cmd("USER %s %d %s :%s", "webtoy", 0, "*", "Anonymous Guest")
	c = &Client{
		Conn:  conn,
		lines: make(chan Event, 8),
	}
	go c.ReadLines()
	return c, nil
}
Example #18
0
func (this *Gossip) Connect() error {
	if this.Conn != nil {
		return errors.New("Already connected.")
	}

	c, err := textproto.Dial("tcp", fmt.Sprintf("%s:%d", this.Server, this.Port))
	if err != nil {
		return err
	}
	this.Conn = c

	c.Cmd("NICK %s\r\n", this.Nick)
	c.Cmd("USER %s 8 * :%s", this.Nick, this.Nick)

	return nil
}
Example #19
0
// New connects a client to an NNTP server.
func New(net, addr string) (*Client, error) {
	conn, err := textproto.Dial(net, addr)
	if err != nil {
		return nil, err
	}

	_, msg, err := conn.ReadCodeLine(200)
	if err != nil {
		return nil, err
	}

	return &Client{
		conn:   conn,
		Banner: msg,
	}, nil
}
Example #20
0
// Connect to a ftp server and returns a ServerConn handler.
func Connect(addr string) (*ServerConn, error) {
	conn, err := textproto.Dial("tcp", addr)
	if err != nil {
		return nil, err
	}

	a := strings.SplitN(addr, ":", 2)
	c := &ServerConn{conn, a[0]}

	_, _, err = c.conn.ReadCodeLine(StatusReady)
	if err != nil {
		c.Quit()
		return nil, err
	}

	return c, nil
}
Example #21
0
func Dial(address, password string) (c *Client, err error) {
	c = new(Client)

	if c.conn, err = textproto.Dial(TCP, address); err != nil {
		return
	}

	var version string
	if version, err = c.conn.ReadLine(); err != nil {
		return nil, err
	}

	if version[0:6] != "OK MPD" {
		return nil, textproto.ProtocolError("Handshake Error")
	}

	return
}
Example #22
0
//Dial will establish a connection to a NNTP server.
//It returns the connection and an error, if any
func Dial(address, user, pass string) (*Conn, error) {
	n := new(Conn)
	var err error
	n.Conn, err = textproto.Dial("tcp", address)
	if err != nil {
		return nil, err
	}
	_, _, err = n.ReadCodeLine(20)
	if err != nil {
		n.Close()
		return nil, err
	}
	err = n.authenticate(user, pass)
	if err != nil {
		return nil, err
	}
	return n, nil
}
Example #23
0
File: conn.go Project: hamo/gorobot
func (conn *Connection) Connect() (err error) {
	addr := strings.Join([]string{conn.conf.Server, strconv.Itoa(conn.conf.Port)}, ":")
	if conn.conf.SSL {
		socket, err := tls.Dial("tcp", addr, conn.TLSConfig)
		if err != nil {
			return err
			//FIXME
		}
		conn.Socket = textproto.NewConn(socket)
	} else {
		conn.Socket, err = textproto.Dial("tcp", addr)
		if err != nil {
			return err
			//FIXME
		}
	}

	return nil
}
Example #24
0
// Connect to a ftp server and returns a ServerConn handler.
func Connect(addr string) (*ServerConn, error) {
	if strings.Contains(addr, ":") == false {
		addr = addr + ":21"
	}
	conn, err := textproto.Dial("tcp", addr)
	if err != nil {
		return nil, err
	}

	a := strings.SplitN(addr, ":", 2)
	c := &ServerConn{conn, a[0]}

	// _, _, err = c.conn.ReadCodeLine(StatusReady)
	_, _, err = MyReadCodeLine(c.conn, StatusReady)
	if err != nil {
		c.Quit()
		return nil, err
	}

	return c, nil
}
Example #25
0
func newConn(host string, port uint, password string) (*textproto.Conn, *Version, error) {
	addr := fmt.Sprintf("%s:%d", host, port)
	conn, err := textproto.Dial(network, addr)
	if err != nil {
		return nil, nil, err
	}
	line, err := conn.ReadLine()
	if err != nil {
		return nil, nil, err
	}

	if line[0:6] != "OK MPD" {
		return nil, nil, errors.New("MPD: not OK")
	}
	m := mpdVersionRegexp.FindStringSubmatch(line)
	if m == nil {
		return conn, nil, errors.New("Unknown MPD protocol version")
	}
	mjr, _ := strconv.ParseUint(m[1], 0, 0)
	mnr, _ := strconv.ParseUint(m[2], 0, 0)
	rev, _ := strconv.ParseUint(m[3], 0, 0)
	version := Version{uint(mjr), uint(mnr), uint(rev)}

	if password != "" {
		if err == nil && password != "" {
			id, err := conn.Cmd("password %s", password)
			conn.StartResponse(id)
			defer conn.EndResponse(id)
			line, err := conn.ReadLine()
			if err != nil {
				return nil, nil, err
			}
			if line != "OK" {
				return nil, nil, errors.New(line)
			}
		}
	}

	return conn, &version, nil
}
Example #26
0
func Dial(addr string, ssl bool) (*Conn, error) {
	conn := new(Conn)

	if ssl {
		if baseConn, err := tls.Dial("tcp", addr, nil); err != nil {
			return nil, err
		} else {
			conn.baseConn = textproto.NewConn(baseConn)
		}
	} else {
		if c, err := textproto.Dial("tcp", addr); err != nil {
			return nil, err
		} else {
			conn.baseConn = c
		}
	}

	if _, _, err := conn.baseConn.ReadCodeLine(200); err != nil {
		return nil, err
	}

	return conn, nil
}
Example #27
0
// Fetches articles as specified in the configuration.
func FetchArticles(config map[string]string) {
	network := "tcp"
	server, port := config["server"], config["port"]
	username, passw := config["login"], config["pass"]
	fetchMaximum := atoi(config["fetch-maximum"], 100) // reasonable (?) default
	_, verbose = config["verbose"]

	if server == "" || port == "" {
		log.Fatal("Port or server not given. Config says: server = '%s', port = '%s'\n",
			server, port)
	}

	if username == "" {
		log.Fatal("Username not given.\n")
	}

	addr := config["server"] + ":" + config["port"]

	// connect
	conn1, err := textproto.Dial(network, addr)
	die(err, "Couldn't dial %s (error: %s)", network, err)
	conn := Conn{conn1}

	defer conn.Close()

	// say hello
	code, message, err := conn.ReadCodeLine(HELLO)
	die(err, "Couldn't connect to server. Error %d, message %s.\n", code, message)
	_, err = conn.Cmd("AUTHINFO USER %s", username)
	die(err, "Didn't like AUTHINFO USER (%s)\n", err)

	// authenticate
	code, message, err = conn.ReadCodeLine(PASSWORD_REQUIRED)
	if code != PASSWORD_REQUIRED && code != AUTHEN_ACCEPTED {
		die(err, "unexpected code: %d (%s) (%s)\n", code, message, err)
	}

	if code == PASSWORD_REQUIRED {
		_, err = conn.Cmd("AUTHINFO PASS %s", passw)
		die(err, "Didn't like AUTHINFO PASSW (%s)\n", err)
		code, message, err = conn.ReadCodeLine(AUTHEN_ACCEPTED)
		die(err, "Didn't like AUTHINFO PASSW (%s) (%s)\n", message, err)
	}

	groups := strings.Split(config["groups"], ", ")
	if len(groups) == 0 {
		log.Fatal("No groups given.\n")
	}

	// fetch articles
	for _, g := range groups {
		err = os.Mkdir(g, PERM_MASK) // everyone may read/write this
		if err != nil && !os.IsExist(err) {
			die(err, "Couldn't create directory %s (%s)", g, err.Error())
		}

		// select group; get server's watermark
		_, err = conn.Cmd("GROUP %s", g)
		die(err, "Couldn't choose group %s", g)
		code, message, err = conn.ReadCodeLine(OK)
		die(err, "Couldn't choose group %s", g)

		parts := strings.Split(message, " ")
		if len(parts) != 4 {
			log.Fatal("Expected four parts, but got '%s' with %d parts", message, len(parts))
		}

		number := atoi(parts[0], -1)
		lo, hi := atoi(parts[1], -1), atoi(parts[2], -1)

		if number < 0 || lo < 0 || hi < 0 {
			log.Fatal("Server answered: %d, %d, %d", number, lo, hi)
		}

		watermark := GetWatermark(g)

		// we can't catch up with server anymore because we are
		// too far behind
		if watermark < lo {
			watermark = lo
		}

		// get a list of article numbers
		_, err = conn.Cmd("LISTGROUP %s %d-", g, watermark+1)
		die(err, "Couldn't list group %s", g)
		articles, err := conn.ReadDotLines()
		die(err, "Couldn't list group %s", g)
		articles = articles[1:]

		// get only the last fetchMaximum articles
		if len(articles) > fetchMaximum {
			articles = articles[len(articles)-fetchMaximum:]
		}

		// number of last read article
		lastRead := watermark

		// save articles
		for _, no := range articles {
			err = fetchArticle(conn, g, no)
			lastRead = atoi(no, lastRead)
			if err != nil {
				break
			}
		}

		if len(articles) == 0 {
			lastRead = hi
		} else {
			lastRead = atoi(articles[len(articles)-1], hi)
		}

		if watermark > lastRead {
			lastRead = watermark
		}

		SetWatermark(g, lastRead)
	}

	// is allowed to fail
	conn.Cmd("QUIT")
}
Example #28
0
func Dial(network, addr string) (*Connection, error) {
	c, e := textproto.Dial(network, addr)
	return &Connection{c}, e
}
Example #29
0
// sseClient is a specialized SSE client that connects to a server and
// issues a request for the events handler, then waits for events to be
// returned from the server and puts them in the returned channel. It
// only handles the initial connect event and one subsequent event.
// This client supports HTTP/1.1 on non-TLS sockets.
func sseClient(serverURL string) (chan *serverSentEvent, error) {
	u, err := url.Parse(serverURL)
	if err != nil {
		return nil, err
	}
	if u.Scheme != "http" {
		return nil, errors.New("Unsupported URL scheme")
	}
	ev := make(chan *serverSentEvent, 2)
	tp, err := textproto.Dial("tcp", u.Host)
	if err != nil {
		return nil, err
	}
	tp.Cmd("GET %s HTTP/1.1\r\nHost: %s\r\n", u.Path, u.Host)
	line, err := tp.ReadLine()
	if err != nil {
		tp.Close()
		return nil, err
	}
	if line != "HTTP/1.1 200 OK" {
		tp.Close()
		return nil, errors.New("Unexpected response:" + line)
	}
	m, err := tp.ReadMIMEHeader()
	if err != nil {
		tp.Close()
		return nil, err
	}
	if v := m.Get("Content-Type"); v != "text/event-stream" {
		tp.Close()
		return nil, errors.New("Unexpected Content-Type: " + v)
	}
	if m.Get("Transfer-Encoding") == "chunked" {
		tp.R = bufio.NewReader(httputil.NewChunkedReader(tp.R))
	}
	go func() {
		defer close(ev)
		defer tp.Close()
		m, err = tp.ReadMIMEHeader()
		if err != nil {
			ev <- &serverSentEvent{Error: err}
			return
		}
		ev <- &serverSentEvent{
			Event: m.Get("Event"),
			Data:  m.Get("Data"),
		}
		if m.Get("Event") != "connect" {
			return
		}
		// If the first event is connect, we proceed and ship
		// the next one in line.
		m, err = tp.ReadMIMEHeader()
		if err != nil {
			ev <- &serverSentEvent{Error: err}
			return
		}
		ev <- &serverSentEvent{
			Event: m.Get("Event"),
			Data:  m.Get("Data"),
		}
	}()
	return ev, nil
}
Example #30
0
func main() {
	startTime = time.Now()
	runtime.GOMAXPROCS(4)
	rand.Seed(time.Now().Unix())
	//read in bot config, or initialize default config
	configFile, err := ioutil.ReadFile("config.json")
	if err == nil {
		err = json.Unmarshal(configFile, &config)
		if err != nil {
			log.Fatal("Error unmarshalling config.json")
		}
	} else {
		config = JSONconfig{"chat.freenode.net", 6667, "yaircb", "", "*", false, make([]string, 0), make([]string, 0)}
	}
	fmt.Println(config)

	//set up command detection regular expressions
	regexpCmds = make([]*regexp.Regexp, 3)
	regexpCmds[0] = regexp.MustCompile(`^:(\S*?)!(\S*?)@(\S*?) PRIVMSG (\S*) :` + config.Nick + `\W?\s*(.*)`)
	regexpCmds[1] = regexp.MustCompile(`^:(\S*)?!(\S*)?@(\S*)? PRIVMSG (\S*) :\s*\+(.*)`)
	regexpCmds[2] = regexp.MustCompile(`^:(\S*)?!(\S*)?@(\S*)? PRIVMSG (` + config.Nick + `) :\s*(.*)`)

	//initialize global string->function command map
	funcMap = initMap()
	err = initCmdRedis()
	if err != nil { //if redis init fails, print error
		log.Println(err)
	}

	if err == nil { //only run web server is redis init doesn't fail
		//initialize web server
		initWebRedis()
		http.Handle("/resources/", http.StripPrefix("/resources/", http.FileServer(http.Dir("resources"))))
		http.HandleFunc("/register/", registerHandler)
		http.HandleFunc("/login/", loginHandler)
		http.HandleFunc("/loginCheck/", loginCheckHandler)
		http.HandleFunc("/", indexHandler)
		http.HandleFunc("/save/", saveHandler)
		http.HandleFunc("/user/", userHandler)
		go http.ListenAndServeTLS(":8080", "ssl.crt", "ssl.pem", nil)
	}

	var conns uint16
	writeChan := make(chan string) //used to send strings from readFromConsole to writeToServer
	readChan := make(chan string)  //send strings from readFromServer to writeToConsole
	//wgSrv for goroutines to/from sever, wg for readFromConsole
	var wgSrv, wg sync.WaitGroup
	quitChans := make(chan chan bool, 2)
	error := make(chan bool, 1) //used to indicate readFromConsole exited
	//initiate connection
	wg.Add(2)
	go readFromConsole(writeChan, &wg, error, quitChans) //doesnt get restarted on connection EOF
	wtsQChan := make(chan bool, 1)
	go writeToConsole(readChan, writeChan, &wg, wtsQChan, quitChans) //doesnt get restarted on connection EOF
connectionLoop:
	for ; ; conns++ {
		select {
		case <-error: //if readFromConsole got a "QUIT", exit program
			wtsQChan <- true
			break connectionLoop
		default: //otherwise restart connections
			if conns == 0 {
				log.Println("STARTING...")
			} else {
				log.Println("RESTARTING...")
				log.Println("WAITING 1 MINUTE...")
				time.Sleep(time.Minute)
			}
			var socketRead *bufio.Reader
			var socketWrite *bufio.Writer
			err := errors.New("")
			if config.TLS {
				log.Printf("Connecting to %s:%d with TLS...\n", config.Server, config.Port)
				var sslSocket *tls.Conn
				sslSocket, err = tls.Dial("tcp", fmt.Sprintf("%s:%d", config.Server, config.Port), nil)
				if err == nil {
					sslSocket.SetReadDeadline(time.Time{})
					socketWrite = bufio.NewWriter(sslSocket)
					socketRead = bufio.NewReader(sslSocket)
				} else {
					log.Println("Disabling TLS...")
				}
			}
			if err != nil || !config.TLS { //!config.TLS shouldn't actually be evaluted, as err != nil would be true from err init
				log.Printf("Connecting to %s:%d...\n", config.Server, config.Port)
				socket, err := textproto.Dial("tcp", fmt.Sprintf("%s:%d", config.Server, config.Port))
				if err != nil {
					errOut(err, quitChans)
					return
				}
				socketWrite = socket.Writer.W
				socketRead = socket.Reader.R
			}
			//make writer/reader to/from server
			//send initial IRC messages, NICK and USER
			_, err = socketWrite.WriteString("NICK " + config.Nick + "\r\n")
			if err == nil {
				err = socketWrite.Flush()
			}
			log.Print("NICK " + config.Nick + "\r\n")
			if err != nil {
				errOut(err, quitChans)
			}
			_, err = socketWrite.WriteString("USER " + config.Nick + " " + config.Hostname + " * :yaircb\r\n")
			if err == nil {
				err = socketWrite.Flush()
			}
			log.Print("USER " + config.Nick + " " + config.Hostname + " * :yaircb\r\n")
			if err != nil {
				errOut(err, quitChans)
			}
			wgSrv.Add(1)
			//launch routine to write server output to console
			rfsQChan := make(chan bool, 1)
			quitChans <- rfsQChan
			go readFromServer(socketRead, readChan, &wgSrv, rfsQChan, quitChans)
			//join first channel
			/*err = socket.Writer.PrintfLine("JOIN #ttestt")
			if err != nil {
				errOut(err, quit)
			}*/
			if config.NickServPass != "" {
				_, err = socketWrite.WriteString("PRIVMSG NickServ :IDENTIFY " + config.NickServPass + "\r\n")
				if err == nil {
					err = socketWrite.Flush()
				}
				if err != nil {
					errOut(err, quitChans)
				}
			}
			wgSrv.Add(1)
			//launch routine to send to server and get input from console
			wtsQChan := make(chan bool, 1)
			quitChans <- wtsQChan
			go writeToServer(socketWrite, writeChan, &wgSrv, wtsQChan, quitChans)
			if len(config.Channels) > 0 { //join supplied channels upon connection
				joinMsg := "JOIN "
				for _, channel := range config.Channels {
					joinMsg += channel + ","
				}
				log.Println(joinMsg[:len(joinMsg)-1])
				writeChan <- joinMsg[:len(joinMsg)-1]
			}
			wgSrv.Wait()
		}
	}
	wg.Wait()
}