{"id":59,"date":"2003-08-07T04:45:25","date_gmt":"2003-08-06T19:45:25","guid":{"rendered":"http:\/\/openlook.org\/wp\/?p=59"},"modified":"2003-08-07T04:45:25","modified_gmt":"2003-08-06T19:45:25","slug":"cb-461","status":"publish","type":"post","link":"https:\/\/openlook.org\/wp\/cb-461\/","title":{"rendered":"ktrace(1)\ub97c \uc774\uc6a9\ud55c \uc790\ub3d9 plist \uc0dd\uc131"},"content":{"rendered":"<p>\n\ud3ec\ud2b8\ub97c \ub9cc\ub4e4\uac70\ub098 \uc5c5\uae00\ud560 \ub54c \uac00\uc7a5 \uadc0\ucc2e\uc740 \uacfc\uc815 \uc911\uc758 \ud558\ub098\uc778 plist\ub97c \uc790\ub3d9\uc73c\ub85c \ub9cc\ub4dc\ub294 \ubc29\ubc95\uc740 <a class=\"external\" href=\"http:\/\/www.freebsd.org\/cgi\/cvsweb.cgi\/ports\/Tools\/scripts\/plist\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/openlook.org\/images\/moin\/classic\/img\/moin-www.png\" alt=\"[WWW]\" height=\"11\" width=\"11\">mtree\uae30\ubc18\uc73c\ub85c \ub41c \uac83<\/a>\uc774  \uc788\uc5c8\uc9c0\ub9cc, \ubb54\uac00 \ub2e4\ub978 \ud504\ub9ac\ud53d\uc2a4\ub85c \ud55c \ubc88 \uae54\uc544\ubcf4\ub294 \uac8c \ub300\ub7b5 \uadc0\ucc2e\uc740 \uad00\uacc4\ub85c.. <a class=\"interwiki\" title=\"FreeBSDMan\" href=\"http:\/\/www.freebsd.org\/cgi\/man.cgi?query=ktrace\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/openlook.org\/images\/moin\/classic\/img\/moin-inter.png\" alt=\"[FreeBSDMan]\" height=\"16\" width=\"16\">ktrace<\/a> \ub97c \uc774\uc6a9\ud55c \ubc29\ubc95\uc744 \ud55c \ubc88 \uc0dd\uac01\ud574 \ubd24\uc2b5\ub2c8\ub2e4. \ud750\ud750\ud750.. open \uc2dc\uc2a4\ud15c \ucf5c\uc744 \ubaa8\ub450 \ucd94\uc801\ud574\uc11c O_WRONLY\ub098 O_CREAT\ub85c \uc5f4\ub9b0 \ub140\uc11d\ub4e4 \ubaa9\ub85d\uc744 \uc790\ub3d9\uc73c\ub85c plist\ub85c \ub9cc\ub4e4\uc5b4\uc8fc\ub294 \uac83\uc778\ub370, \ub300\ucda9 \ub9cc\ub4e4\uc5b4 \ubcf8 \uc18c\uc2a4\ub294..\n<\/p>\n<pre><pre>  1 \n  2 \n  3 \n  4 \n  5 \n  6 \n  7 \n  8 \n  9 \n 10 \n 11 \n 12 \n 13 \n 14 \n 15 \n 16 \n 17 \n 18 \n 19 \n 20 \n 21 \n 22 \n 23 \n 24 \n 25 \n 26 \n 27 \n 28 \n 29 \n 30 \n 31 \n 32 \n 33 \n 34 \n 35 \n 36 \n 37 \n 38 \n 39 \n 40 \n 41 \n 42 \n 43 \n 44 \n 45 \n 46 \n 47 \n 48 \n 49 \n 50 \n 51 \n 52 \n 53 \n 54 \n 55 \n 56 \n 57 \n 58 \n 59 \n 60 \n 61 \n 62 \n 63 \n 64 \n 65 \n 66 \n 67 \n 68 \n 69 \n 70 \n 71 \n 72 \n 73 \n 74 \n 75 \n 76 \n 77 \n 78 \n 79 \n 80 \n 81 \n 82 \n 83 \n 84 \n 85 \n 86 \n 87 \n 88 \n 89 \n 90 \n 91 \n 92 \n 93 \n 94 \n 95 \n 96 \n 97 \n 98 \n 99 \n100 \n101 \n102 \n103 \n104 \n105 \n106 \n107 \n108 \n109 \n110 \n111 \n112 \n113 \n114 \n115 \n116 \n117 \n118 \n119 \n120 \n121 \n122 \n123 \n124 \n125 \n126 \n127 \n128 \n129 \n130 \n131 \n132 \n133 \n134 \n135 \n136 \n137 \n138 \n139 \n140 \n141 \n142 \n143 \n144 \n145 \n146 \n147 \n148 \n149 \n150 \n151 \n152 \n153 \n154 \n155 \n156 \n157 \n158 \n159 \n160 \n161 \n162 \n163 \n164 \n165 \n166 \n167 \n168 \n169 \n170 \n171 \n172 \n173 \n174 \n175 \n176 \n177 \n178 \n179 \n180 \n181 \n182 \n183 \n184 \n185 \n186 \n187 \n188 \n189 \n<\/pre>\n<pre>#!\/usr\/bin\/env python\n#\n# autoplist.py - Automatic pkg-plist generator based on ktrace\n#\n# ----------------------------------------------------------------------------\n# \"THE BEER-WARE LICENSE\" (Revision 42, (c) Poul-Henning Kamp):\n# Hye-Shik Chang &lt;perky@FreeBSD.org&gt; wrote this file.  As long as you retain\n# this notice you can do whatever you want with this stuff. If we meet some\n# day, and you think this stuff is worth it, you can buy me a beer in return.\n#\n# Hye-Shik Chang\n# ----------------------------------------------------------------------------\n# $FreeBSD$\n\nimport os, random\nimport sys, re\nimport time\n\nrandom.whseed()\nTMPNAM = '.autoplist.%d.%x' % (os.getpid(), random.randrange(65536))\nKTRACECMD = 'ktrace -f %s -id -t cn %%s' % TMPNAM\nKDUMPCMD = 'kdump -f %s' % TMPNAM\nO_WFLAGS = os.O_WRONLY | os.O_RDWR | os.O_CREAT\nPREFIX = '\/usr\/local'\nIGNOREPREFIX = ['\/dev\/', '\/tmp\/']\nPLIST_SUBS = (\n    'PYTHON_INCLUDEDIR', 'PYTHON_LIBDIR', 'PYTHON_SITELIBDIR',\n    'SITE_PERL', 'SITE_RUBY', 'DOCSDIR', 'EXAMPLESDIR', 'DATADIR',\n)\nPLISTREPLACE = []\n\ndef errorexit(msg):\n    print &gt;&gt; sys.stdout, \"autoplist.py:\", msg\n    sys.exit(-1)\n\ndef cleanup_tmpfiles():\n    try:\n        os.unlink(TMPNAM)\n    except:\n        pass\n\ndef getmakeenv(envname):\n    return os.popen('make -V \"%s\"' % envname).read().strip()\n\ndef echo_msg(msg):\n    print '===&gt;  ', msg\n\nclass InstallState:\n\n    procs = {}\n    lastforker = 0\n\n    def __init__(self, pid, procname):\n        self.pid = pid\n        self.procname = procname\n        if not self.lastforker:\n            self.curdir = os.getcwd()\n        else:\n            self.curdir = self.procs[self.lastforker].curdir\n        self.procs[pid] = self\n        self.files, self.dirs = {}, {}\n        self.trackatom = {}\n\n    def feed(self, args):\n        if self.trackatom:\n            if args[2] == 'NAMI':\n                self.trackatom['nami'].append(eval(args[3]))\n            elif args[2] == 'RET':\n                rtok = args[3].split()\n                if rtok[1].isdigit() or rtok[1].startswith('0x'):\n                    self.trackatom['exit'] = eval(rtok[1])\n                else:\n                    self.trackatom['exit'] = rtok[1]\n                if len(rtok) &gt;= 3:\n                    self.trackatom['errno'] = eval(rtok[3])\n                self.newsyscall(**self.trackatom)\n                self.trackatom = {}\n        elif args[2] == 'CALL':\n            syscall, ignore, args = re_syscallargs.findall(args[3])[0]\n            self.trackatom['syscall'] = syscall\n            self.trackatom['args'] = args and args.split(',') or []\n            self.trackatom['nami'] = []\n            if syscall in ('fork', 'vfork', 'rfork'):\n                InstallState.lastforker = self.pid\n\n    def getabspath(self, path):\n        if path.startswith('\/'):\n            return path\n        else:\n            return os.path.realpath(os.sep.join([self.curdir, path]))\n\n    def newsyscall(self, syscall, args, nami, exit, errno=0):\n        if syscall == 'open':\n            if eval(args[1]) &amp; O_WFLAGS:\n                self.files[self.getabspath(nami[0])] = None\n        elif syscall == 'mkdir':\n            self.dirs[self.getabspath(nami[0])] = None\n        elif syscall == 'chdir' and exit == 0:\n            self.curdir = self.getabspath(nami[0])\n        elif syscall in ('execve',) and exit == 0:\n            self.procname = nami[0]\n\ndef filterfilelist(files):\n    filelist = []\n    warnlist = []\n    prefix = PREFIX + os.sep\n    for f in files:\n        for pfx in IGNOREPREFIX:\n            if f.startswith(pfx):\n                continue\n        if f.startswith(prefix):\n            filelist.append(f[len(prefix):])\n            for var, repl in PLISTREPLACE:\n                if filelist[-1].startswith(repl):\n                    filelist[-1] = filelist[-1].replace(repl, '%%'+var+'%%')\n        else:\n            warnlist.append(f)\n    return filelist, warnlist\n\nre_syscallargs = re.compile('([A-Za-z0-9_-]+)(\\(([^)]*)\\))?')\ndef getwfiles():\n    entry = {}\n    istate = InstallState.procs\n    echo_msg('Analyzing installation syscall logs')\n    for l in os.popen(KDUMPCMD):\n        ltok = l[:-1].split(None, 3)\n        pid = int(ltok[0])\n        if not istate.has_key(pid):\n            proc = istate[pid] = InstallState(pid, ltok[1])\n        else:\n            proc = istate[pid]\n        proc.feed(ltok)\n\n    echo_msg('Generating auto plist')\n    fo = open(\"pkg-plist.autogen\", \"w\")\n    print &gt;&gt;fo, \"@comment Generated by autoplist.py\", time.asctime()\n\n    files = {}\n    dirs = {}\n    for pid, data in istate.iteritems():\n        files.update(data.files)\n        dirs.update(data.dirs)\n\n    files = files.keys()\n    files.sort()\n    files, warnfiles = filterfilelist(files)\n    for file in files:\n        print &gt;&gt;fo, file\n\n    dirs = dirs.keys()\n    dirs.sort()\n    dirs.reverse()\n    dirs, warndirs = filterfilelist(dirs)\n    for dir in dirs:\n        print &gt;&gt;fo, \"@dirrm\", dir\n\n    return istate\n\ndef main():\n    try:\n        err = os.system('make build')\n        if err != 0:\n            errorexit(\"`make' exited with error code %d\" % err)\n        err = os.system(KTRACECMD % 'make install')\n        if err != 0:\n            errorexit(\"`make' exited with error code %d\" % err)\n        getwfiles()\n    finally:\n        cleanup_tmpfiles()\n\ndef buildenvironment():\n    global IGNOREPREFIX, PREFIX, PLISTREPLACE\n\n    IGNOREPREFIX.append(os.path.abspath(getmakeenv('WRKDIRPREFIX')))\n    IGNOREPREFIX.append(os.path.abspath(getmakeenv('DISTDIR')))\n    IGNOREPREFIX.append(os.path.abspath(getmakeenv('PKG_DBDIR')))\n    PREFIX = getmakeenv('PREFIX')\n\n    for var, raw, stripped in re.findall('([A-Za-z_0-9]+)=(\"([^\"]*)\"|[^\"]\\S*)',\n                                getmakeenv('PLIST_SUB')):\n        if var in PLIST_SUBS:\n            PLISTREPLACE.append((var, stripped or raw))\n    PLISTREPLACE.sort(lambda x,y: -cmp(x[1], y[1]))\n\nif __name__ == '__main__':\n    buildenvironment()\n    main()\n\n# ex: ts=9 sts=4 sw=4 et<\/pre>\n<\/p>\n<p>\n\ud750\ud750.. \uadf8\ub7f0\ub370, \ub300\ucda9 \ub9cc\ub4e4\uace0 \ub098\uc11c \ubcf4\ub2c8, \uc18d\ub3c4\uac00 \ub108\ubb34 \ub290\ub9ac\uace0 (\uc880\ub9cc \ub300\ud615 \ud3ec\ud2b8\ub85c \uac00\uba74 \uc5c4\uccad\ub09c \uc591\uc758 kdump\uac00 \ub098\uc640\ubc84\ub824\uc11c \uadf8\uac83 \ud30c\uc2f1\ud558\ub294\ub370 \uc2ed\ubd84\uc774 \ub118\uac8c \uac78\ub9bd\ub2c8\ub2e4 &#8211;;) mtree\uae30\ubc18\uc758 \ub140\uc11d\uc5d0\uac8c \ud2b9\ubcc4\ud55c \uc7a5\uc810\uc774 \uc5c6\ub2e4\ub294 \uacb0\ub860\uc774.. \ud750\ud750\ud750&#8230; (\uadf8\ub9ac\uace0, \uc704 \uad6c\ud604\uc5d0\uc11c\ub294 \ub514\ub809\ud1a0\ub9ac\ub97c \uc778\uc2a4\ud1a8 \ub3c4\uc911\uc5d0 mv \ud574 \ubc84\ub9b0\ub2e4\ub358\uc9c0 \ud558\ub294 \uac83\uc5d0 \ub300\ud574\uc11c \ubb34\ubc29\ube44 &#8211;;)\n<\/p>\n<p>\n\uadf8\ub798\uc11c, \uc774 \ub140\uc11d\uc744 \uc880 \ubcc0\ubaa8\uc2dc\ucf1c\uc11c plistlint \uc815\ub3c4\uc758 \uc774\ub984\uc73c\ub85c \uc778\uc2a4\ud1a8\ud558\uba74\uc11c plist\uc5d0 \uc5c6\ub294 \ud504\ub85c\uadf8\ub7a8 \uac74\ub4dc\ub9ac\uc9c0\ub294 \uc54a\ub098, \ube7c\uba39\uc740 \ud30c\uc77c \uc5c6\ub098, \/tmp\uc5d0 \uc774\uc0c1\ud55c \ud30c\uc77c \ub0a8\uae30\uc9c0 \uc54a\ub098 \ub4f1\ub4f1\uc744 \uac80\uc0ac\ud558\ub294 \uac78\ub85c \ub9cc\ub4e4\uc5b4 \ubcfc \uae4c \ud569\ub2c8\ub2f9. \ud06c\ud06c<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\ud3ec\ud2b8\ub97c \ub9cc\ub4e4\uac70\ub098 \uc5c5\uae00\ud560 \ub54c \uac00\uc7a5 \uadc0\ucc2e\uc740 \uacfc\uc815 \uc911\uc758 \ud558\ub098\uc778 plist\ub97c \uc790\ub3d9\uc73c\ub85c \ub9cc\ub4dc\ub294 \ubc29\ubc95\uc740 mtree\uae30\ubc18\uc73c\ub85c \ub41c \uac83\uc774 \uc788\uc5c8\uc9c0\ub9cc, \ubb54\uac00 \ub2e4\ub978 \ud504\ub9ac\ud53d\uc2a4\ub85c \ud55c \ubc88 \uae54\uc544\ubcf4\ub294 \uac8c \ub300\ub7b5 \uadc0\ucc2e\uc740 \uad00\uacc4\ub85c.. ktrace \ub97c \uc774\uc6a9\ud55c \ubc29\ubc95\uc744 \ud55c \ubc88 \uc0dd\uac01\ud574 \ubd24\uc2b5\ub2c8\ub2e4. \ud750\ud750\ud750.. open \uc2dc\uc2a4\ud15c \ucf5c\uc744 \ubaa8\ub450 \ucd94\uc801\ud574\uc11c O_WRONLY\ub098 O_CREAT\ub85c \uc5f4\ub9b0 \ub140\uc11d\ub4e4 \ubaa9\ub85d\uc744 \uc790\ub3d9\uc73c\ub85c plist\ub85c \ub9cc\ub4e4\uc5b4\uc8fc\ub294 \uac83\uc778\ub370, \ub300\ucda9 \ub9cc\ub4e4\uc5b4 \ubcf8 \uc18c\uc2a4\ub294.. 1 &#8230; <a title=\"ktrace(1)\ub97c \uc774\uc6a9\ud55c \uc790\ub3d9 plist \uc0dd\uc131\" class=\"read-more\" href=\"https:\/\/openlook.org\/wp\/cb-461\/\" aria-label=\"Read more about ktrace(1)\ub97c \uc774\uc6a9\ud55c \uc790\ub3d9 plist \uc0dd\uc131\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-59","post","type-post","status-publish","format-standard","hentry","category-freebsd"],"_links":{"self":[{"href":"https:\/\/openlook.org\/wp\/wp-json\/wp\/v2\/posts\/59","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/openlook.org\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/openlook.org\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/openlook.org\/wp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/openlook.org\/wp\/wp-json\/wp\/v2\/comments?post=59"}],"version-history":[{"count":0,"href":"https:\/\/openlook.org\/wp\/wp-json\/wp\/v2\/posts\/59\/revisions"}],"wp:attachment":[{"href":"https:\/\/openlook.org\/wp\/wp-json\/wp\/v2\/media?parent=59"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/openlook.org\/wp\/wp-json\/wp\/v2\/categories?post=59"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/openlook.org\/wp\/wp-json\/wp\/v2\/tags?post=59"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}