// ParseContents sends a Composition for each block of the source container func (g *Genie) ParseContents(onComp CompositionListener) error { patchWire := g.PatchWire // for each file, the patch contains a SyncHeader followed by a series of // operations, always ending in HEY_YOU_DID_IT sh := &pwr.SyncHeader{} for fileIndex, f := range g.SourceContainer.Files { sh.Reset() err := patchWire.ReadMessage(sh) if err != nil { return errors.Wrap(err, 1) } if sh.FileIndex != int64(fileIndex) { fmt.Printf("expected fileIndex = %d, got fileIndex %d\n", fileIndex, sh.FileIndex) return errors.Wrap(pwr.ErrMalformedPatch, 1) } err = g.analyzeFile(patchWire, int64(fileIndex), f.Size, onComp) if err != nil { return errors.Wrap(err, 1) } } return nil }
// GetReader returns an io.Reader for the file at index fileIndex // Successive calls to `GetReader` will attempt to re-use the last // returned reader if the file index is similar. The cache size is 1, so // reading in parallel from different files is not supported. func (cfp *ZipPool) GetReader(fileIndex int64) (io.Reader, error) { if cfp.fileIndex != fileIndex { if cfp.reader != nil { err := cfp.reader.Close() if err != nil { return nil, errors.Wrap(err, 1) } cfp.reader = nil cfp.fileIndex = -1 } relPath := cfp.GetRelativePath(fileIndex) f := cfp.fmap[relPath] if f == nil { if os.Getenv("VERBOSE_ZIP_POOL") != "" { fmt.Printf("\nzip contents:\n") for k := range cfp.fmap { fmt.Printf("\n- %s", k) } fmt.Println() } return nil, errors.WrapPrefix(os.ErrNotExist, relPath, 1) } reader, err := f.Open() if err != nil { return nil, errors.Wrap(err, 1) } cfp.reader = reader cfp.fileIndex = fileIndex } return cfp.reader, nil }
// ApplyPatch applies the difference to the target. func (ctx *Context) ApplyPatch(output io.Writer, pool Pool, ops chan Operation) error { blockSize := int64(ctx.blockSize) for op := range ops { switch op.Type { case OpBlockRange: target, err := pool.GetReadSeeker(op.FileIndex) if err != nil { return errors.Wrap(err, 1) } _, err = target.Seek(blockSize*op.BlockIndex, os.SEEK_SET) if err != nil { return errors.Wrap(err, 1) } _, err = io.CopyN(output, target, blockSize*op.BlockSpan) if err != nil { // EOF is actually expected, since we want to copy short // blocks at the end of files. Other errors aren't expected. if err != io.EOF { return errors.Wrap(fmt.Errorf("While copying %d bytes: %s", blockSize*op.BlockSpan, err.Error()), 1) } } case OpData: _, err := output.Write(op.Data) if err != nil { return errors.Wrap(err, 1) } } } return nil }
// ParseHeader is the first step of the genie's operation - it reads both // containers, leaving the caller a chance to use them later, when parsing // the contents func (g *Genie) ParseHeader(patchReader io.Reader) error { rawPatchWire := wire.NewReadContext(patchReader) err := rawPatchWire.ExpectMagic(pwr.PatchMagic) if err != nil { return errors.Wrap(err, 1) } header := &pwr.PatchHeader{} err = rawPatchWire.ReadMessage(header) if err != nil { return errors.Wrap(err, 1) } patchWire, err := pwr.DecompressWire(rawPatchWire, header.Compression) if err != nil { return errors.Wrap(err, 1) } g.PatchWire = patchWire g.TargetContainer = &tlc.Container{} err = patchWire.ReadMessage(g.TargetContainer) if err != nil { return errors.Wrap(err, 1) } g.SourceContainer = &tlc.Container{} err = patchWire.ReadMessage(g.SourceContainer) if err != nil { return errors.Wrap(err, 1) } return nil }
func ExtractPath(archive string, destPath string, settings ExtractSettings) (*ExtractResult, error) { var result *ExtractResult var err error file, err := eos.Open(archive) if err != nil { return nil, errors.Wrap(err, 1) } stat, err := file.Stat() if err != nil { return nil, errors.Wrap(err, 1) } defer func() { if cErr := file.Close(); cErr != nil && err == nil { err = errors.Wrap(cErr, 1) } }() result, err = Extract(file, stat.Size(), destPath, settings) if err != nil { return nil, errors.Wrap(err, 1) } return result, nil }
func Mkdir(dstpath string) error { dirstat, err := os.Lstat(dstpath) if err != nil { // main case - dir doesn't exist yet err = os.MkdirAll(dstpath, DirMode) if err != nil { return errors.Wrap(err, 1) } return nil } if dirstat.IsDir() { // is already a dir, good! } else { // is a file or symlink for example, turn into a dir err = os.Remove(dstpath) if err != nil { return errors.Wrap(err, 1) } err = os.MkdirAll(dstpath, DirMode) if err != nil { return errors.Wrap(err, 1) } } return nil }
// GetOrderBookSummary loads a summary of an order book identified by a // selling/buying pair. It is designed to drive an order book summary client // interface (bid/ask spread, prices and volume, etc). func (q *Q) GetOrderBookSummary(dest interface{}, selling xdr.Asset, buying xdr.Asset) error { var sql bytes.Buffer var oq orderbookQueryBuilder err := selling.Extract(&oq.SellingType, &oq.SellingCode, &oq.SellingIssuer) if err != nil { return err } err = buying.Extract(&oq.BuyingType, &oq.BuyingCode, &oq.BuyingIssuer) if err != nil { return err } oq.pushArg(20) err = orderbookQueryTemplate.Execute(&sql, &oq) if err != nil { return errors.Wrap(err, 1) } err = q.SelectRaw(dest, sql.String(), oq.args...) if err != nil { return errors.Wrap(err, 1) } return nil }
// WalkAny tries to retrieve container information on containerPath. It supports: // the empty container (/dev/null), local directories, zip archives func WalkAny(containerPath string, filter FilterFunc) (*Container, error) { // empty container case if containerPath == NullPath { return &Container{}, nil } file, err := eos.Open(containerPath) if err != nil { return nil, errors.Wrap(err, 1) } defer file.Close() stat, err := file.Stat() if err != nil { return nil, errors.Wrap(err, 1) } if stat.IsDir() { if err != nil { return nil, errors.Wrap(err, 1) } // local directory case return WalkDir(containerPath, filter) } // zip archive case zr, err := zip.NewReader(file, stat.Size()) if err != nil { return nil, errors.Wrap(err, 1) } return WalkZip(zr, filter) }
// Fetch reads a block from disk func (ds *DiskSource) Fetch(loc BlockLocation, data []byte) (int, error) { addr := ds.BlockAddresses.Get(loc) if addr == "" { return 0, errors.Wrap(fmt.Errorf("no address for block %+v", loc), 1) } path := filepath.Join(ds.BasePath, addr) fr, err := os.Open(path) if err != nil { return 0, errors.Wrap(err, 1) } defer fr.Close() if ds.Decompressor == nil { bytesRead, err := io.ReadFull(fr, data) if err != nil { if err == io.ErrUnexpectedEOF { // all good } else { return 0, errors.Wrap(err, 1) } } return bytesRead, nil } return ds.Decompressor.Decompress(data, fr) }
// Prepare creates all directories, files, and symlinks. // It also applies the proper permissions if the files already exist func (c *Container) Prepare(basePath string) error { err := os.MkdirAll(basePath, 0755) if err != nil { return errors.Wrap(err, 1) } for _, dirEntry := range c.Dirs { err := c.prepareDir(basePath, dirEntry) if err != nil { return errors.Wrap(err, 1) } } for _, fileEntry := range c.Files { err := c.prepareFile(basePath, fileEntry) if err != nil { return errors.Wrap(err, 1) } } for _, link := range c.Symlinks { err := c.prepareSymlink(basePath, link) if err != nil { return errors.Wrap(err, 1) } } return nil }
// GetReadSeeker is like GetReader but the returned object allows seeking func (cfp *ZipPool) GetReadSeeker(fileIndex int64) (io.ReadSeeker, error) { if cfp.seekFileIndex != fileIndex { if cfp.readSeeker != nil { err := cfp.readSeeker.Close() if err != nil { return nil, errors.Wrap(err, 1) } cfp.readSeeker = nil cfp.seekFileIndex = -1 } key := cfp.GetRelativePath(fileIndex) f := cfp.fmap[key] if f == nil { return nil, errors.Wrap(os.ErrNotExist, 1) } reader, err := f.Open() if err != nil { return nil, errors.Wrap(err, 1) } defer reader.Close() buf, err := ioutil.ReadAll(reader) if err != nil { return nil, errors.Wrap(err, 1) } cfp.readSeeker = &closableBuf{bytes.NewReader(buf)} cfp.seekFileIndex = fileIndex } return cfp.readSeeker, nil }
func (dw *Writer) Write(data []byte) (int, error) { dataOffset := 0 totalBytes := len(data) for dataOffset < totalBytes { writtenBytes := totalBytes - dataOffset if writtenBytes > len(dw.Buffer)-dw.offset { writtenBytes = len(dw.Buffer) - dw.offset } copy(dw.Buffer[dw.offset:], data[dataOffset:dataOffset+writtenBytes]) dataOffset += writtenBytes dw.offset += writtenBytes if dw.offset == len(dw.Buffer) { buf := dw.Buffer if dw.Validate != nil { err := dw.Validate(buf) if err != nil { return 0, errors.Wrap(err, 1) } } _, err := dw.Writer.Write(buf) if err != nil { return 0, errors.Wrap(err, 1) } dw.offset = 0 } } return totalBytes, nil }
func New(c *tlc.Container, basePath string) (wsync.Pool, error) { if basePath == "/dev/null" { return fspool.New(c, basePath), nil } fr, err := eos.Open(basePath) if err != nil { return nil, errors.Wrap(err, 1) } targetInfo, err := fr.Stat() if err != nil { return nil, errors.Wrap(err, 1) } if targetInfo.IsDir() { err := fr.Close() if err != nil { return nil, err } return fspool.New(c, basePath), nil } else { zr, err := zip.NewReader(fr, targetInfo.Size()) if err != nil { return nil, errors.Wrap(err, 1) } return zippool.New(c, zr), nil } }
func (actx *ApplyContext) move(oldAbsolutePath string, newAbsolutePath string) error { err := os.Remove(newAbsolutePath) if err != nil { if !os.IsNotExist(err) { return errors.Wrap(err, 1) } } err = os.MkdirAll(filepath.Dir(newAbsolutePath), os.FileMode(0755)) if err != nil { return errors.Wrap(err, 1) } if actx.debugBrokenRename { err = &os.PathError{} } else { err = os.Rename(oldAbsolutePath, newAbsolutePath) } if err != nil { cErr := actx.copy(oldAbsolutePath, newAbsolutePath, mkdirBehaviorNever) if cErr != nil { return cErr } cErr = os.Remove(oldAbsolutePath) if cErr != nil { return cErr } } return nil }
// WriteMessage serializes a protobuf message and writes it to the stream func (w *WriteContext) WriteMessage(msg proto.Message) error { if DebugWire { fmt.Printf("<< %s %+v\n", reflect.TypeOf(msg).Elem().Name(), msg) } buf, err := proto.Marshal(msg) if err != nil { return errors.Wrap(err, 1) } vibuflen := binary.PutUvarint(w.varintBuffer, uint64(len(buf))) if err != nil { return errors.Wrap(err, 1) } _, err = w.writer.Write(w.varintBuffer[:vibuflen]) if err != nil { return errors.Wrap(err, 1) } _, err = w.writer.Write(buf) if err != nil { return errors.Wrap(err, 1) } return nil }
func doLogin() error { var identity = *appArgs.identity _, err := os.Lstat(identity) hasSavedCredentials := !os.IsNotExist(err) if hasSavedCredentials { client, err := authenticateViaOauth() if err != nil { return errors.Wrap(err, 1) } _, err = client.WharfStatus() if err != nil { return errors.Wrap(err, 1) } comm.Logf("Your local credentials are valid!\n") comm.Logf("If you want to log in as another account, use the `butler logout` command first, or specify a different credentials path with the `-i` flag.") } else { // this does the full login flow + saves _, err := authenticateViaOauth() if err != nil { return errors.Wrap(err, 1) } return nil } return nil }
func (s *server) inc(req *IncReq) (res *IncRes, err error) { defer Logger.Time(time.Now(), time.Second, "server.inc") res = &IncRes{} db, ok := s.databases[req.Database] if !ok { return nil, goerr.Wrap(ErrDatabase, 0) } metadata, err := db.Info() if err != nil { return nil, goerr.Wrap(err, 0) } timestamp := int64(req.Timestamp) * 1e9 endTime := timestamp + metadata.Resolution data, err := db.One(timestamp, endTime, req.Fields) if err != nil { return nil, goerr.Wrap(err, 0) } val, num := pldToVal(data[0]) num += req.Count val += req.Value pld := valToPld(val, num) err = db.Put(timestamp, req.Fields, pld) if err != nil { return nil, goerr.Wrap(err, 0) } return res, nil }
func CopyFile(filename string, mode os.FileMode, fileReader io.Reader) error { err := os.RemoveAll(filename) if err != nil { return errors.Wrap(err, 1) } dirname := filepath.Dir(filename) err = os.MkdirAll(dirname, LuckyMode) if err != nil { return errors.Wrap(err, 1) } writer, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, mode) if err != nil { return errors.Wrap(err, 1) } defer writer.Close() _, err = io.Copy(writer, fileReader) if err != nil { return errors.Wrap(err, 1) } err = os.Chmod(filename, mode) if err != nil { return errors.Wrap(err, 1) } return nil }
func (d *DatasourceDDerive) CalculatePdpPrep(newValue string, interval float64) (float64, error) { if float64(d.Heartbeat) < interval { d.LastValue = Undefined } rate := math.NaN() newPdp := math.NaN() if newValue != Undefined && float64(d.Heartbeat) >= interval { newval, err := strconv.ParseFloat(newValue, 64) if err != nil { return math.NaN(), errors.Wrap(err, 0) } oldval, err := strconv.ParseFloat(d.LastValue, 64) if err != nil { return math.NaN(), errors.Wrap(err, 0) } newPdp = newval - oldval rate = newPdp / interval } if !d.checkRateBounds(rate) { newPdp = math.NaN() } d.LastValue = newValue return newPdp, nil }
func OpenRrdRawFile(name string, readOnly bool) (*rrd.Rrd, error) { dataFile, err := OpenRawDataFile(name, readOnly, binary.LittleEndian, 8, 8) if err != nil { return nil, err } rrdFile := &RrdRawFile{ dataFile: dataFile, } reader := dataFile.Reader(0) if err := rrdFile.readHeaders(reader); err != nil { dataFile.Close() return nil, errors.Wrap(err, 0) } rrdFile.headerSize = reader.CurPosition() rrdFile.calculateRraStarts() rrd, err := rrd.NewRrd(rrdFile) if err != nil { return nil, errors.Wrap(err, 0) } return rrd, nil }
func (c *Container) FixPermissions(pool wsync.Pool) error { defer pool.Close() buf := make([]byte, minScannedFileSize) for index, f := range c.Files { if f.Size < minScannedFileSize { continue } r, err := pool.GetReader(int64(index)) if err != nil { return errors.Wrap(err, 1) } _, err = io.ReadFull(r, buf) if err != nil { return errors.Wrap(err, 1) } if isExecutable(buf) { f.Mode |= 0111 } } return nil }
func (s *Emulator) CreateUnicorn() *errors.Error { if s.mu != nil { s.Close() } mu, err2 := uc.NewUnicorn(s.Config.Arch.ToUnicornArchDescription(), s.Config.Arch.ToUnicornModeDescription()) s.WorkingSet = NewWorkingSet(s.Config.MaxTracePages) if err2 != nil { return errors.Wrap(err2, 0) } s.mu = mu err := s.addHooks() if err != nil { return errors.Wrap(err, 0) } if err := s.ResetMemoryImage(); err != nil { return err } if err := s.ResetWorkingSet(); err != nil { return err } if err := s.ResetRegisters(); err != nil { return err } return nil }
// Close writes symlinks and dirs of the container, then closes // the zip writer. func (zwp *ZipWriterPool) Close() error { for _, symlink := range zwp.container.Symlinks { fh := zip.FileHeader{ Name: symlink.Path, } fh.SetMode(os.FileMode(symlink.Mode)) entryWriter, eErr := zwp.zw.CreateHeader(&fh) if eErr != nil { return errors.Wrap(eErr, 1) } entryWriter.Write([]byte(symlink.Dest)) } for _, dir := range zwp.container.Dirs { fh := zip.FileHeader{ Name: dir.Path + "/", } fh.SetMode(os.FileMode(dir.Mode)) fh.SetModTime(time.Now()) _, hErr := zwp.zw.CreateHeader(&fh) if hErr != nil { return errors.Wrap(hErr, 1) } } err := zwp.zw.Close() if err != nil { return errors.Wrap(err, 1) } return nil }
func ParseAPIResponse(dst interface{}, res *http.Response) error { if res == nil || res.Body == nil { return fmt.Errorf("No response from server") } bodyReader := res.Body defer bodyReader.Close() if res.StatusCode/100 != 2 { return fmt.Errorf("Server returned %s for %s", res.Status, res.Request.URL.String()) } body, err := ioutil.ReadAll(bodyReader) if err != nil { return errors.Wrap(err, 1) } err = json.NewDecoder(bytes.NewReader(body)).Decode(dst) if err != nil { msg := fmt.Sprintf("JSON decode error: %s\n\nBody: %s\n\n", err.Error(), string(body)) return errors.Wrap(errors.New(msg), 1) } errs := reflect.Indirect(reflect.ValueOf(dst)).FieldByName("Errors") if errs.Len() > 0 { // TODO: handle other errors too return fmt.Errorf("itch.io API error: %s", errs.Index(0).String()) } return nil }
// ApplyPatchFull is like ApplyPatch but accepts an ApplyWound channel func (ctx *Context) ApplyPatchFull(output io.Writer, pool Pool, ops chan Operation, failFast bool) error { blockSize := int64(ctx.blockSize) pos := int64(0) for op := range ops { switch op.Type { case OpBlockRange: fileSize := pool.GetSize(op.FileIndex) fixedSize := (op.BlockSpan - 1) * blockSize lastIndex := op.BlockIndex + (op.BlockSpan - 1) lastSize := blockSize if blockSize*(lastIndex+1) > fileSize { lastSize = fileSize % blockSize } opSize := (fixedSize + lastSize) target, err := pool.GetReadSeeker(op.FileIndex) if err != nil { if failFast { return errors.Wrap(err, 1) } io.CopyN(output, &devNullReader{}, opSize) pos += opSize continue } _, err = target.Seek(blockSize*op.BlockIndex, os.SEEK_SET) if err != nil { if failFast { return errors.Wrap(err, 1) } io.CopyN(output, &devNullReader{}, opSize) pos += opSize continue } copied, err := io.CopyN(output, target, opSize) if err != nil { if failFast { return errors.Wrap(fmt.Errorf("While copying %d bytes: %s", blockSize*op.BlockSpan, err.Error()), 1) } remaining := opSize - copied io.CopyN(output, &devNullReader{}, remaining) pos += opSize continue } case OpData: _, err := output.Write(op.Data) if err != nil { return errors.Wrap(err, 1) } } } return nil }
func doVerify(signaturePath string, dir string, woundsPath string, healPath string) error { if woundsPath == "" { if healPath == "" { comm.Opf("Verifying %s", dir) } else { comm.Opf("Verifying %s, healing as we go", dir) } } else { if healPath == "" { comm.Opf("Verifying %s, writing wounds to %s", dir, woundsPath) } else { comm.Dief("Options --wounds and --heal cannot be used at the same time") } } startTime := time.Now() signatureReader, err := eos.Open(signaturePath) if err != nil { return errors.Wrap(err, 1) } defer signatureReader.Close() signature, err := pwr.ReadSignature(signatureReader) if err != nil { return errors.Wrap(err, 1) } vc := &pwr.ValidatorContext{ Consumer: comm.NewStateConsumer(), WoundsPath: woundsPath, HealPath: healPath, } comm.StartProgressWithTotalBytes(signature.Container.Size) err = vc.Validate(dir, signature) if err != nil { return errors.Wrap(err, 1) } comm.EndProgress() prettySize := humanize.IBytes(uint64(signature.Container.Size)) perSecond := humanize.IBytes(uint64(float64(signature.Container.Size) / time.Since(startTime).Seconds())) comm.Statf("%s (%s) @ %s/s\n", prettySize, signature.Container.Stats(), perSecond) if vc.WoundsConsumer.HasWounds() { if healer, ok := vc.WoundsConsumer.(pwr.Healer); ok { comm.Statf("%s corrupted data found, %s healed", humanize.IBytes(uint64(vc.WoundsConsumer.TotalCorrupted())), humanize.IBytes(uint64(healer.TotalHealed()))) } else { comm.Dief("%s corrupted data found", humanize.IBytes(uint64(vc.WoundsConsumer.TotalCorrupted()))) } } return nil }
// Submit sends the provided envelope to stellar-core and parses the response into // a SubmissionResult func (sub *submitter) Submit(ctx context.Context, env string) (result SubmissionResult) { start := time.Now() defer func() { result.Duration = time.Since(start) }() // construct the request u, err := url.Parse(sub.coreURL) if err != nil { result.Err = errors.Wrap(err, 1) return } u.Path = "/tx" q := u.Query() q.Add("blob", env) u.RawQuery = q.Encode() req, err := http.NewRequest("GET", u.String(), nil) if err != nil { result.Err = errors.Wrap(err, 1) return } // perform the submission resp, err := sub.http.Do(req) if err != nil { result.Err = errors.Wrap(err, 1) return } defer resp.Body.Close() // parse response var cresp coreSubmissionResponse err = json.NewDecoder(resp.Body).Decode(&cresp) if err != nil { result.Err = errors.Wrap(err, 1) return } // interpet response if cresp.Exception != "" { result.Err = errors.Errorf("stellar-core exception: %s", cresp.Exception) return } switch cresp.Status { case StatusError: result.Err = &FailedTransactionError{cresp.Error} case StatusPending, StatusDuplicate: //noop. A nil Err indicates success default: result.Err = errors.Errorf("Unrecognized stellar-core status response: %s", cresp.Status) } return }
// CreateSignature calculate the signature of target. func (ctx *Context) CreateSignature(fileIndex int64, fileReader io.Reader, writeHash SignatureWriter) error { s := bufio.NewScanner(fileReader) s.Buffer(make([]byte, ctx.blockSize), 0) s.Split(splitfunc.New(ctx.blockSize)) blockIndex := int64(0) hashBlock := func(block []byte) error { weakHash, _, _ := βhash(block) strongHash := ctx.uniqueHash(block) blockHash := BlockHash{ FileIndex: fileIndex, BlockIndex: blockIndex, WeakHash: weakHash, StrongHash: strongHash, } if len(block) < ctx.blockSize { blockHash.ShortSize = int32(len(block)) } err := writeHash(blockHash) if err != nil { return errors.Wrap(err, 1) } blockIndex++ return nil } for s.Scan() { err := hashBlock(s.Bytes()) if err != nil { return errors.Wrap(err, 1) } } err := s.Err() if err != nil { return errors.Wrap(err, 1) } // let empty files have a 0-length shortblock if blockIndex == 0 { err := hashBlock([]byte{}) if err != nil { return errors.Wrap(err, 1) } } return nil }
// Open the postgres database at the provided url and performing an initial // ping to ensure we can connect to it. func Open(url string) (*sql.DB, error) { db, err := sql.Open("postgres", url) if err != nil { return db, errors.Wrap(err, 1) } err = db.Ping() if err != nil { return db, errors.Wrap(err, 1) } return db, nil }
func (c *Container) prepareDir(basePath string, dirEntry *Dir) error { fullPath := filepath.Join(basePath, dirEntry.Path) err := os.MkdirAll(fullPath, os.FileMode(dirEntry.Mode)) if err != nil { return errors.Wrap(err, 1) } err = os.Chmod(fullPath, os.FileMode(dirEntry.Mode)) if err != nil { return errors.Wrap(err, 1) } return nil }