コード例 #1
0
ファイル: service_darwin.go プロジェクト: supr/service
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)
}
コード例 #2
0
ファイル: service_windows.go プロジェクト: supr/service
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
}
コード例 #3
0
ファイル: util.go プロジェクト: Joffcom/silver
func exePath() string {
	exePath, err := osext.Executable()
	if err != nil {
		panic(err)
	}
	return exePath
}
コード例 #4
0
ファイル: selfupdate.go プロジェクト: pombredanne/grid-cli
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.")
}
コード例 #5
0
ファイル: upgrade_unix.go プロジェクト: JIVS/syncthing
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
}
コード例 #6
0
ファイル: installer.go プロジェクト: hayesgm/fiddler
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
}
コード例 #7
0
ファイル: installer.go プロジェクト: hayesgm/fiddler
// 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
}
コード例 #8
0
ファイル: update.go プロジェクト: ZhangBanger/go-update
func (u *Update) getPath() (string, error) {
	if u.TargetPath == "" {
		return osext.Executable()
	} else {
		return u.TargetPath, nil
	}
}
コード例 #9
0
ファイル: update.go プロジェクト: noma4i/cx
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()
	}
}
コード例 #10
0
ファイル: config.go プロジェクト: hasantayyar/kiwi
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
}
コード例 #11
0
ファイル: upgrade.go プロジェクト: reth-/mole
// 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)
}
コード例 #12
0
ファイル: updater.go プロジェクト: C3La-NS/qTox-UI
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")
		}

	}
}
コード例 #13
0
ファイル: arguments.go プロジェクト: jvehent/go-toybox
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")
	}
}
コード例 #14
0
func scriptDir() string {
	executable, err := osext.Executable()
	if err != nil {
		log.Fatal(err)
	}
	dir := filepath.Dir(executable)
	return dir
}
コード例 #15
0
ファイル: logger.go プロジェクト: kisom/etcd
func getExecutableName() string {
	executablePath, err := osext.Executable()
	if err != nil {
		return "(UNKNOWN)"
	} else {
		return path.Base(executablePath)
	}
}
コード例 #16
0
ファイル: files.go プロジェクト: kelyar/clio
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
}
コード例 #17
0
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")
}
コード例 #18
0
ファイル: main.go プロジェクト: qjpcpu/watchman
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()
		}
	}
}
コード例 #19
0
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)
}
コード例 #20
0
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)
			}
		}
	}
}
コード例 #21
0
ファイル: cache.go プロジェクト: vogxn/gocs
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
}
コード例 #22
0
ファイル: goqless.go プロジェクト: ngaut/goqless
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
}
コード例 #23
0
ファイル: conf.go プロジェクト: qjpcpu/watchman
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
	}
}
コード例 #24
0
ファイル: update.go プロジェクト: herokai/hk
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
}
コード例 #25
0
ファイル: md5sum.go プロジェクト: xta/go_intro_problems
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
}
コード例 #26
0
ファイル: check.go プロジェクト: bzz/go-update
func defaultChecksum() string {
	path, err := osext.Executable()
	if err != nil {
		return ""
	}

	checksum, err := update.ChecksumForFile(path)
	if err != nil {
		return ""
	}

	return hex.EncodeToString(checksum)
}
コード例 #27
0
ファイル: update.go プロジェクト: BrettBukowski/how
// 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
}
コード例 #28
0
ファイル: version.go プロジェクト: jaden/hugo
// 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)
}
コード例 #29
0
ファイル: bowery.go プロジェクト: Bowery/bowery-cli
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...))
}
コード例 #30
0
ファイル: config.go プロジェクト: ZhuHangpeng/mig
// 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
}