main.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "os/exec"
  6. "log"
  7. "bytes"
  8. "path/filepath"
  9. "strings"
  10. "strconv"
  11. "io"
  12. "io/ioutil"
  13. "hash"
  14. "crypto/sha256"
  15. "crypto/sha512"
  16. "bufio"
  17. "unicode"
  18. "debug/elf"
  19. "text/template"
  20. "gopkg.in/ini.v1"
  21. )
  22. var pkg_env []string
  23. var srcdir string
  24. var pkgdir string
  25. var archive string
  26. var CurDir string
  27. var log_file *os.File
  28. var cfg *ini.File
  29. var build_sections map[string]string
  30. //var source_def map[string]string
  31. type Talimat struct {
  32. // paket
  33. name string
  34. version string
  35. release string
  36. desc string
  37. packager string
  38. group string
  39. url string
  40. srcdir string
  41. tdir string
  42. // build
  43. build string
  44. install string
  45. sources []Source
  46. hashes []Hash
  47. }
  48. type Source struct {
  49. // kaynak
  50. path string
  51. store string
  52. stype string
  53. order string
  54. extract bool
  55. }
  56. type Hash struct {
  57. // hash
  58. htype string
  59. value string
  60. order string
  61. }
  62. func check(e error) {
  63. if e != nil {
  64. panic(e)
  65. }
  66. }
  67. func downloadFile(url string, filepath string) bool {
  68. cmd_check := "curl --head %s"
  69. //HTTP/2 200
  70. // todo: dosya var mı kontrol edilcek net/http ile olabilir
  71. out := process_cmd(fmt.Sprintf(cmd_check,url),true,false,true)
  72. //fmt.Println(out)
  73. if !strings.Contains(out,"404 Not Found") {
  74. cmd_str := "curl --progress-bar -L %s --output %s"
  75. process_cmd(fmt.Sprintf(cmd_str,url,filepath),true,true,false)
  76. return true
  77. } else {
  78. log.Fatal("Dosya bulunamadı:", url)
  79. return false
  80. }
  81. }
  82. func gitClone(url string, filepath string) {
  83. cmd_str := "git clone %s %s"
  84. process_cmd(fmt.Sprintf(cmd_str,url,filepath),true,true,false)
  85. }
  86. func gitPull(filepath string) {
  87. cmd_str := "cd %s ;git pull"
  88. process_cmd(fmt.Sprintf(cmd_str,filepath),true,true,false)
  89. }
  90. func copy_file(src string, dest string) bool {
  91. input, err := ioutil.ReadFile(src)
  92. if err != nil {
  93. fmt.Println(err)
  94. return false
  95. }
  96. err = ioutil.WriteFile(dest, input, 0644)
  97. if err != nil {
  98. fmt.Println("Error creating", dest)
  99. fmt.Println(err)
  100. return false
  101. }
  102. return true
  103. }
  104. func calculate_hash(htype string, file string) string {
  105. f, err := os.Open(file)
  106. if err != nil {
  107. log.Fatal(err)
  108. }
  109. //defer f.Close()
  110. var h hash.Hash
  111. if htype == "sha256" {
  112. h = sha256.New()
  113. } else if htype == "sha512" {
  114. h = sha512.New()
  115. } else {
  116. log.Fatal("tanımsız hash tipi", htype)
  117. }
  118. if _, err := io.Copy(h, f); err != nil {
  119. log.Fatal(err)
  120. }
  121. f.Close()
  122. return fmt.Sprintf("%x", h.Sum(nil))
  123. }
  124. // check for path traversal and correct forward slashes
  125. func validRelPath(p string) bool {
  126. if p == "" || strings.Contains(p, `\`) || strings.HasPrefix(p, "/") || strings.Contains(p, "../") {
  127. return false
  128. }
  129. return true
  130. }
  131. func isDir(path string) bool {
  132. fileInfo, err := os.Stat(path)
  133. if err != nil {
  134. return false
  135. }
  136. return fileInfo.IsDir()
  137. }
  138. func add2env(key string, value string){
  139. pkg_env = append(pkg_env, fmt.Sprintf("%s=%s", key, value))
  140. }
  141. func prepare_pkg_env(pkg *Talimat){
  142. add2env("isim",pkg.name)
  143. add2env("surum",pkg.version)
  144. add2env("devir",pkg.release)
  145. add2env("url",pkg.url)
  146. add2env("SRC_DIR",pkg.srcdir)
  147. add2env("TDIR",pkg.tdir)
  148. }
  149. func prepare_env(){
  150. for _, key := range cfg.Section("export").Keys() {
  151. add2env(key.Name(), cfg.Section("export").Key(key.Name()).String())
  152. }
  153. for _, key := range cfg.Section("source_site").Keys() {
  154. add2env(key.Name(), cfg.Section("source_site").Key(key.Name()).String())
  155. }
  156. }
  157. func create_dirs(){
  158. srcdir = cfg.Section("export").Key("SRC").String() + "/"
  159. pkgdir = cfg.Section("export").Key("PKG").String() + "/"
  160. archive = cfg.Section("export").Key("SOURCES_DIR").String() + "/"
  161. // silinmeli mi?
  162. os.RemoveAll(srcdir)
  163. os.RemoveAll(pkgdir)
  164. os.MkdirAll(srcdir, os.ModePerm)
  165. os.MkdirAll(pkgdir, os.ModePerm)
  166. }
  167. func (pkg Talimat) Print() {
  168. metainfo := fmt.Sprintf(`[paket]
  169. isim=%s
  170. surum=%s
  171. devir=%s
  172. tanim=%s
  173. url=%s
  174. paketci=%s
  175. grup=%s
  176. arsiv=%s
  177. `, pkg.name, pkg.version, pkg.release, pkg.desc, pkg.url, pkg.packager, pkg.group, pkg.srcdir)
  178. fmt.Println(metainfo)
  179. fmt.Println("[kaynak]")
  180. for _, s := range pkg.sources {
  181. fmt.Printf("%s =%s|%s->%s\n", s.order, s.stype, s.path, s.store)
  182. }
  183. fmt.Println("[hash]")
  184. for _, h := range pkg.hashes {
  185. fmt.Printf("%s =%s|%s\n", h.order, h.htype, h.value)
  186. }
  187. fmt.Println("[derle]")
  188. fmt.Println(pkg.build)
  189. fmt.Println("[pakur]")
  190. fmt.Println(pkg.install)
  191. }
  192. func evalsh(expr string) string {
  193. //fmt.Println("evalsh:",expr)
  194. cmd := exec.Command("bash", "-c","echo "+ expr)
  195. cmd.Env = os.Environ()
  196. for _, envar := range pkg_env {
  197. cmd.Env = append(cmd.Env, envar)
  198. }
  199. var outb, errb bytes.Buffer
  200. cmd.Stdout = &outb
  201. cmd.Stderr = &errb
  202. err := cmd.Run()
  203. if err != nil {
  204. log.Fatal(err)
  205. }
  206. //fmt.Println("evalsh:",expr,strings.TrimSuffix(outb.String(), "\n"))
  207. return strings.TrimSuffix(outb.String(), "\n")
  208. }
  209. func process_cmd(cmd_str string, debug bool, logto bool, output bool) string{
  210. // build,install -> true,true,false
  211. // cmd output -> true,false,true
  212. if debug {
  213. cmd_str = "set -x;" + cmd_str
  214. }
  215. cmd := exec.Command("bash","-c",cmd_str)
  216. //cmd := exec.Command("bash", "-c",cmd_str)
  217. cmd.Env = os.Environ()
  218. for _, envar := range pkg_env {
  219. //fmt.Println("envar:",envar)
  220. cmd.Env = append(cmd.Env, evalsh(envar))
  221. }
  222. //for _,x := range cmd.Env {fmt.Println("...",x)}
  223. stdout, err := cmd.StdoutPipe()
  224. check(err)
  225. // hata konsolunu out a eşitleme
  226. cmd.Stderr = cmd.Stdout
  227. //if err != nil { fmt.Println("process_cmd_stdoutpipe:",err) }
  228. err = cmd.Start()
  229. check(err)
  230. //if err != nil { fmt.Println("process_cmd_start:",err) }
  231. if logto {
  232. // print the output of the subprocess stdout and logfile
  233. wlog := bufio.NewWriter(log_file)
  234. log_file.Sync()
  235. scanner := bufio.NewScanner(stdout)
  236. for scanner.Scan() {
  237. m := scanner.Text()
  238. fmt.Println(m)
  239. // log dosyasına da yazılacak.
  240. //n4, err := w.WriteString("buffered\n")
  241. wlog.WriteString(m+"\n")
  242. }
  243. if err := cmd.Wait(); err != nil {
  244. log.Fatal("Çalıştırma betik hatası:", err)
  245. }
  246. wlog.Flush()
  247. return "OK"
  248. }
  249. if output {
  250. outstr := ""
  251. reader := bufio.NewReader(stdout)
  252. line, err := reader.ReadString('\n')
  253. for err == nil {
  254. outstr += line
  255. line, err = reader.ReadString('\n')
  256. }
  257. cmd.Wait()
  258. return outstr
  259. }
  260. return ""
  261. }
  262. func parse_headers(talimat *ini.File, pkg *Talimat) {
  263. talimat_dir := filepath.Base(pkg.tdir)
  264. pkg.name = strings.Split(talimat_dir, "#")[0]
  265. pkg.version = strings.Split(strings.Split(talimat_dir, "#")[1], "-")[0]
  266. pkg.release = strings.Split(strings.Split(talimat_dir, "#")[1], "-")[1]
  267. pkg.desc = talimat.Section("paket").Key("tanim").String()
  268. pkg.packager = talimat.Section("paket").Key("paketci").String()
  269. pkg.group = talimat.Section("paket").Key("grup").String()
  270. pkg.url = talimat.Section("paket").Key("url").String()
  271. pkg.srcdir = talimat.Section("paket").Key("arsiv").String()
  272. if pkg.srcdir == "" {
  273. pkg.srcdir = srcdir+pkg.name+"-"+pkg.version
  274. } else {
  275. pkg.srcdir = srcdir+pkg.srcdir
  276. }
  277. pkg.build = fmt.Sprintf("cd %s\n",pkg.srcdir)
  278. pkg.install = pkg.build
  279. }
  280. func parse_sources(talimat *ini.File, pkg *Talimat) {
  281. s_name := ""
  282. s_url := ""
  283. s_type := "url"
  284. count := 0
  285. var str string
  286. var extract_state bool
  287. for _,k := range talimat.Section("kaynak").Keys() {
  288. for _, v := range k.ValueWithShadows() {
  289. var value bytes.Buffer
  290. //fmt.Println("--",v)
  291. extract_state = true
  292. str = ""
  293. t_str := cfg.Section("source").Key(k.Name()).String()
  294. t := template.Must(template.New("tpl").Parse(t_str))
  295. t.Execute(&value, v)
  296. str = value.String()
  297. if str != "" {
  298. v = str
  299. }
  300. if strings.Contains(v,"!"){
  301. v = strings.Replace(v, "!","",1)
  302. extract_state = false
  303. }
  304. if strings.Contains(v,"::"){
  305. s_url = strings.Split(v, "::")[0]
  306. s_name = strings.Split(v, "::")[1]
  307. s_name = archive + evalsh(s_name)
  308. }
  309. if k.Name() == "git" {
  310. s_type = "git"
  311. }
  312. if k.Name() == "dosya" {
  313. s_url = pkg.tdir +"/"+ evalsh(v)
  314. s_name = srcdir + evalsh(v)
  315. s_type = "file"
  316. }
  317. if s_name == "" {
  318. s_url = evalsh(v)
  319. s_name = s_url[strings.LastIndex(s_url, "/")+1:]
  320. s_name = archive + s_name
  321. }
  322. count += 1
  323. pkg.sources = append(pkg.sources, Source{order: string(count), stype: s_type, path: s_url, store: s_name, extract: extract_state})
  324. s_name, s_url = "",""
  325. s_type = "url"
  326. }
  327. }
  328. fmt.Println("----",pkg.sources)
  329. }
  330. func parse_hashes(talimat *ini.File, pkg *Talimat) {
  331. for _, hashkey := range []string{"sha256","sha512"} {
  332. for _,k := range talimat.Section(hashkey).Keys() {
  333. pkg.hashes = append(pkg.hashes,
  334. Hash{htype: hashkey, order: k.Name(),
  335. value:talimat.Section(hashkey).Key(k.Name()).String()})
  336. }
  337. }
  338. }
  339. func fetch_sources(talimat *ini.File, pkg *Talimat) {
  340. for _, source := range pkg.sources {
  341. //fmt.Println(source.stype +":"+ source.path +"->"+ source.store)
  342. if _, err := os.Stat(source.store); err == nil {
  343. log.Println("dosya zaten var:",source.store)
  344. // git ise pull
  345. if source.stype == "git" {
  346. gitPull(source.store)
  347. // srcdir kopyalama kontrol
  348. if _, err := os.Stat(pkg.srcdir); err != nil {
  349. process_cmd(fmt.Sprintf("cp -r %s %s",source.store, pkg.srcdir),true,true,false)
  350. }
  351. }
  352. continue;
  353. }
  354. if source.stype == "file" {
  355. if copy_file(source.path,source.store) {
  356. log.Println("dosya kopyalama:",source.store)
  357. }
  358. } else if source.stype == "url" {
  359. if !downloadFile(source.path,source.store) {
  360. log.Fatal("dosya indirme hatası:",source.path)
  361. }
  362. //log.Println("dosya kopyalama:",source.store)
  363. } else if source.stype == "git" {
  364. gitClone(source.path,source.store)
  365. log.Println("----------------------")
  366. process_cmd(fmt.Sprintf("cp -r %s %s",source.store, pkg.srcdir),true,true,false)
  367. //log.Fatal("git dizin kopyalama hatası:",source.path)
  368. } else {
  369. log.Fatal("dosya belirsiz indirme tipi:",source.stype)
  370. }
  371. }
  372. }
  373. func check_sources(talimat *ini.File, pkg *Talimat) bool {
  374. log.Println("Dosyaların tutarlılık kontrolü yapılacak.")
  375. nr := 0
  376. file := ""
  377. for _,hash := range pkg.hashes {
  378. nr, _ = strconv.Atoi(hash.order)
  379. file = pkg.sources[nr-1].store
  380. if !isDir(file) {
  381. if hash.value == calculate_hash(hash.htype, file) {
  382. fmt.Println(file,"+")
  383. } else {
  384. log.Fatal(file,"-")
  385. return false
  386. }
  387. } else {
  388. log.Println("Hash kontrol dizin için pas geçildi",file)
  389. }
  390. }
  391. return true
  392. }
  393. func extract_sources(talimat *ini.File, pkg *Talimat) bool {
  394. log.Println("Dosyaların dışarı çıkarması yapılacak.")
  395. for _,source := range pkg.sources {
  396. if source.stype == "file" || source.stype == "git" || !source.extract {continue;}
  397. cmd := fmt.Sprintf("tar xf %s -C %s",source.store,srcdir)
  398. process_cmd(cmd,true,true,false)
  399. }
  400. return true
  401. }
  402. func parse_build(talimat *ini.File, pkg *Talimat, section string) {
  403. body := talimat.Section(section).Body()
  404. for _,line := range strings.Split(body,"\n") {
  405. k := strings.TrimRightFunc(strings.Split(line,"=")[0],unicode.IsSpace)
  406. v := strings.Replace(line,k,"",1)
  407. v = strings.Replace(v,"=","",1)
  408. v = strings.TrimLeftFunc(v, unicode.IsSpace)
  409. var value bytes.Buffer
  410. t_str := cfg.Section(build_sections[section]).Key(k).String()
  411. t := template.Must(template.New("tpl").Parse(t_str))
  412. t.Execute(&value, v)
  413. str := value.String()
  414. for _, sec := range []string{"build_type","install_type"} {
  415. if sec == str {
  416. str = cfg.Section(str).Key(v).String()
  417. }
  418. }
  419. /*
  420. // dosya içerik okuma ile
  421. if strings.Contains(strings.Split(line, "=")[0],"dosya") {
  422. build_file := strings.TrimLeftFunc(strings.TrimRightFunc(strings.Split(line, "=")[1],unicode.IsSpace),unicode.IsSpace)
  423. build_content, _ := ioutil.ReadFile(pkg.tdir+"/"+build_file)
  424. pkg.build += string(build_content) + "\n"
  425. }
  426. */
  427. if build_sections[section] == "build" {
  428. pkg.build += str + "\n"
  429. }
  430. if build_sections[section] == "install" {
  431. pkg.install += str + "\n"
  432. }
  433. }
  434. }
  435. func build_package(pkg *Talimat) {
  436. log.Println("Derleme Başladı")
  437. process_cmd(pkg.build,true,true,false)
  438. log.Println("Derleme Bitti")
  439. }
  440. func install_package(pkg *Talimat) {
  441. log.Println("Paket Kurma Başladı")
  442. process_cmd(pkg.install,true,true,false)
  443. log.Println("Paket Kurma Bitti")
  444. }
  445. func generate_package(pkg *Talimat) {
  446. log.Println("Paket Hazırlama Başladı")
  447. os.Chdir(pkgdir)
  448. pack_t := "%s#%s-%s-%s.mps"
  449. p_archive := fmt.Sprintf(pack_t, pkg.name, pkg.version, pkg.release, "x86_64")
  450. process_cmd(fmt.Sprintf("tar --preserve-permissions -cf %s * .meta .icbilgi",p_archive),true,true,false)
  451. // lzip -9 ${urpkt}.mps
  452. //process_cmd("lzip -9 "+p_archive,true,true,false)
  453. process_cmd("lzip -9 "+p_archive,true,true,false)
  454. // paketi taşı
  455. process_cmd("mv "+p_archive+".lz "+CurDir,true,true,false)
  456. log.Println("Paket Hazırlama Bitti")
  457. }
  458. func generate_package_info(pkg *Talimat) {
  459. log.Println("Paket Bilgisi Üretme Başladı")
  460. os.Chdir(CurDir)
  461. pack_t := "%s#%s-%s-%s.mps.lz"
  462. info_t := "%s %s %s %s %d %s %s"
  463. p_archive := fmt.Sprintf(pack_t, pkg.name, pkg.version, pkg.release, "x86_64")
  464. hash_val := process_cmd("sha256sum "+p_archive,false,false,true)
  465. hash_val = strings.Fields(hash_val)[0]
  466. pack_file, _ := os.Stat(p_archive)
  467. //pack_dir, _ := os.Stat(pkgdir)
  468. size := pack_file.Size()
  469. size_dir := process_cmd("du -sb "+pkgdir,false,false,true)
  470. size_dir = strings.Fields(size_dir)[0]
  471. f, _ := os.Create(p_archive+".bilgi")
  472. defer f.Close()
  473. f.WriteString(fmt.Sprintf(info_t, pkg.name, pkg.version, pkg.release, "x86_64", size, size_dir, hash_val))
  474. // pktlibler, libgerekler
  475. //process_cmd("cp "+pkgdir+"/.meta/libgerekler "+pkg.name+".libgerekler",true,true,false)
  476. //process_cmd("cp "+pkgdir+"/.meta/pktlibler "+pkg.name+".pktlibler",true,true,false)
  477. copy_file(pkgdir+"/.meta/libgerekler",pkg.name+".libgerekler")
  478. copy_file(pkgdir+"/.meta/pktlibler",pkg.name+".pktlibler")
  479. log.Println("Paket Bilgisi Üretme Bitti")
  480. }
  481. func copy_scripts(pkg *Talimat) {
  482. log.Println("Paket Koşuk Kopyalama Başladı")
  483. os.Chdir(pkgdir)
  484. cmd_str := "cp %s %s"
  485. scrpath := ""
  486. for _, script := range []string{"kurkos.sh","koskur.sh","silkos.sh","kossil.sh"} {
  487. // script file exists
  488. scrpath = pkg.tdir+"/"+script
  489. if _, err := os.Stat(scrpath); err == nil {
  490. process_cmd(fmt.Sprintf(cmd_str,scrpath,".meta/."+strings.Split(script,".")[0]),true,true,false)
  491. }
  492. }
  493. log.Println("Paket Koşuk Kopyalama Bitti")
  494. }
  495. func generate_mtree() {
  496. log.Println("Paket İçbilgi Başladı")
  497. os.Chdir(pkgdir)
  498. cmd_str := "bsdtar --preserve-permissions --format=mtree --options='!all,use-set,type,uid,gid,mode,time,size,sha256,link' -czf - * .meta > .icbilgi"
  499. process_cmd(cmd_str,true,true,false)
  500. log.Println("Paket İçbilgi Bitti")
  501. }
  502. func generate_meta(pkg *Talimat) {
  503. log.Println("Paket Meta Başladı")
  504. metadir := pkgdir + "/.meta/"
  505. os.Chdir(pkgdir)
  506. os.MkdirAll(metadir, 0755)
  507. f, err := os.Create(metadir + ".ustbilgi")
  508. check(err)
  509. defer f.Close()
  510. // boyut
  511. //pkgdir_boyut := process_cmd(fmt.Sprintf("du -sb %s",pkgdir),true,false,true)
  512. size_dir := process_cmd("du -sb "+pkgdir,false,false,true)
  513. size_dir = strings.Fields(size_dir)[0]
  514. thash := process_cmd("sha256sum "+pkg.tdir+"/talimat",false,false,true)
  515. thash = strings.Fields(thash)[0]
  516. w := bufio.NewWriter(f)
  517. metainfo := fmt.Sprintf(`isim=%s
  518. surum=%s
  519. devir=%s
  520. tanim=%s
  521. url=%s
  522. paketci=%s
  523. derzaman=1671887877
  524. mimari=x86_64
  525. grup=%s
  526. boyut=%s
  527. thash=%s
  528. `, pkg.name, pkg.version, pkg.release, pkg.desc, pkg.url, pkg.packager, pkg.group, size_dir, thash)
  529. _, err = w.WriteString(metainfo)
  530. check(err)
  531. w.Flush()
  532. log.Println("Paket Meta Bitti")
  533. }
  534. func generate_libs() {
  535. log.Println("Paket Kütüphane Oluşturma Başladı")
  536. os.Chdir(pkgdir)
  537. // pktlibler
  538. var lines []string
  539. lg_out := ""
  540. filepath.Walk("usr/",
  541. func(path string, file os.FileInfo, err error) error {
  542. if err != nil {
  543. return err
  544. }
  545. // dosya işlemleri
  546. if !file.IsDir() {
  547. elft := elf_check(path)
  548. if (elft == 2 || elft == 3) {
  549. if strings.Contains(path,".so.") || path[len(path)-3:] == ".so" {
  550. lines = append(lines,filepath.Base(path))
  551. }
  552. lg_out += process_cmd(fmt.Sprintf("objdump -x %s | grep NEEDED",path),false,false,true)
  553. }
  554. }
  555. return nil
  556. })
  557. if len(lines) > 0 {
  558. file, _ := os.Create(pkgdir + "/.meta/pktlibler")
  559. defer file.Close()
  560. w := bufio.NewWriter(file)
  561. for _, line := range lines {
  562. fmt.Fprintln(w, line)
  563. }
  564. w.Flush()
  565. }
  566. // libgerekler
  567. lg_map := make(map[string]int)
  568. if lg_out != "" {
  569. for _, line := range strings.Split(lg_out,"\n") {
  570. if strings.Contains(line,"NEEDED") {
  571. lg_map[strings.Fields(line)[1]] = 0
  572. }
  573. }
  574. }
  575. file2, _ := os.Create(pkgdir + "/.meta/libgerekler")
  576. defer file2.Close()
  577. w2 := bufio.NewWriter(file2)
  578. for k, _ := range lg_map {
  579. fmt.Fprintln(w2, k)
  580. }
  581. w2.Flush()
  582. log.Println("Paket Kütüphane Oluşturma Bitti")
  583. }
  584. func elf_check(file string) int {
  585. f, err := os.Open(file)
  586. _elf, err := elf.NewFile(f)
  587. if err != nil {
  588. //fmt.Println(file,"not elf")
  589. return -1
  590. }
  591. //defer f.Close()
  592. // Read and decode ELF identifier
  593. var ident [16]uint8
  594. f.ReadAt(ident[0:], 0)
  595. check(err)
  596. f.Close()
  597. if ident[0] != '\x7f' || ident[1] != 'E' || ident[2] != 'L' || ident[3] != 'F' {
  598. fmt.Printf("Bad magic number at %d\n", ident[0:4])
  599. return -1
  600. } else if _elf.Type == 2 {
  601. return 2
  602. } else if _elf.Type == 3 {
  603. return 3
  604. } else {
  605. return -1
  606. }
  607. }
  608. func strip_file(file string) {
  609. ret := elf_check(file)
  610. if ret == 2 {
  611. process_cmd("strip --strip-all "+file,true,true,false)
  612. //fmt.Println(file,"exe stripped")
  613. } else if ret == 3 {
  614. process_cmd("strip --strip-unneeded "+file,true,true,false)
  615. //fmt.Println(file,"shared obj stripped")
  616. } else {
  617. fmt.Println(file,"not stripped")
  618. }
  619. //process_cmd("strip --debug "+file,true,true,false)
  620. }
  621. func compress_manpage(file string) {
  622. if strings.Contains(file, "usr/share/man") {
  623. fmt.Printf("manpages:")
  624. cmd_str := "gzip -9 %s"
  625. cmd_str = fmt.Sprintf(cmd_str, file)
  626. process_cmd(cmd_str,true,true,false)
  627. }
  628. }
  629. func delete_file(file string) {
  630. e := os.RemoveAll(file)
  631. if e == nil {
  632. fmt.Println("deleted:",file)
  633. } else {
  634. log.Println("delete_error",file)
  635. }
  636. }
  637. func IsEmpty(name string) bool {
  638. f, err := os.Open(name)
  639. if err != nil {
  640. return false
  641. }
  642. //defer f.Close()
  643. // https://stackoverflow.com/questions/37804804/too-many-open-file-error-in-golang
  644. _, err = f.Readdirnames(1) // Or f.Readdir(1)
  645. f.Close()
  646. if err == io.EOF {
  647. return true
  648. }
  649. return false
  650. }
  651. func process_files() {
  652. log.Println("Paket Dosya Düzenleme Başladı")
  653. os.Chdir(pkgdir)
  654. log.Println("-geçersiz dizinlerin kontrolü")
  655. name_checks := strings.Split(cfg.Section("files").Key("invalid").String(),",")
  656. for _, fd := range name_checks {
  657. if isDir(fd) {
  658. log.Fatal("geçersiz dizin:",fd)
  659. }
  660. }
  661. log.Println("-gereksiz dizinlerin silinmesi")
  662. delete_files := strings.Split(cfg.Section("files").Key("delete").String(),",")
  663. for _, fd := range delete_files {
  664. if isDir(fd) {
  665. delete_file(fd)
  666. }
  667. }
  668. // builtin silme betiği?
  669. if isDir("usr/lib") {
  670. process_cmd(`find usr/lib -name "*.la" ! -path "usr/lib/ImageMagick*" -exec rm -fv {} \;`,true,true,false)
  671. }
  672. // dosyaların strip
  673. // nostrip dosyası varsa strip pas geçilecek
  674. if _, err := os.Stat(pkgdir + "/nostrip"); err == nil {
  675. log.Println("-ikili ve paylaşımlı kütüphane tırpanı yapılmayacak")
  676. } else {
  677. log.Println("-ikili ve paylaşımlı kütüphane tırpanı")
  678. filepath.Walk(".",
  679. func(path string, file os.FileInfo, err error) error {
  680. if err != nil {
  681. return err
  682. }
  683. // dosya işlemleri
  684. // dşizin ve kısayol değilse
  685. if !file.IsDir() && file.Mode().String()[0:1] != "L" {
  686. //fmt.Println("f----------",file.Mode())
  687. strip_file(path)
  688. }
  689. return nil
  690. })
  691. }
  692. /*
  693. log.Println("-manpages sıkıştırma")
  694. filepath.Walk("usr/share",
  695. func(path string, file os.FileInfo, err error) error {
  696. if err != nil {
  697. return err
  698. }
  699. if !file.IsDir() {
  700. compress_manpage(path)
  701. }
  702. return nil
  703. })
  704. */
  705. /*
  706. log.Println("-boş dizinlerin silinmesi")
  707. filepath.Walk(".",
  708. func(path string, file os.FileInfo, err error) error {
  709. if file.IsDir() {
  710. //fmt.Println("d----------",path)
  711. if IsEmpty(path) {
  712. delete_file(path)
  713. }
  714. }
  715. return nil
  716. })
  717. */
  718. log.Println("Paket Dosya Düzenleme Bitti")
  719. }
  720. func main() {
  721. build_sections = make(map[string]string)
  722. build_sections["derle"]="build"
  723. build_sections["pakur"]="install"
  724. var err error
  725. ini_path := "./mpsd.ini"
  726. if _, err := os.Stat(ini_path); err != nil {
  727. ini_file := "/go/mpsd.ini"
  728. if _, mps_pf := os.LookupEnv("MPS_PATH"); mps_pf {
  729. ini_path = os.Getenv("MPS_PATH") + ini_file
  730. } else {
  731. ini_path = "/usr/milis/mps" + ini_file
  732. }
  733. }
  734. cfg, err = ini.Load(ini_path)
  735. if err != nil {
  736. fmt.Printf("mpsd.ini okunamadı: %v", err)
  737. os.Exit(1)
  738. }
  739. CurDir, _ = os.Getwd()
  740. prepare_env()
  741. create_dirs()
  742. // talimat dizin parametresi - tam yol tespiti
  743. talimat_dir, _ := filepath.Abs(os.Args[1])
  744. // talimat dosya yolu
  745. talimat_file := talimat_dir+"/talimat"
  746. // log ile yolun doğrulanması
  747. log.Println(talimat_dir,"işlenecek")
  748. if _, err := os.Stat(talimat_file); err != nil {
  749. fmt.Printf("talimat dosyası bulunamadı: %v\n", talimat_file)
  750. os.Exit(1)
  751. }
  752. mpsd_mode := "-b"
  753. if len(os.Args) > 2 {
  754. // -i parametresi beklenmekte
  755. // mpsd abc#1.2.3-1 -i
  756. // todo: çoğul mod desteği verilecek
  757. mpsd_mode = os.Args[2]
  758. }
  759. talimat, err := ini.LoadSources(
  760. ini.LoadOptions{
  761. AllowShadows: true,
  762. IgnoreInlineComment: true,
  763. UnparseableSections: []string{"derle","pakur"},
  764. }, talimat_file)
  765. if err != nil {
  766. fmt.Printf("Fail to read file: %v", err)
  767. os.Exit(1)
  768. }
  769. var pkg *Talimat
  770. pkg = new(Talimat)
  771. pkg.tdir = talimat_dir
  772. // ayrıştırma
  773. parse_headers(talimat, pkg)
  774. prepare_pkg_env(pkg)
  775. parse_sources(talimat, pkg)
  776. parse_hashes(talimat, pkg)
  777. parse_build(talimat, pkg,"derle")
  778. parse_build(talimat, pkg,"pakur")
  779. // loglama
  780. log_file, err = os.Create(fmt.Sprintf("%s_%s-%s.log", pkg.name, pkg.version, pkg.release))
  781. check(err)
  782. mw := io.MultiWriter(os.Stdout, log_file)
  783. log.SetOutput(mw)
  784. // yazdırma
  785. pkg.Print()
  786. // talimat işleme
  787. if mpsd_mode == "-b" {
  788. fetch_sources(talimat, pkg)
  789. check_sources(talimat, pkg)
  790. extract_sources(talimat, pkg)
  791. build_package(pkg)
  792. mpsd_mode = "-i"
  793. }
  794. if mpsd_mode == "-i" {
  795. install_package(pkg)
  796. process_files() // strip + manpages + delete
  797. generate_meta(pkg)
  798. copy_scripts(pkg)
  799. generate_mtree()
  800. generate_libs()
  801. generate_package(pkg)
  802. generate_package_info(pkg)
  803. }
  804. }