|
| 1 | +package config |
| 2 | + |
| 3 | +import ( |
| 4 | + "errors" |
| 5 | + "io/ioutil" |
| 6 | + "os" |
| 7 | + "path/filepath" |
| 8 | + "strings" |
| 9 | + |
| 10 | + "github.com/getlantern/yaml" |
| 11 | + |
| 12 | + "github.com/getlantern/flashlight/common" |
| 13 | +) |
| 14 | + |
| 15 | +var ( |
| 16 | + name = ".packaged-lantern.yaml" |
| 17 | + lanternYamlName = "lantern.yaml" |
| 18 | +) |
| 19 | + |
| 20 | +// BootstrapSettings provides access to configuration embedded directly in Lantern installation |
| 21 | +// packages. On OSX, that means data embedded in the Lantern.app app bundle in |
| 22 | +// Lantern.app/Contents/Resources/.lantern.yaml, while on Windows that means data embedded |
| 23 | +// in AppData/Roaming/Lantern/.lantern.yaml. This allows customization embedded in the |
| 24 | +// installer outside of the auto-updated binary that should only be used under special |
| 25 | +// circumstances. |
| 26 | +type BootstrapSettings struct { |
| 27 | + StartupUrl string |
| 28 | +} |
| 29 | + |
| 30 | +// ReadBootstrapSettings reads packaged settings from pre-determined paths |
| 31 | +// on the various OSes. |
| 32 | +func ReadBootstrapSettings(configDir string) (*BootstrapSettings, error) { |
| 33 | + _, yamlPath, err := bootstrapPath(name) |
| 34 | + if err != nil { |
| 35 | + return &BootstrapSettings{}, err |
| 36 | + } |
| 37 | + |
| 38 | + ps, er := readSettingsFromFile(yamlPath) |
| 39 | + if er != nil { |
| 40 | + // This is the local copy of our embedded ration file. This is necessary |
| 41 | + // to ensure we remember the embedded ration across auto-updated |
| 42 | + // binaries. We write to the local file system instead of to the package |
| 43 | + // itself (app bundle on OSX, install directory on Windows) because |
| 44 | + // we're not always sure we can write to that directory. |
| 45 | + return readSettingsFromFile(filepath.Join(configDir, name)) |
| 46 | + } |
| 47 | + return ps, nil |
| 48 | +} |
| 49 | + |
| 50 | +// ReadSettingsFromFile reads BootstrapSettings from the yaml file at the specified |
| 51 | +// path. |
| 52 | +func readSettingsFromFile(yamlPath string) (*BootstrapSettings, error) { |
| 53 | + log.Debugf("Opening file at: %v", yamlPath) |
| 54 | + data, err := ioutil.ReadFile(yamlPath) |
| 55 | + if err != nil { |
| 56 | + // This will happen whenever there's no packaged settings, which is often |
| 57 | + log.Debugf("Error reading file %v", err) |
| 58 | + return &BootstrapSettings{}, err |
| 59 | + } |
| 60 | + |
| 61 | + trimmed := strings.TrimSpace(string(data)) |
| 62 | + |
| 63 | + log.Debugf("Read bytes: %v", trimmed) |
| 64 | + |
| 65 | + if trimmed == "" { |
| 66 | + log.Debugf("Ignoring empty string") |
| 67 | + return &BootstrapSettings{}, errors.New("Empty string") |
| 68 | + } |
| 69 | + var s BootstrapSettings |
| 70 | + err = yaml.Unmarshal([]byte(trimmed), &s) |
| 71 | + |
| 72 | + if err != nil { |
| 73 | + log.Errorf("Could not read yaml: %v", err) |
| 74 | + return &BootstrapSettings{}, err |
| 75 | + } |
| 76 | + return &s, nil |
| 77 | +} |
| 78 | + |
| 79 | +func bootstrapPath(fileName string) (string, string, error) { |
| 80 | + dir, err := filepath.Abs(filepath.Dir(os.Args[0])) |
| 81 | + if err != nil { |
| 82 | + log.Errorf("Could not get current directory %v", err) |
| 83 | + return "", "", err |
| 84 | + } |
| 85 | + var yamldir string |
| 86 | + if common.Platform == "windows" { |
| 87 | + yamldir = dir |
| 88 | + } else if common.Platform == "darwin" { |
| 89 | + // Code signing doesn't like this file in the current directory |
| 90 | + // for whatever reason, so we grab it from the Resources/en.lproj |
| 91 | + // directory in the app bundle. See: |
| 92 | + // https://developer.apple.com/library/mac/technotes/tn2206/_index.html#//apple_ref/doc/uid/DTS40007919-CH1-TNTAG402 |
| 93 | + yamldir = dir + "/../Resources/en.lproj" |
| 94 | + if _, err := ioutil.ReadDir(yamldir); err != nil { |
| 95 | + // This likely means the user originally installed with an older version that didn't include en.lproj |
| 96 | + // in the app bundle, so just look in the old location in Resources. |
| 97 | + yamldir = dir + "/../Resources" |
| 98 | + } |
| 99 | + } else if common.Platform == "linux" { |
| 100 | + yamldir = dir + "/../" |
| 101 | + } |
| 102 | + fullPath := filepath.Join(yamldir, fileName) |
| 103 | + log.Debugf("Opening bootstrap file from: %v", fullPath) |
| 104 | + return yamldir, fullPath, nil |
| 105 | +} |
0 commit comments