func (s *darwinLaunchdService) Install() error { var confPath = s.getServiceFilePath() _, err := os.Stat(confPath) if err == nil { return fmt.Errorf("Init already exists: %s", confPath) } f, err := os.Create(confPath) if err != nil { return err } defer f.Close() path, err := osext.Executable() if err != nil { return err } var to = &struct { Name string Display string Description string Path string }{ s.name, s.displayName, s.description, path, } t := template.Must(template.New("launchdConfig").Parse(launchdConfig)) return t.Execute(f, to) }
func (ws *windowsService) Install() error { exepath, err := osext.Executable() if err != nil { return err } m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() s, err := m.OpenService(ws.name) if err == nil { s.Close() return fmt.Errorf("service %s already exists", ws.name) } s, err = m.CreateService(ws.name, exepath, mgr.Config{ DisplayName: ws.displayName, Description: ws.description, StartType: mgr.StartAutomatic, }) if err != nil { return err } defer s.Close() err = eventlog.InstallAsEventCreate(ws.name, eventlog.Error|eventlog.Warning|eventlog.Info) if err != nil { s.Delete() return fmt.Errorf("InstallAsEventCreate() failed: %s", err) } return nil }
func exePath() string { exePath, err := osext.Executable() if err != nil { panic(err) } return exePath }
func updateSelf() { fmt.Println("Downloading latest version...") resp, err := http.Get("https://s3.amazonaws.com/progrium-flynn/flynn-grid/dev/grid-cli_" + runtime.GOOS + "_" + runtime.GOARCH + ".tgz") assert(err) defer resp.Body.Close() z, err := gzip.NewReader(resp.Body) assert(err) defer z.Close() t := tar.NewReader(z) hdr, err := t.Next() assert(err) if hdr.Name != "grid" { log.Fatal("grid binary not found in tarball") } defer t.Next() selfpath, err := osext.Executable() assert(err) info, err := os.Stat(selfpath) assert(err) assert(os.Rename(selfpath, selfpath+".old")) f, err := os.OpenFile(selfpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, info.Mode().Perm()) if err != nil { assert(os.Rename(selfpath+".old", selfpath)) assert(err) } defer f.Close() _, err = io.Copy(f, t) if err != nil { assert(os.Rename(selfpath+".old", selfpath)) assert(err) } assert(os.Remove(selfpath + ".old")) fmt.Println("Updated.") }
func upgrade() error { path, err := osext.Executable() if err != nil { return err } resp, err := http.Get("https://api.github.com/repos/calmh/syncthing/releases?per_page=1") if err != nil { return err } var rels []githubRelease json.NewDecoder(resp.Body).Decode(&rels) resp.Body.Close() if len(rels) != 1 { return fmt.Errorf("Unexpected number of releases: %d", len(rels)) } rel := rels[0] if rel.Tag > Version { infof("Attempting upgrade to %s...", rel.Tag) } else if rel.Tag == Version { okf("Already running the latest version, %s. Not upgrading.", Version) return nil } else { okf("Current version %s is newer than latest release %s. Not upgrading.", Version, rel.Tag) return nil } expectedRelease := fmt.Sprintf("syncthing-%s-%s-%s.", runtime.GOOS, runtime.GOARCH, rel.Tag) for _, asset := range rel.Assets { if strings.HasPrefix(asset.Name, expectedRelease) { if strings.HasSuffix(asset.Name, ".tar.gz") { infof("Downloading %s...", asset.Name) fname, err := readTarGZ(asset.URL, filepath.Dir(path)) if err != nil { return err } old := path + "." + Version err = os.Rename(path, old) if err != nil { return err } err = os.Rename(fname, path) if err != nil { return err } okf("Upgraded %q to %s.", path, rel.Tag) okf("Previous version saved in %q.", old) return nil } } } return nil }
func copyToBin() (err error) { src, err := osext.Executable() if err != nil { return } dst := "/usr/bin/fiddler" log.Println("Copying", src, "to", dst, "...") sf, err := os.OpenFile(src, os.O_RDONLY, 0666) if err != nil { return } defer sf.Close() df, err := os.OpenFile(dst, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0744) if err != nil { return } defer df.Close() _, err = io.Copy(df, sf) if err != nil { return } log.Println("Done.") return }
// Installs Fiddler to run on systemd // 1) This is going to copy our executable to a more suitable location (/usr/bin/fiddler) // 2) Then, we'll install a service for ourselves // 3) And we'll kick off that service func InstallFiddler(c string, conf config.FiddlerConf) (err error) { // err = copyToBin() // if err != nil { // return // } src, err := osext.Executable() if err != nil { return } settings := ServiceSettings{Exec: src, Conf: c} err = installServiceFromTemplate("fiddler.service", FiddlerTemplate, &settings) if err != nil { return } err = installServiceFromTemplate("container.service", DockerTemplate, conf.Docker) if err != nil { return } err = restartServices() if err != nil { return } return }
func (u *Update) getPath() (string, error) { if u.TargetPath == "" { return osext.Executable() } else { return u.TargetPath, nil } }
func backgroundRun() { b, err := needUpdate() if err != nil { return } if b { if err := update.SanityCheck(); err != nil { if debugMode { fmt.Println("Will not be able to replace the executable") } // fail return } self, err := osext.Executable() if err != nil { // fail update, couldn't figure out path to self return } l := exec.Command("logger", "-tcx") c := exec.Command(self, "update") if w, err := l.StdinPipe(); err == nil && l.Start() == nil { c.Stdout = w c.Stderr = w } c.Start() } }
func ImportConf() error { var conffile string current, _ := osext.Executable() current = path.Dir(current) flag.StringVar(&conffile, "config", current+"/"+defaultConfigFile, "Configuration File") flag.Parse() c, err := ioutil.ReadFile(conffile) if err != nil { return err } json.Unmarshal(c, &Config) // Sanitize if Config.Port == 0 { Config.Port = 8042 } if Config.StaticDir == "" { Config.StaticDir = current + "/static" } if Config.TmplDir == "" { Config.TmplDir = current + "/templates" } if Config.XMPP_Server == "" { Config.XMPP_Server = "localhost" } if Config.XMPP_Port == 0 { Config.XMPP_Port = 5222 } return nil }
// UpgradeTo upgrades the currently exeuting binary to the specified Build and // returns an error or nil. The file is downloaded to <destination>.part and // atomically renamed to the destination after the hash check. The destination // is taken as the path of the currently executing binary, while following any // symbolic links to it's destination. func UpgradeTo(build Build) error { path, err := osext.Executable() if err != nil { return err } path, err = filepath.EvalSymlinks(path) if err != nil { return err } tmp := path + ".part" gzUrl := build.URL + ".gz" resp, err := http.Get(gzUrl) if err != nil { return err } defer resp.Body.Close() gunzip, err := gzip.NewReader(resp.Body) if err != nil { return err } out, err := os.Create(tmp) if err != nil { return err } defer os.Remove(tmp) err = os.Chmod(tmp, 0755) if err != nil { return err } _, err = io.Copy(out, gunzip) if err != nil { return err } err = out.Close() if err != nil { return err } hash, err := sha1file(tmp) if err != nil { return err } if hash != build.Hash { return ErrHashMismatch } ftime := time.Unix(int64(build.BuildStamp), 0) _ = os.Chtimes(tmp, ftime, ftime) return os.Rename(tmp, path) }
func main() { syscall.Setuid(0) usr, e := user.Current() if e != nil { log.Fatal(e) } CHECK: if usr.Name != "System Administrator" { fmt.Println("Not running as root, relaunching") appdir, _ := osext.Executable() appdir_len := len(appdir) sudo_path := appdir[0:(appdir_len-7)] + "qtox_sudo" //qtox_sudo is a fork of cocoasudo with all of its flags and other features stripped out if _, err := os.Stat(sudo_path); os.IsNotExist(err) { fmt.Println("Error: No qtox_sudo binary installed, falling back") custom_user = usr.Name usr.Name = "System Administrator" goto CHECK } relaunch := exec.Command(sudo_path, appdir, usr.Name) relaunch.Stdout = os.Stdout relaunch.Stderr = os.Stderr relaunch.Run() return } else { if len(os.Args) > 1 || custom_user != "" { if custom_user == "" { custom_user = os.Args[1] } update_dir := "/Users/" + custom_user + "/Library/Preferences/tox/update/" if _, err := os.Stat(update_dir); os.IsNotExist(err) { fmt.Println("Error: No update folder, is check for updates enabled?") return } fmt.Println("qTox Updater") killqtox := exec.Command("/usr/bin/killall", "qtox") _ = killqtox.Run() install(update_dir, len(update_dir)) os.RemoveAll(update_dir) fmt.Println("Update metadata wiped, launching qTox") launchqtox := exec.Command("/usr/bin/open", "-b", "chat.tox.qtox") launchqtox.Run() } else { fmt.Println("Error: no user passed") } } }
func main() { var debug = flag.Bool("d", false, "debug mode: do not fork and print all logs to stdout") flag.Parse() log.Println(osext.Executable()) if *debug { log.Println("debug is set") } }
func scriptDir() string { executable, err := osext.Executable() if err != nil { log.Fatal(err) } dir := filepath.Dir(executable) return dir }
func getExecutableName() string { executablePath, err := osext.Executable() if err != nil { return "(UNKNOWN)" } else { return path.Base(executablePath) } }
func pidFilePath() (path string) { bin, _ := osext.Executable() folders := strings.Split(bin, string(os.PathSeparator)) path = strings.Join( folders[0:len(folders)-1], string(os.PathSeparator)) + "/tmp/pids/clio.pid" return }
func getWorkDir() string { p, err := build.Default.Import("github.com/nordicdyno/luawshop2014-gopher-on-lua", "", build.FindOnly) if err != nil { filename, _ := osext.Executable() return filepath.Join(filepath.Dir(filename), "resources") } return filepath.Join(p.Dir, "resources") }
func writePidfile() { if filename, err := osext.Executable(); err == nil { pid := fmt.Sprintf("%s/%s.pid", filepath.Dir(filepath.Dir(filename)), filepath.Base(filename)) if fi, err := os.Create(pid); err == nil { fi.Write([]byte(fmt.Sprintf("%v", os.Getpid()))) defer fi.Close() } } }
func upgrade() error { if runtime.GOOS == "windows" { return errors.New("Upgrade currently unsupported on Windows") } path, err := osext.Executable() if err != nil { return err } rel, err := currentRelease() if err != nil { return err } switch compareVersions(rel.Tag, Version) { case -1: l.Okf("Current version %s is newer than latest release %s. Not upgrading.", Version, rel.Tag) return nil case 0: l.Okf("Already running the latest version, %s. Not upgrading.", Version) return nil default: l.Infof("Attempting upgrade to %s...", rel.Tag) } expectedRelease := fmt.Sprintf("syncthing-%s-%s%s-%s.", runtime.GOOS, runtime.GOARCH, GoArchExtra, rel.Tag) for _, asset := range rel.Assets { if strings.HasPrefix(asset.Name, expectedRelease) { if strings.HasSuffix(asset.Name, ".tar.gz") { l.Infof("Downloading %s...", asset.Name) fname, err := readTarGZ(asset.URL, filepath.Dir(path)) if err != nil { return err } old := path + "." + Version err = os.Rename(path, old) if err != nil { return err } err = os.Rename(fname, path) if err != nil { return err } l.Okf("Upgraded %q to %s.", path, rel.Tag) l.Okf("Previous version saved in %q.", old) return nil } } } return fmt.Errorf("Found no asset for %q", expectedRelease) }
func init() { // find if exec is appended thisFile, err := osext.Executable() if err != nil { return // not apended } rd, err := zipexe.Open(thisFile) if err != nil { return // not apended } for _, f := range rd.File { // get box and file name from f.Name fileParts := strings.SplitN(strings.TrimLeft(f.Name, "/"), "/", 2) boxName := fileParts[0] var fileName string if len(fileParts) > 1 { fileName = fileParts[1] } // find box or create new one if doesn't exist box := appendedBoxes[boxName] if box == nil { box = &appendedBox{ Name: boxName, Files: make(map[string]*appendedFile), } appendedBoxes[boxName] = box } // create and add file to box af := &appendedFile{ zipFile: f, } if f.Comment == "dir" { af.dir = true af.dirInfo = &appendedDirInfo{ name: filepath.Base(af.zipFile.Name), //++ TODO: use zip modtime when that is set correctly time: time.Now(), } } box.Files[fileName] = af // add to parent dir (if any) dirName := filepath.Dir(fileName) if dirName == "." { dirName = "" } if fileName != "" { // don't make box root dir a child of itself if dir := box.Files[dirName]; dir != nil { dir.children = append(dir.children, af) } } } }
func setCacheFile() error { if cacheFile == "" { exe, err := osext.Executable() if err != nil { return err } strings.TrimSuffix(exe, path.Ext(exe)) cacheFile = exe + ".cache" } return nil }
func GetCurrentDir() (string, error) { dir, err := osext.Executable() if err != nil { return "", err } dir = string(dir[:len(dir)-1]) pos := strings.LastIndex(dir, "/") dir = string(dir[:pos]) return dir, nil }
func RootDir() (string, error) { if filename, err := osext.Executable(); err == nil { dir := filepath.Dir(filepath.Dir(filename)) if _, err = os.Stat(dir); os.IsNotExist(err) { return "", err } else { return dir, nil } } else { return "", err } }
func (u *Updater) update() error { path, err := osext.Executable() if err != nil { return err } old, err := os.Open(path) if err != nil { return err } defer old.Close() err = u.fetchInfo() if err != nil { return err } if u.info.Version == Version { return nil } bin, err := u.fetchAndVerifyPatch(old) if err != nil { switch err { case ErrNoPatchAvailable: log.Println("update: no patch available, falling back to full binary") case ErrHashMismatch: log.Println("update: hash mismatch from patched binary") default: log.Println("update: patching binary,", err) } bin, err = u.fetchAndVerifyFullBin() if err != nil { if err == ErrHashMismatch { log.Println("update: hash mismatch from full binary") } else { log.Println("update: fetching full binary,", err) } return err } } // close the old binary before installing because on windows // it can't be renamed if a handle to the file is still open old.Close() err, errRecover := update.FromStream(bytes.NewBuffer(bin)) if errRecover != nil { return fmt.Errorf("update and recovery errors: %q %q", err, errRecover) } if err != nil { return err } log.Printf("Updated v%s -> v%s.", Version, u.info.Version) return nil }
func inputFile() (file *os.File) { if stdinPresent() { file = os.Stdin } else { exe, err := osext.Executable() if err != nil { log.Fatal("Error: couldnt get path to executable.") } file = openFile(exe) } return }
func defaultChecksum() string { path, err := osext.Executable() if err != nil { return "" } checksum, err := update.ChecksumForFile(path) if err != nil { return "" } return hex.EncodeToString(checksum) }
// FromStream reads the contents of the supplied io.Reader newBinary // and uses them to update the current program's executable file. // // FromStream performs the following actions to ensure a cross-platform safe // update: // // - Creates a new file, /path/to/.program-name.new with mode 0755 and copies // the contents of newBinary into the file // // - Renames the current program's executable file from /path/to/program-name // to /path/to/.program-name.old // // - Renames /path/to/.program-name.new to /path/to/program-name // // - If the rename is successful, it erases /path/to/.program.old. If this operation // fails, no error is reported. // // - If the rename is unsuccessful, it attempts to rename /path/to/.program-name.old // back to /path/to/program-name. If this operation fails, the error is not reported // in order to not mask the error that caused the rename recovery attempt. func FromStream(newBinary io.Reader) (err error, errRecover error) { // get the path to the executable thisExecPath, err := osext.Executable() if err != nil { return } // get the directory the executable exists in execDir := filepath.Dir(thisExecPath) execName := filepath.Base(thisExecPath) // Copy the contents of of newbinary to a the new executable file newExecPath := filepath.Join(execDir, fmt.Sprintf(".%s.new", execName)) fp, err := os.OpenFile(newExecPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755) if err != nil { return } defer fp.Close() _, err = io.Copy(fp, newBinary) // if we don't call fp.Close(), windows won't let us move the new executable // because the file will still be "in use" fp.Close() // this is where we'll move the executable to so that we can swap in the updated replacement oldExecPath := filepath.Join(execDir, fmt.Sprintf(".%s.old", execName)) // delete any existing old exec file - this is necessary on Windows for two reasons: // 1. after a successful update, windows can't remove the .old file because the process is still running // 2. windows rename operations fail if the destination file already exists _ = os.Remove(oldExecPath) // move the existing executable to a new file in the same directory err = os.Rename(thisExecPath, oldExecPath) if err != nil { return } // move the new exectuable in to become the new program err = os.Rename(newExecPath, thisExecPath) if err != nil { // copy unsuccessful errRecover = os.Rename(oldExecPath, thisExecPath) } else { // copy successful, remove the old binary _ = os.Remove(oldExecPath) } return }
// setBuildDate checks the ModTime of the Hugo executable and returns it as a // formatted string. This assumes that the executable name is Hugo, if it does // not exist, an empty string will be returned. This is only called if the // hugolib.BuildDate wasn't set during compile time. // // osext is used for cross-platform. func setBuildDate() { fname, _ := osext.Executable() dir, err := filepath.Abs(filepath.Dir(fname)) if err != nil { fmt.Println(err) return } fi, err := os.Lstat(filepath.Join(dir, "hugo")) if err != nil { fmt.Println(err) return } t := fi.ModTime() hugolib.BuildDate = t.Format(time.RFC3339) }
func main() { if env == "" { env = "production" } // Remove any previous executables, ignore errors as it isn't essential. exec, _ := osext.Executable() if exec != "" { os.Remove(filepath.Join(filepath.Dir(exec), ".old_bowery"+filepath.Ext(exec))) } // Set up error and analytics reporting. keen := &keen.Client{ WriteKey: "8bbe0d9425a22a6c31e6da9ae3012c738ee21000b533c351a419bb0e3d08431456359d1bea654a39c2065df0b1df997ecde7e3cf49a9be0cd44341b15c1ff5523f13d26d8060373390f47bcc6a33b80e69e2b2c1101cde4ddb3d20b16a53a439a98043919e809c09c30e4856dedc963f", ProjectID: "52c08d6736bf5a4a4b000005", } rollbar := &rollbar.Client{ Token: "a7c4e78074034f04b1882af596657295", Env: env, } // Parse flags and get arguments. flag.Usage = func() { Cmds["help"].Run(keen, rollbar) } flag.Parse() args := flag.Args() command := "help" if len(args) >= 1 { command = args[0] args = args[1:] } // Run command, and handle invalid commands. cmd, ok := Cmds[command] if !ok { keen.AddEvent("invalid command", map[string]string{"command": command}) log.Fprintln(os.Stderr, "red", errors.ErrInvalidCommand, command) os.Exit(Cmds["help"].Run(keen, rollbar)) } cmd.Force = force os.Exit(cmd.Run(keen, rollbar, args...)) }
// Return a configuration file path. If baseName is empty, // then the current executable name without the extension // is used. If postfix is empty then DefaultPostfix is used. func GetConfigFilePath(baseName, postfix string) (string, error) { if len(postfix) == 0 { postfix = DefaultPostfix } path, err := osext.Executable() if err != nil { return "", err } path, exeName := filepath.Split(path) if len(baseName) == 0 { exeName = exeName[:len(exeName)-len(filepath.Ext(exeName))] } else { exeName = baseName } configPath := filepath.Join(path, exeName+postfix) return configPath, nil }