Commit 871fee96 authored by 黄大凯's avatar 黄大凯
Browse files

Merge branch 'master' of github.com:kaiakz/rsync-os

parents e17951b4 3a25d78d
Loading
Loading
Loading
Loading
+53 −4
Original line number Diff line number Diff line
package fldb

import (
	"bytes"
	"rsync-os/rsync"

	bolt "go.etcd.io/bbolt"
	"google.golang.org/protobuf/proto"
)

// Diff two sorted list
// Return two lists: new files, deleted files
func (cache *Cache) Diff(list *rsync.FileList) (*rsync.FileList, *rsync.FileList) {
func (cache *Cache) Diff(list *rsync.FileList) {

	db, err := bolt.Open("test.db", 0666, nil)
	if err != nil {
		return
	}

	defer db.Close()

	// Iterate cache.module(A) & list(B), both A & B must be sorted lexicographically before

	i := 0
	downloadList := make([]int, 1000)
	deleteList := make([]string, 1000)
	db.View(func(tx *bolt.Tx) error {
		// Assume bucket exists and has keys
		c := tx.Bucket([]byte("MyBucket")).Cursor()

		prefix := []byte(cache.prepath)
		// for k, v := c.Seek(prefix); k != nil && bytes.HasPrefix(k, prefix); k, v = c.Next() {

		// }
		k, v := c.Seek(prefix)
		for i < list.Len() && k != nil && bytes.HasPrefix(k, prefix) {
			switch bytes.Compare([]byte((*list)[i].Path), k) {
			case 0:
				info := &FInfo{}
				err := proto.Unmarshal(v, info)
				if err != nil {
				}
				if (*list)[i].Mtime != info.Mtime || (*list)[i].Size != info.Size {
					downloadList = append(downloadList, i)
				}
				i++
				k, v = c.Next()
				break
			case 1:
				deleteList = append(deleteList, string(k))
				k, v = c.Next()
				break
			case -1:
				downloadList = append(downloadList, i)
				i++
				break
			}
		}

	// Interate cache.module(A) & list(B), both A & B must be sorted lexicographically before
		return nil
	})

	// Compare their path

@@ -22,5 +72,4 @@ func (cache *Cache) Diff(list *rsync.FileList) (*rsync.FileList, *rsync.FileList

	// If < 0, A doesn't have

	return nil, nil
}
+5 −1
Original line number Diff line number Diff line
@@ -36,7 +36,11 @@ func Socket(uri string) {

	defer conn.Close()

	rsync.HandShake(conn, module, path)
	c := &rsync.Client{
		Conn: conn,
	}

	c.HandShake(module, path)

	// fmt.Println(readInteger(conn))
	log.Println("HandShake OK")
+59 −14
Original line number Diff line number Diff line
@@ -12,39 +12,56 @@ import (
	"github.com/minio/minio-go/v6"
)

type Client struct {
	Conn    net.Conn
	DemuxIn chan byte
	CksSeed int32
	// Options
}

// Header: '@RSYNCD: 31.0\n' + ? + '\n' + arguments + '\0'
// Header len 8		AUTHREQD: 18	"@RSYNCD: EXIT" 13		RSYNC_MODULE_LIST_QUERY "\n"

// See clienserver.c start_inband_exchange
func HandShake(conn net.Conn, module string, path string) {
func (c *Client) HandShake(module string, path string) {
	// send my version
	// send("@RSYNCD: 31.0\n");
	conn.Write([]byte("@RSYNCD: 27.0\n"))
	c.Conn.Write([]byte("@RSYNCD: 27.0\n"))

	// receive server's protocol version and seed
	version_str, _ := ReadLine(conn)
	versionStr, _ := ReadLine(c.Conn)

	// recv(version)
	var remote_protocol, remote_sub int
	fmt.Sscanf(version_str, "@RSYNCD: %d.%d", remote_protocol, remote_sub)
	log.Println(version_str)
	var remoteProtocol, remoteProtocolSub int
	fmt.Sscanf(versionStr, "@RSYNCD: %d.%d", remoteProtocol, remoteProtocolSub)
	log.Println(versionStr)

	// send mod name
	// send("Foo\n")
	conn.Write([]byte(module))
	conn.Write([]byte("\n"))
	c.Conn.Write([]byte(module))
	c.Conn.Write([]byte("\n"))
	//conn.Write([]byte("epel\n"))
	// conn.Write([]byte("\n"))

	for {
		// Wait for '@RSYNCD: OK': until \n, then add \0
		res, _ := ReadLine(conn)
		res, _ := ReadLine(c.Conn)
		log.Print(res)
		if strings.Contains(res, "@RSYNCD: OK") {
			break
		}
	}

	c.SendArgs(module, path)

	// read int32 as seed
	c.CksSeed = ReadInteger(c.Conn)
	log.Println("SEED", c.CksSeed)

	c.SendEmptyExclusion()
}

func (c *Client) SendArgs(module string, path string) {
	// send parameters list
	//conn.Write([]byte("--server\n--sender\n-g\n-l\n-o\n-p\n-D\n-r\n-t\n.\nepel/7/SRPMS\n\n"))
	//conn.Write([]byte("--server\n--sender\n-l\n-p\n-r\n-t\n.\nepel/7/SRPMS\n\n"))	// without gid, uid, mdev
@@ -53,14 +70,42 @@ func HandShake(conn net.Conn, module string, path string) {
	args.Write([]byte(module))
	args.Write([]byte(path))
	args.Write([]byte("\n\n"))
	conn.Write(args.Bytes())
	c.Conn.Write(args.Bytes())
}

	// read int32 as seed
	bseed := ReadInteger(conn)
	log.Println("SEED", bseed)
func (c *Client) ListOnly(module string, path string) {
	c.Conn.Write([]byte("@RSYNCD: 27.0\n"))
	versionStr, _ := ReadLine(c.Conn)
	// var remoteProtocol, remoteProtocolSub int
	// fmt.Sscanf(versionStr, "@RSYNCD: %d.%d", remoteProtocol, remoteProtocolSub)
	log.Println(versionStr)
	c.Conn.Write([]byte(module))
	c.Conn.Write([]byte("\n"))
	for {
		// Wait for '@RSYNCD: OK': until \n, then add \0
		res, _ := ReadLine(c.Conn)
		log.Print(res)
		if strings.Contains(res, "@RSYNCD: OK") {
			break
		}
	}
	args := new(bytes.Buffer)
	args.Write([]byte("--server\n--sender\n-l\n-p\n-r\n-t\n.\n"))
	args.Write([]byte(module))
	args.Write([]byte(path))
	args.Write([]byte("\n\n"))

	c.Conn.Write(args.Bytes())

	seed := ReadInteger(c.Conn)
	log.Println("SEED", seed)

	c.Conn.Write(make([]byte, 4))
}

func (c *Client) SendEmptyExclusion() {
	// send filter_list, empty is 32-bit zero
	conn.Write([]byte("\x00\x00\x00\x00"))
	c.Conn.Write([]byte("\x00\x00\x00\x00"))
}

type FileInfo struct {