NewFromControlFile loads a zsync control file and returns a Syncer to be used to reconstruct the target file.
(f io.Reader, options SyncerOptions)
| 79 | // NewFromControlFile loads a zsync control file and returns a Syncer to be |
| 80 | // used to reconstruct the target file. |
| 81 | func NewFromControlFile(f io.Reader, options SyncerOptions) (*Syncer, error) { |
| 82 | zs := &Syncer{} |
| 83 | err := zs.parseControlFile(f) |
| 84 | if err != nil { |
| 85 | return nil, err |
| 86 | } |
| 87 | |
| 88 | if options.OverrideTargetFilename != "" { |
| 89 | zs.targetFilename = options.OverrideTargetFilename |
| 90 | } else if zs.targetFilename == "" { |
| 91 | zs.targetFilename = options.FallbackTargetFilename |
| 92 | if zs.targetFilename == "" { |
| 93 | return nil, errNoFilename |
| 94 | } |
| 95 | } else { |
| 96 | // Strip any leading path component from the control file, to stop any |
| 97 | // "Filename: ../../" trickery. |
| 98 | zs.targetFilename = filepath.Base(zs.targetFilename) |
| 99 | if !strings.HasPrefix(zs.targetFilename, options.RequireTargetFilenamePrefix) { |
| 100 | return nil, errBadPrefix |
| 101 | } |
| 102 | } |
| 103 | zs.targetFilename = filepath.Join(options.TargetDirectory, zs.targetFilename) |
| 104 | |
| 105 | zs.tempFile, err = os.CreateTemp(options.TargetDirectory, "rcksum-*") |
| 106 | if err != nil { |
| 107 | return nil, fmt.Errorf("failed to create temporary file in %s: %w", options.TargetDirectory, err) |
| 108 | } |
| 109 | zs.rs.SetTargetFile(zs.tempFile) |
| 110 | zs.curFilename = zs.tempFile.Name() |
| 111 | zs.rs.Prepare() |
| 112 | return zs, nil |
| 113 | } |
| 114 | |
| 115 | // GetTargetFilename returns the filename for the file being reconstructed. |
| 116 | func (zs *Syncer) GetTargetFilename() string { |