static int utx_lastlogin_add(const struct futx *fu) { struct futx fe; FILE *fp; int error, ret; ret = 0; /* * Write an entry to lastlogin. Overwrite the entry if the * current user already has an entry. If not, append a new * entry. */ fp = futx_open(_PATH_UTX_LASTLOGIN); if (fp == NULL) return (-1); while (fread(&fe, sizeof fe, 1, fp) == 1) { if (strncmp(fu->fu_user, fe.fu_user, sizeof fe.fu_user) != 0) continue; /* Found a previous lastlogin entry for this user. */ ret = fseeko(fp, -(off_t)sizeof fe, SEEK_CUR); break; } if (ret == -1) error = errno; else if (fwrite(fu, sizeof *fu, 1, fp) < 1) { error = errno; ret = -1; } fclose(fp); errno = error; return (ret); }
static int utx_active_remove(struct futx *fu) { FILE *fp; struct futx fe; int error, ret; /* * Remove user login sessions, having the same ut_id. */ fp = futx_open(_PATH_UTX_ACTIVE); if (fp == NULL) return (-1); error = ESRCH; ret = -1; while (fread(&fe, sizeof(fe), 1, fp) == 1 && ret != 0) switch (fe.fu_type) { case USER_PROCESS: case INIT_PROCESS: case LOGIN_PROCESS: if (memcmp(fu->fu_id, fe.fu_id, sizeof(fe.fu_id)) != 0) continue; /* Terminate session. */ if (fseeko(fp, -(off_t)sizeof(fe), SEEK_CUR) == -1) error = errno; else if (fwrite(fu, sizeof(*fu), 1, fp) < 1) error = errno; else ret = 0; } fclose(fp); if (ret != 0) errno = error; return (ret); }
static int utx_active_add(const struct futx *fu) { FILE *fp; struct futx fe; off_t partial; int error, ret; partial = -1; ret = 0; /* * Register user login sessions. Overwrite entries of sessions * that have already been terminated. */ fp = futx_open(_PATH_UTX_ACTIVE); if (fp == NULL) return (-1); while (fread(&fe, sizeof(fe), 1, fp) == 1) { switch (fe.fu_type) { case BOOT_TIME: /* Leave these intact. */ break; case USER_PROCESS: case INIT_PROCESS: case LOGIN_PROCESS: case DEAD_PROCESS: /* Overwrite when ut_id matches. */ if (memcmp(fu->fu_id, fe.fu_id, sizeof(fe.fu_id)) == 0) { ret = fseeko(fp, -(off_t)sizeof(fe), SEEK_CUR); goto exact; } if (fe.fu_type != DEAD_PROCESS) break; /* FALLTHROUGH */ default: /* Allow us to overwrite unused records. */ if (partial == -1) { partial = ftello(fp); /* * Distinguish errors from valid values so we * don't overwrite good data by accident. */ if (partial != -1) partial -= (off_t)sizeof(fe); } break; } } /* * No exact match found. Use the partial match. If no partial * match was found, just append a new record. */ if (partial != -1) ret = fseeko(fp, partial, SEEK_SET); exact: if (ret == -1) error = errno; else if (fwrite(fu, sizeof(*fu), 1, fp) < 1) error = errno; else error = 0; fclose(fp); errno = error; return (error == 0 ? 0 : 1); }