+
+ if (stat(file, &stats) != 0)
+ goto create;
+
+ /* preserve node with already correct numbers, to not change the inode number */
+ if (((stats.st_mode & S_IFMT) == S_IFBLK || (stats.st_mode & S_IFMT) == S_IFCHR) &&
+ (stats.st_rdev == makedev(major, minor))) {
+ dbg("preserve file '%s', cause it has correct dev_t", file);
+ goto perms;
+ }
+
+ if (unlink(file) != 0)
+ dbg("unlink(%s) failed with error '%s'", file, strerror(errno));
+ else
+ dbg("already present file '%s' unlinked", file);
+
+create:
+ retval = mknod(file, mode, makedev(major, minor));
+ if (retval != 0) {
+ dbg("mknod(%s, %#o, %u, %u) failed with error '%s'",
+ file, mode, major, minor, strerror(errno));
+ goto exit;
+ }
+
+perms:
+ dbg("chmod(%s, %#o)", file, mode);
+ if (chmod(file, mode) != 0) {
+ dbg("chmod(%s, %#o) failed with error '%s'", file, mode, strerror(errno));
+ goto exit;
+ }
+
+ if (uid != 0 || gid != 0) {
+ dbg("chown(%s, %u, %u)", file, uid, gid);
+ if (chown(file, uid, gid) != 0) {
+ dbg("chown(%s, %u, %u) failed with error '%s'",
+ file, uid, gid, strerror(errno));
+ goto exit;
+ }
+ }
+
+exit:
+ return retval;
+}
+
+/* get the local logged in user */
+static void set_to_local_user(char *user)
+{
+ struct utmp *u;
+ time_t recent = 0;
+
+ strfieldcpymax(user, default_owner_str, OWNER_SIZE);
+ setutent();
+ while (1) {
+ u = getutent();
+ if (u == NULL)
+ break;
+
+ /* is this a user login ? */
+ if (u->ut_type != USER_PROCESS)
+ continue;
+
+ /* is this a local login ? */
+ if (strcmp(u->ut_host, ""))
+ continue;
+
+ if (u->ut_time > recent) {
+ recent = u->ut_time;
+ strfieldcpymax(user, u->ut_user, OWNER_SIZE);
+ dbg("local user is '%s'", user);
+ break;
+ }
+ }
+ endutent();
+}
+
+static int create_node(struct udevice *dev, int fake)
+{
+ char filename[NAME_SIZE];
+ char linkname[NAME_SIZE];
+ char linktarget[NAME_SIZE];
+ char partitionname[NAME_SIZE];