int dhcp_settag(dhcp_t *dp, int tag, void *data, size_t len) { /* Add a tag to a DHCP packet. No padding. Only do the options field. * (This is Minix, we don't need megabytes of silly bits of data.) * The length may be zero to delete a tag. */ u8_t *p; int n; if (tag <= 0 || tag >= 255) return 0; for (p= dp->options; p < arraylimit(dp->options) && *p != 255; p += n) { n= 1 + 1 + p[1]; if (*p == tag) { /* The tag is already there, remove it so it gets replaced. */ memmove(p, p + n, arraylimit(dp->options) - (p + n)); memset(arraylimit(dp->options) - n, 255, n); n= 0; } } /* Add tag. */ if (len == 0) { /* We're merely deleting a tag. */ } else if (p + 1 + 1 + len <= arraylimit(dp->options)) { *p++ = tag; *p++ = len; memcpy(p, data, len); } else { /* Oops, it didn't fit? Is this really Minix??? */ return 0; } return 1; }
struct group *getgrent(void) /* Read one entry from the group file. */ { char *p; char **mem; /* Open the file if not yet open. */ if (grfd < 0 && setgrent() < 0) return nil; /* Until a good line is read. */ for (;;) { if (!getline()) return nil; /* EOF or corrupt. */ if ((entry.gr_name= scan_punct(':')) == nil) continue; if ((entry.gr_passwd= scan_punct(':')) == nil) continue; if ((p= scan_punct(':')) == nil) continue; entry.gr_gid= strtol(p, nil, 0); entry.gr_mem= mem= members; if (*lineptr != '\n') { do { if ((*mem= scan_punct(',')) == nil) goto again; if (mem < arraylimit(members) - 1) mem++; } while (*lineptr != 0); } *mem= nil; return &entry; again:; } }
void forget(void *mem) /* Some objects must be deleted in time, but not just yet. */ { static void *death_row[2][50]; static void **dp[2]= { death_row[0], death_row[1] }; deallocate(*dp[keep]); *dp[keep]++= mem; if (dp[keep] == arraylimit(death_row[keep])) dp[keep]= death_row[keep]; }
static int getline(void) /* Get one line from the password file, return 0 if bad or EOF. */ { lineptr= pwline; do { if (buflen == 0) { if ((buflen= read(pwfd, buf, sizeof(buf))) <= 0) return 0; bufptr= buf; } if (lineptr == arraylimit(pwline)) return 0; buflen--; } while ((*lineptr++ = *bufptr++) != '\n'); lineptr= pwline; return 1; }
static int getline(void) /* Get one line from the ttytab file, return 0 if bad or EOF. */ { lineptr= ttline; argvptr= ttargv; do { if (buflen == 0) { if ((buflen= read(ttfd, buf, sizeof(buf))) <= 0) return 0; bufptr= buf; } if (lineptr == arraylimit(ttline)) return 0; buflen--; } while ((*lineptr++ = *bufptr++) != '\n'); lineptr= ttline; return 1; }
static char *link_islink(const struct stat *stp, const char *file) { /* Tell if a file, which stat(2) information in '*stp', has been seen * earlier by this function under a different name. If not return a * null pointer with errno set to ENOENT, otherwise return the name of * the link. Return a null pointer with an error code in errno for any * error, using E2BIG for a too long file name. * * Use link_islink(nil, nil) to reset all bookkeeping. * * Call for a file twice to delete it from the store. */ typedef struct link { /* In-memory link store. */ struct link *next; /* Hash chain on inode number. */ ino_t ino; /* File's inode number. */ off_t off; /* Offset to more info in temp file. */ } link_t; typedef struct dlink { /* On-disk link store. */ dev_t dev; /* Device number. */ char file[PATH_MAX]; /* Name of earlier seen link. */ } dlink_t; static link_t *links[256]; /* Hash list of known links. */ static int tfd= -1; /* Temp file for file name storage. */ static dlink_t dlink; link_t *lp, **plp; size_t len; off_t off; if (file == nil) { /* Reset everything. */ for (plp= links; plp < arraylimit(links); plp++) { while ((lp= *plp) != nil) { *plp= lp->next; free(lp); } } if (tfd != -1) close(tfd); tfd= -1; return nil; } /* The file must be a non-directory with more than one link. */ if (S_ISDIR(stp->st_mode) || stp->st_nlink <= 1) { errno= ENOENT; return nil; } plp= &links[stp->st_ino % arraysize(links)]; while ((lp= *plp) != nil) { if (lp->ino == stp->st_ino) { /* May have seen this link before. Get it and check. */ if (lseek(tfd, lp->off, SEEK_SET) == -1) return nil; if (read(tfd, &dlink, sizeof(dlink)) < 0) return nil; /* Only need to check the device number. */ if (dlink.dev == stp->st_dev) { if (strcmp(file, dlink.file) == 0) { /* Called twice. Forget about this link. */ *plp= lp->next; free(lp); errno= ENOENT; return nil; } /* Return the name of the earlier link. */ return dlink.file; } } plp= &lp->next; } /* First time I see this link. Add it to the store. */ if (tfd == -1) { for (;;) { char *tmp; tmp= tmpnam(nil); tfd= open(tmp, O_RDWR|O_CREAT|O_EXCL, 0600); if (tfd < 0) { if (errno != EEXIST) return nil; } else { (void) unlink(tmp); break; } } } if ((len= strlen(file)) >= PATH_MAX) { errno= E2BIG; return nil; } dlink.dev= stp->st_dev; strcpy(dlink.file, file); len += offsetof(dlink_t, file) + 1; if ((off= lseek(tfd, 0, SEEK_END)) == -1) return nil; if (write(tfd, &dlink, len) != len) return nil; if ((lp= malloc(sizeof(*lp))) == nil) return nil; lp->next= nil; lp->ino= stp->st_ino; lp->off= off; *plp= lp; errno= ENOENT; return nil; }