+
+/*
+ * proc_core_name(name, uid, pid)
+ * Expand the name described in corefilename, using name, uid, and pid.
+ * corefilename is a printf-like string, with three format specifiers:
+ * %N name of process ("name")
+ * %P process id (pid)
+ * %U user id (uid)
+ * For example, "%N.core" is the default; they can be disabled completely
+ * by using "/dev/null", or all core files can be stored in "/cores/%U/%N-%P".
+ * This is controlled by the sysctl variable kern.corefile (see above).
+ */
+__private_extern__ char *
+proc_core_name(const char *name, uid_t uid, pid_t pid)
+{
+ const char *format, *appendstr;
+ char *temp;
+ char id_buf[11]; /* Buffer for pid/uid -- max 4B */
+ size_t i, l, n;
+
+ format = corefilename;
+ MALLOC(temp, char *, MAXPATHLEN, M_TEMP, M_NOWAIT | M_ZERO);
+ if (temp == NULL)
+ return (NULL);
+ for (i = 0, n = 0; n < MAXPATHLEN && format[i]; i++) {
+ switch (format[i]) {
+ case '%': /* Format character */
+ i++;
+ switch (format[i]) {
+ case '%':
+ appendstr = "%";
+ break;
+ case 'N': /* process name */
+ appendstr = name;
+ break;
+ case 'P': /* process id */
+ sprintf(id_buf, "%u", pid);
+ appendstr = id_buf;
+ break;
+ case 'U': /* user id */
+ sprintf(id_buf, "%u", uid);
+ appendstr = id_buf;
+ break;
+ default:
+ appendstr = "";
+ log(LOG_ERR,
+ "Unknown format character %c in `%s'\n",
+ format[i], format);
+ }
+ l = strlen(appendstr);
+ if ((n + l) >= MAXPATHLEN)
+ goto toolong;
+ bcopy(appendstr, temp + n, l);
+ n += l;
+ break;
+ default:
+ temp[n++] = format[i];
+ }
+ }
+ if (format[i] != '\0')
+ goto toolong;
+ return (temp);
+toolong:
+ log(LOG_ERR, "pid %ld (%s), uid (%lu): corename is too long\n",
+ (long)pid, name, (u_long)uid);
+ FREE(temp, M_TEMP);
+ return (NULL);
+}