{"id":95,"date":"2025-12-03T18:02:17","date_gmt":"2025-12-03T07:02:17","guid":{"rendered":"https:\/\/securelang.net\/cms\/?p=95"},"modified":"2025-12-03T18:47:00","modified_gmt":"2025-12-03T07:47:00","slug":"how-my-audit-process-works","status":"publish","type":"post","link":"https:\/\/securelang.net\/cms\/blog\/2025\/12\/03\/how-my-audit-process-works\/","title":{"rendered":"How My Audit Process Works"},"content":{"rendered":"\n<p>During the build process for the kernel, a program just scans code for markings &#8220;NEW CODE&#8221; or &#8220;OLD CODE&#8221; in each file and prints a report. Obviously this simple method can be adapted to check for more complicated audit requirements e.g. checking that each file has been reviewed within a certain timeframe (the current process just checks which files have been written anew versus which are old code).<\/p>\n\n\n\n<p>Totals are rounded so will usually add up to just under 100%. This is only a simple tool and can be extended later for more thorough audit statistics!<\/p>\n\n\n\n<p>But this is a really powerful tool. You ever written an OS kernel? I&#8217;ve written most of one, but I did it the easy way: One piece at a time.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"752\" height=\"160\" src=\"https:\/\/securelang.net\/cms\/wp-content\/uploads\/2025\/12\/Screenshot-from-2025-12-03-17-55-00.png\" alt=\"\" class=\"wp-image-96\" srcset=\"https:\/\/securelang.net\/cms\/wp-content\/uploads\/2025\/12\/Screenshot-from-2025-12-03-17-55-00.png 752w, https:\/\/securelang.net\/cms\/wp-content\/uploads\/2025\/12\/Screenshot-from-2025-12-03-17-55-00-300x64.png 300w\" sizes=\"auto, (max-width: 752px) 100vw, 752px\" \/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Copyright (c) 2025, Rainbow (Zak) Yani Star Fenton\n\/\/ This \"audit\" program is licensed under the Mulan PSL v2. You can use this\n\/\/ software according to the terms and conditions of the Mulan PSL v2.\n\/\/ You may obtain a copy of Mulan PSL v2 at:\n\/\/ http:\/\/license.coscl.org.cn\/MulanPSL2\n\/\/ THIS SOFTWARE IS PROVIDED ON AN \u201cAS IS\u201d BASIS, WITHOUT warranties of\n\/\/ any kind, either express or implied, including but not limited to\n\/\/ non-infringement, merchantability or fit for a particular purpose.\n\/\/ See the Mulan PSL v2 for more details.\n\n#include &lt;stdlib.h&gt;\n#include &lt;stddef.h&gt;\n#include &lt;stdio.h&gt;\n\n#define AUDIT_TYPE_OLD      1\n#define AUDIT_TYPE_NEW      2\n#define AUDIT_TYPE_UNMARKED 3\n\ntypedef struct audit_info audit_info_t;\ntypedef struct audit_filelist audit_filelist_t;\nstruct audit_filelist {\n  const char* name;\n  audit_filelist_t* next;\n  int type;\n  int lines;\n};\nstruct audit_info {\n  int filecount;\n  int linecount;\n  audit_filelist_t* oldcode;\n  audit_filelist_t* newcode;\n  audit_filelist_t* unmarkedcode;\n};\n\nint audit_filelist_countfiles(audit_filelist_t* l) {\n  int total = 0;\n  while (l) {\n    total++;\n    l = l-&gt;next;\n  }\n  return total;\n}\n\nint audit_filelist_countlines(audit_filelist_t* l) {\n  int total = 0;\n  while (l) {\n    total += l-&gt;lines;\n    l = l-&gt;next;\n  }\n  return total;\n}\n\nint usage(int argc, char** argv, const char* error) {\n  FILE* out = error ? stderr : stdout;\n  fprintf(out, \"ABOUT:\\n\");\n  fprintf(out, \"This is a simple code audit tool to note occurrences like OLD CODE &amp; NEW CODE\\n\");\n  fprintf(out, \"The main purpose of this tool is to help gradually remove old\/third-party code from a codebase,\\n\");\n  fprintf(out, \"but it could be extended later e.g. for checking each file has been manually audited at a recent date.\\n\");\n  fprintf(out, \"This tool isn't specific to a particular programming language and can be used for config files too.\\n\");\n  fprintf(out, \"\\nUSAGE:\\n\");\n  fprintf(out, \"\\t%s &#91;source files...]\\n\", argv&#91;0]);\n  if (error) {\n    fprintf(out, \"ERROR: %s\\n\", error);\n    return -1;\n  } else {\n    return 0;\n  }\n}\n\nint audit_check(const char* line, const char* check) {\n  char c;\n  while ((c = *line++) != 0) {\n    if (c == check&#91;0]) {\n      const char* search = check+1;\n      while (*search &amp;&amp; *search == *line) {\n        line++;\n        search++;\n      }\n      if (!*search) {\n        return 1; \/\/ Found!\n      }\n    }\n  }\n  return 0; \/\/ Not found\n}\n\nvoid audit_line(audit_info_t* info, audit_filelist_t* file, const char* line) {\n  if (audit_check(line, \"OLD CODE\")) {\n    file-&gt;type = AUDIT_TYPE_OLD;\n  } else if (file-&gt;type == AUDIT_TYPE_UNMARKED &amp;&amp; audit_check(line, \"NEW CODE\")) {\n    file-&gt;type = AUDIT_TYPE_NEW;\n  }\n  file-&gt;lines++;\n}\n\nchar linebuf&#91;1000];\n\nint audit_run(audit_info_t* info, const char* filename) {\n  FILE* f = fopen(filename, \"r\");\n  if (!f) {\n    return -1;\n  }\n  audit_filelist_t* filelist = malloc(sizeof(audit_filelist_t));\n  if (!filelist) {\n    fprintf(stderr, \"ERROR: Failed to allocate memory\\n\");\n    fclose(f);\n    return -1;\n  }\n  filelist-&gt;name = strdup(filename);\n  filelist-&gt;type = AUDIT_TYPE_UNMARKED;\n  filelist-&gt;lines = 0;\n  filelist-&gt;next = NULL;\n  \n  while (fgets(linebuf, 1000, f)) {\n    audit_line(info, filelist, linebuf);\n  }\n  \n  switch (filelist-&gt;type) {\n    case AUDIT_TYPE_NEW:\n      filelist-&gt;next = info-&gt;newcode;\n      info-&gt;newcode = filelist;\n      break;\n    case AUDIT_TYPE_OLD:\n      filelist-&gt;next = info-&gt;oldcode;\n      info-&gt;oldcode = filelist;\n      break;\n    default:\n      filelist-&gt;next = info-&gt;unmarkedcode;\n      info-&gt;unmarkedcode = filelist;\n      break;\n  }\n  info-&gt;linecount += filelist-&gt;lines;\n  \n  fclose(f);\n  return 0;\n}\n\nvoid audit_subreport(audit_info_t* info, const char* startline, audit_filelist_t* files, FILE* out, int extrastats) {\n  int nfiles = audit_filelist_countfiles(files);\n  int nlines = audit_filelist_countlines(files);\n  int fpercent = (int) (((double) nfiles) \/ ((double) (info-&gt;filecount)) * 100);\n  int lpercent = (int) (((double) nlines) \/ ((double) (info-&gt;linecount)) * 100);\n  fprintf(out, \"%s %d FILES (%d%%)\\t%d LINES (%d%%)\\n\", startline, nfiles, fpercent, nlines, lpercent);\n  if (!files) {\n    return;\n  }\n  \/\/fprintf(out, \"%s IN \", startline);\n  audit_filelist_t* smallest = files;\n  audit_filelist_t* largest = files;\n  while (files) {\n    \/\/fprintf(out, \" %s\", files-&gt;name);\n    if (files-&gt;lines &lt; smallest-&gt;lines) {\n      smallest = files;\n    } else if (files-&gt;lines &gt; largest-&gt;lines) {\n      largest = files;\n    }\n    files = files-&gt;next;\n  }\n  \/\/fprintf(out, \"\\n\");\n  if (extrastats) {\n    fprintf(out, \"%s SMALLEST %s (%d lines) LARGEST %s (%d lines)\\n\", startline, smallest-&gt;name, smallest-&gt;lines, largest-&gt;name, largest-&gt;lines);\n  }\n}\n\nvoid audit_report(audit_info_t* info, FILE* out) {\n  fprintf(out, \"THIS IS AN AUTOGENERATED REPORT\\n\");\n  fprintf(out, \"This report was created by the 'audit' program\\n\");\n  fprintf(out, \"TOTAL %d FILES %d LINES\\n\", info-&gt;filecount, info-&gt;linecount);\n  audit_subreport(info, \"NEW CODE:     \", info-&gt;newcode, out, 0);\n  audit_subreport(info, \"OLD CODE:     \", info-&gt;oldcode, out, 1);\n  audit_subreport(info, \"UNMARKED CODE:\", info-&gt;unmarkedcode, out, 1);\n}\n\nint main(int argc, char** argv) {\n  audit_info_t info;\n  info.filecount = 0;\n  info.oldcode = NULL;\n  info.newcode = NULL;\n  info.unmarkedcode = NULL;\n  \n  for (int i = 1; i &lt; argc; i++) {\n    if (audit_run(&amp;info, argv&#91;i]) != 0) {\n      fprintf(stderr, \"ERROR: Failed to process file '%s'\\n\", argv&#91;i]);\n      return -1;\n    }\n    info.filecount++;\n  }\n  \n  if (info.filecount &lt; 1) {\n    return usage(argc, argv, \"Expecting list of source files\\n\");\n  } else {\n    audit_report(&amp;info, stdout);\n    return 0;\n  }\n}\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>During the build process for the kernel, a program just scans code for markings &#8220;NEW CODE&#8221; or &#8220;OLD CODE&#8221; in each file and prints a report. Obviously this simple method can be adapted to check for more complicated audit requirements e.g. checking that each file has been reviewed within a certain timeframe (the current process [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"pagelayer_contact_templates":[],"_pagelayer_content":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-95","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/securelang.net\/cms\/wp-json\/wp\/v2\/posts\/95","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/securelang.net\/cms\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/securelang.net\/cms\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/securelang.net\/cms\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/securelang.net\/cms\/wp-json\/wp\/v2\/comments?post=95"}],"version-history":[{"count":6,"href":"https:\/\/securelang.net\/cms\/wp-json\/wp\/v2\/posts\/95\/revisions"}],"predecessor-version":[{"id":105,"href":"https:\/\/securelang.net\/cms\/wp-json\/wp\/v2\/posts\/95\/revisions\/105"}],"wp:attachment":[{"href":"https:\/\/securelang.net\/cms\/wp-json\/wp\/v2\/media?parent=95"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/securelang.net\/cms\/wp-json\/wp\/v2\/categories?post=95"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/securelang.net\/cms\/wp-json\/wp\/v2\/tags?post=95"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}