ALR

Форк
1
/
osrelease.go 
118 строк · 3.3 Кб
1
/*
2
 * ALR - Any Linux Repository
3
 * Copyright (C) 2024 Евгений Храмов
4
 *
5
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18

19
package distro
20

21
import (
22
	"context"
23
	"os"
24
	"strings"
25

26
	"plemya-x.ru/alr/internal/shutils/handlers"
27
	"mvdan.cc/sh/v3/expand"
28
	"mvdan.cc/sh/v3/interp"
29
	"mvdan.cc/sh/v3/syntax"
30
)
31

32
// OSRelease contains information from an os-release file
33
type OSRelease struct {
34
	Name             string
35
	PrettyName       string
36
	ID               string
37
	Like             []string
38
	VersionID        string
39
	ANSIColor        string
40
	HomeURL          string
41
	DocumentationURL string
42
	SupportURL       string
43
	BugReportURL     string
44
	Logo             string
45
}
46

47
var parsed *OSRelease
48

49
// OSReleaseName returns a struct parsed from the system's os-release
50
// file. It checks /etc/os-release as well as /usr/lib/os-release.
51
// The first time it's called, it'll parse the os-release file.
52
// Subsequent calls will return the same value.
53
func ParseOSRelease(ctx context.Context) (*OSRelease, error) {
54
	if parsed != nil {
55
		return parsed, nil
56
	}
57

58
	fl, err := os.Open("/usr/lib/os-release")
59
	if err != nil {
60
		fl, err = os.Open("/etc/os-release")
61
		if err != nil {
62
			return nil, err
63
		}
64
	}
65

66
	file, err := syntax.NewParser().Parse(fl, "/usr/lib/os-release")
67
	if err != nil {
68
		return nil, err
69
	}
70

71
	fl.Close()
72

73
	// Create new shell interpreter with nop open, exec, readdir, and stat handlers
74
	// as well as no environment variables in order to prevent vulnerabilities
75
	// caused by changing the os-release file.
76
	runner, err := interp.New(
77
		interp.OpenHandler(handlers.NopOpen),
78
		interp.ExecHandler(handlers.NopExec),
79
		interp.ReadDirHandler(handlers.NopReadDir),
80
		interp.StatHandler(handlers.NopStat),
81
		interp.Env(expand.ListEnviron()),
82
	)
83
	if err != nil {
84
		return nil, err
85
	}
86

87
	err = runner.Run(ctx, file)
88
	if err != nil {
89
		return nil, err
90
	}
91

92
	out := &OSRelease{
93
		Name:             runner.Vars["NAME"].Str,
94
		PrettyName:       runner.Vars["PRETTY_NAME"].Str,
95
		ID:               runner.Vars["ID"].Str,
96
		VersionID:        runner.Vars["VERSION_ID"].Str,
97
		ANSIColor:        runner.Vars["ANSI_COLOR"].Str,
98
		HomeURL:          runner.Vars["HOME_URL"].Str,
99
		DocumentationURL: runner.Vars["DOCUMENTATION_URL"].Str,
100
		SupportURL:       runner.Vars["SUPPORT_URL"].Str,
101
		BugReportURL:     runner.Vars["BUG_REPORT_URL"].Str,
102
		Logo:             runner.Vars["LOGO"].Str,
103
	}
104

105
	distroUpdated := false
106
	if distID, ok := os.LookupEnv("ALR_DISTRO"); ok {
107
		out.ID = distID
108
	}
109

110
	if distLike, ok := os.LookupEnv("ALR_DISTRO_LIKE"); ok {
111
		out.Like = strings.Split(distLike, " ")
112
	} else if runner.Vars["ID_LIKE"].IsSet() && !distroUpdated {
113
		out.Like = strings.Split(runner.Vars["ID_LIKE"].Str, " ")
114
	}
115

116
	parsed = out
117
	return out, nil
118
}
119

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.