static int newentry(int parent) { int n = findempty(); int sib; if (n < 0) error(EFAIL, "#root. No more"); printd("new entry is %d\n", n); /* add the new one to the head of the linked list. vers is 'next' */ roottab[n].qid.vers = rootdata[parent].child; rootdata[parent].child = n; return n; }
static void filedb_setlink(char *dir, char *fn, char *link) { FILE *f; filedb fdb; long where = 0; f = filedb_open(dir, 0); if (!f) return; if (findmatch(f, fn, &where, &fdb)) { /* change existing one? */ if ((fdb.stat & FILE_DIR) || !(fdb.sharelink[0])) return; if (!link[0]) { /* erasing file */ fdb.stat |= FILE_UNUSED; } else { strncpy(fdb.sharelink, link, 60); fdb.sharelink[60] = 0; } fseek(f, where, SEEK_SET); fwrite(&fdb, sizeof(filedb), 1, f); filedb_close(f); return; } fdb.version = FILEVERSION; fdb.stat = 0; fdb.desc[0] = 0; strcpy(fdb.uploader, botnetnick); strncpy(fdb.filename, fn, 30); fdb.filename[30] = 0; fdb.flags_req[0] = 0; fdb.uploaded = now; fdb.size = 0; fdb.gots = 0; fdb.chname[0] = 0; strncpy(fdb.sharelink, link, 60); fdb.sharelink[60] = 0; where = findempty(f); fseek(f, where, SEEK_SET); fwrite(&fdb, sizeof(filedb), 1, f); filedb_close(f); }
static void filedb_update(char *path, FILE * f, int sort) { struct dirent *dd; DIR *dir; filedb fdb[2]; char name[61]; long where, oldwhere; struct stat st; char s[512]; int ret; /* FIRST: make sure every real file is in the database */ dir = opendir(path); if (dir == NULL) { putlog(LOG_MISC, "*", FILES_NOUPDATE); return; } dd = readdir(dir); while (dd != NULL) { strncpy(name, dd->d_name, 60); name[60] = 0; if (NAMLEN(dd) <= 60) name[NAMLEN(dd)] = 0; else { /* truncate name on disk */ char s1[512], s2[256]; strcpy(s1, path); strcat(s1, "/"); strncat(s1, dd->d_name, NAMLEN(dd)); s1[strlen(path) + NAMLEN(dd) + 1] = 0; sprintf(s2, "%s/%s", path, name); movefile(s1, s2); } if (name[0] != '.') { sprintf(s, "%s/%s", path, name); stat(s, &st); where = 0; ret = findmatch(f, name, &where, &fdb[0]); if (!ret) { /* new file! */ where = findempty(f); fseek(f, where, SEEK_SET); fdb[0].version = FILEVERSION; fdb[0].stat = 0; /* by default, visible regular file */ strcpy(fdb[0].filename, name); fdb[0].desc[0] = 0; strcpy(fdb[0].uploader, botnetnick); fdb[0].gots = 0; fdb[0].flags_req[0] = 0; fdb[0].uploaded = now; fdb[0].size = st.st_size; fdb[0].sharelink[0] = 0; if (S_ISDIR(st.st_mode)) fdb[0].stat |= FILE_DIR; fwrite(&fdb[0], sizeof(filedb), 1, f); } else if (fdb[0].version < FILEVERSION) { /* old version filedb, do the dirty */ if (fdb[0].version == FILEVERSION_OLD) { filedb_old *fdbo = (filedb_old *) & fdb[0]; fdb[0].desc[185] = 0; /* truncate it */ fdb[0].chname[0] = 0; /* new entry */ strcpy(fdb[0].uploader, fdbo->uploader); /* moved forward * a few bytes */ strcpy(fdb[0].flags_req, fdbo->flags_req); /* and again */ fdb[0].version = FILEVERSION; fdb[0].size = st.st_size; fseek(f, where, SEEK_SET); fwrite(&fdb[0], sizeof(filedb), 1, f); } else { putlog(LOG_MISC, "*", "!!! Unknown filedb type !"); } } else { /* update size if needed */ fdb[0].size = st.st_size; fseek(f, where, SEEK_SET); fwrite(&fdb[0], sizeof(filedb), 1, f); } } dd = readdir(dir); } closedir(dir); /* SECOND: make sure every db file is real, and sort as we go, * if we're sorting */ rewind(f); while (!feof(f)) { where = ftell(f); fread(&fdb[0], sizeof(filedb), 1, f); if (!feof(f)) { if (!(fdb[0].stat & FILE_UNUSED) && !fdb[0].sharelink[0]) { sprintf(s, "%s/%s", path, fdb[0].filename); if (stat(s, &st) != 0) { /* gone file */ fseek(f, where, SEEK_SET); fdb[0].stat |= FILE_UNUSED; fwrite(&fdb[0], sizeof(filedb), 1, f); /* sunos and others will puke bloody chunks if you write the * last record in a file and then attempt to read to EOF: */ fseek(f, where, SEEK_SET); continue; /* cycle to next one */ } } if (sort && !(fdb[0].stat & FILE_UNUSED)) { rewind(f); oldwhere = ftell(f); ret = 0; while (!feof(f) && (oldwhere < where)) { fread(&fdb[1 - ret], sizeof(filedb), 1, f); if (!feof(f)) { if ((fdb[0].stat & FILE_UNUSED) || (strcasecmp(fdb[ret].filename, fdb[1 - ret].filename) < 0)) { /* our current is < the checked one, insert here */ fseek(f, oldwhere, SEEK_SET); fwrite(&fdb[ret], sizeof(filedb), 1, f); ret = 1 - ret; /* and fall out */ } /* otherwise read next entry */ oldwhere = ftell(f); } } /* here, either we've found a place to insert, or got to * the end of the list */ /* if we've got to the end of the current list oldwhere == where * so we fall through ret will point to the current valid one */ while (!feof(f) && (oldwhere < where)) { /* need to move this entry up 1 .. */ fread(&fdb[1 - ret], sizeof(filedb), 1, f); oldwhere = ftell(f); /* write lower record here */ fseek(f, oldwhere, SEEK_SET); fwrite(&fdb[ret], sizeof(filedb), 1, f); ret = 1 - ret; } /* when we get here fdb[ret] holds the last record, * which needs to be written where we first grabbed the * record from */ fseek(f, where, SEEK_SET); fwrite(&fdb[ret], sizeof(filedb), 1, f); } } } /* write new timestamp */ filedb_timestamp(f); }