rfainfo.c
来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 689 行 · 第 1/2 页
C
689 行
rfa->ri_group = strdup(lastgname); else if ((gr = getgrgid (lastgid = st.st_gid)) == NULL) { advise (LLOG_EXCEPTIONS, NULLCP, "Unknown group-id '%d'", lastgid); sprintf(buf, "group-id %d", st.st_gid); rfa->ri_group = strdup(buf); } else { rfa->ri_group = strdup(gr->gr_name); strcpy(lastgname, gr->gr_name); } /*--- read symbolic links ---*/ if ((rfa->ri_mode & S_IFMT) == S_IFLNK) { if ((rc = readlink(fn, lnkbuf, sizeof lnkbuf)) == -1) sprintf(lnkbuf, "(error reading link)"); else lnkbuf[rc] = '\0'; rfa->ri_lnkName = strdup(lnkbuf); } return OK;}/*------------------------------------------------------ * getRfaInfo - read RFA file info from ".rfainfo" *------------------------------------------------------*/static int getRfaInfo(dirname, f, rfap) char *dirname; FILE *f; struct RfaInfo **rfap;{ register char *s, *d; char buf[BUFSIZ]; char line[BUFSIZ]; int rc = 1; struct RfaInfo *rfa; advise(LLOG_DEBUG,NULLCP,"getRfaInfo: %s",dirname); if (f == NULL) return OK; while (fgets(line, sizeof(line), f)) { s = line; while (isspace(*s)) s++; for(d = buf; ! isspace(*s); s++, d++) *d = *s; *d = '\0'; if ((rfa = findRfaInfo(buf, *rfap)) == NULL) continue; while (isspace(*s)) s++; for(d = buf; ! isspace(*s); s++, d++) *d = *s; *d = '\0'; if ((rc = str2status(buf)) == NOTOK) { sprintf(rfaErrStr, "invalid status in '%s/.rfainfo'",dirname); advise(LLOG_EXCEPTIONS,NULLCP,rfaErrStr); continue; } rfa->ri_status = rc; while (isspace(*s)) s++; for(d = buf; ! isspace(*s); s++, d++) *d = *s; *d = '\0'; rfa->ri_lastChange = (time_t)atol(buf); while (isspace(*s)) s++; for(d = buf; ! isspace(*s); s++, d++) *d = *s; *d = '\0'; if (strcmp(buf, "NONE")) rfa->ri_lckname = strdup(buf); else rfa->ri_lckname = NULL; while (isspace(*s)) s++; for(d = buf; ! isspace(*s); s++, d++) *d = *s; *d = '\0'; rfa->ri_lcksince = (time_t)atol(buf); } /*-- while fgets --*/ return OK;}/*------------------------------------------------------ * getRfaInfoList - get file info list for "dir" *------------------------------------------------------*/int getRfaInfoList(dir, rfaHeadp, target, locked) char *dir; struct RfaInfo **rfaHeadp; char *target; int locked;{ struct RfaInfo *rfalist = NULL, **rfap = & rfalist; DIR *dirp; struct dirent *dp; struct stat st; int rc; char *rfa_fn; FILE *rfa_fp; struct LockEntry *le; advise (LLOG_DEBUG, NULLCP, "getRfaInfoList: '%s', target '%s'", dir, target); /*--- find out if directory --*/ if (stat(makeFN(dir),&st) == -1) { advise (LLOG_EXCEPTIONS, NULLCP, "cant stat '%s':%s", dir, sys_errname(errno)); sprintf(rfaErrStr, "%s - %s", dir, sys_errname(errno)); return NOTOK; } /*-- get rfainfo --*/ if (st.st_mode & S_IFDIR) rfa_fn = dir; else rfa_fn = dirname(dir); if (rfa_fp = fopen(makeFN2(rfa_fn,".rfainfo"),locked ? "a+":"r")) rewind(rfa_fp); else if (errno != ENOENT) { sprintf(rfaErrStr, "%s/.rfainfo (%s)", rfa_fn, sys_errname(errno)); advise(LLOG_EXCEPTIONS, NULLCP, "cant open '%s/.rfainfo' - %s", rfa_fn, sys_errname(errno)); return NOTOK_SYS; } if (locked) if ((le = lockRfainfo(rfa_fn, rfa_fp)) == NULL) { fclose(rfa_fp); return NOTOK; } if (st.st_mode & S_IFDIR) { /*--- dir is a directory name, so open dir ---*/ if ((dirp = opendir(makeFN(dir))) == NULL) { sprintf(rfaErrStr, "%s - %s", dir, sys_errname(errno)); advise(LLOG_EXCEPTIONS, NULLCP, "can't open dir '%s' - %s", dir, sys_errname(errno)); rc = NOTOK; goto err_cleanup; } for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { if (((*rfap) = mallocRfaInfo(strdup(dp->d_name))) == NULL) { freeRfaInfoList(rfalist); sprintf(rfaErrStr, "out of memory"); advise(LLOG_EXCEPTIONS, NULLCP, rfaErrStr); rc = NOTOK; goto err_cleanup; } SET_STATUS((*rfap)->ri_status, RI_UNREGISTERED); SET_LOCKINFO((*rfap)->ri_status, RI_UNLOCKED); SET_TRANSFER((*rfap)->ri_status, RI_TR_REQ); if ((target == NULL ) || (strcmp(target, dp->d_name) == 0)) { if ((rc = statFile(makeFN2(dir, dp->d_name), *rfap)) != OK) { freeRfaInfoList(rfalist); goto err_cleanup; } } rfap = &((*rfap)->ri_next); } closedir(dirp); if ((rc = getRfaInfo(dir, rfa_fp, &rfalist)) != OK) { freeRfaInfoList(rfalist); goto err_cleanup; } } else { /*--- dir is a single file ---*/ if (((*rfap) = mallocRfaInfo(strdup(basename(dir)))) == NULL) { freeRfaInfoList(rfalist); sprintf(rfaErrStr, "out of memory"); advise(LLOG_EXCEPTIONS, NULLCP, rfaErrStr); rc = NOTOK; goto err_cleanup; } SET_STATUS((*rfap)->ri_status, RI_UNREGISTERED); SET_LOCKINFO((*rfap)->ri_status, RI_UNLOCKED); SET_TRANSFER((*rfap)->ri_status, RI_TR_REQ); if ((rc = statFile(makeFN(dir), *rfap)) != OK) { freeRfaInfoList(rfalist); goto err_cleanup; } /*--- get locking info ---*/ if ((rc = getRfaInfo(dirname(dir), rfa_fp, &rfalist)) != OK) { freeRfaInfoList(rfalist); goto err_cleanup; } } *rfaHeadp = rfalist; if (!locked && rfa_fp) fclose(rfa_fp); return OK;err_cleanup:; if (locked) closeAndUnlockRfainfo(rfa_fn); else if (rfa_fp) fclose(rfa_fp); return rc;}/*------------------------------------------------------ * putRfaInfoList - write RFA file info list to ".rfainfo" *------------------------------------------------------*/int putRfaInfoList(dirname, rfa) char *dirname; struct RfaInfo *rfa;{ FILE *backup_f; char buf[BUFSIZ]; struct LockEntry *le; int num; advise(LLOG_DEBUG,NULLCP,"putRfaInfo %s", makeFN(dirname)); for (le = lockList; le; le = le->le_next) if (strcmp(le->le_fn, dirname) == 0) break; if (le == NULL) { sprintf(rfaErrStr, "can't write %s/.rfainfo (not locked)", dirname); advise(LLOG_EXCEPTIONS,NULLCP,rfaErrStr); return NOTOK; } if (backup_f = fopen(makeFN2(dirname, ".rfainfo.bak"), "w")) { rewind(le->le_filep); while (num = fread(buf, 1, BUFSIZ, le->le_filep)) fwrite(buf, 1, num, backup_f); fclose(backup_f); } rewind(le->le_filep); for (; rfa; rfa = rfa->ri_next) { if (rfa->ri_mode && (rfa->ri_mode & S_IFMT & (S_IFREG | S_IFDIR)) == 0) continue; if (fprintf(le->le_filep, "%s %s %ld %s %ld\n", rfa->ri_filename, status2str(rfa->ri_status), rfa->ri_lastChange, rfa->ri_lckname ? rfa->ri_lckname : "NONE", rfa->ri_lcksince) == EOF) { sprintf(rfaErrStr, "can't write %s/.rfainfo (%s)", dirname, sys_errname(errno)); (void)advise(LLOG_EXCEPTIONS,NULLCP,rfaErrStr); unlink(makeFN2(dirname, ".rfainfo")); strcpy(buf, makeFN2(dirname,".rfainfo.bak")); rename (buf, makeFN2(dirname,".rfainfo")); return NOTOK; } } fflush(le->le_filep); return OK;}/*------------------------------------------------------ * extractRfaInfo - extract RFA file info by filename *------------------------------------------------------*/struct RfaInfo *extractRfaInfo(fn, rfap) char *fn; struct RfaInfo **rfap;{ struct RfaInfo *h; for (; *rfap; rfap = &((*rfap)->ri_next)) if (strcmp(fn, (*rfap)->ri_filename) == 0) { h = *rfap; *rfap = h->ri_next; h->ri_next = NULL; return h; } return NULL;}/*------------------------------------------------------ * remRfaInfo - remove RFA file info from list *------------------------------------------------------*/void remRfaInfo (fn, rfap) char *fn; struct RfaInfo **rfap;{ struct RfaInfo *h; if ((h = extractRfaInfo(fn, rfap))) { h->ri_next = NULL; freeRfaInfoList(h); }} /*------------------------------------------------------ * findRfaInfo - find RFA file info by filename *------------------------------------------------------*/struct RfaInfo *findRfaInfo(fn, rfa) char *fn; register struct RfaInfo *rfa;{ for (; rfa; rfa = rfa->ri_next) if (strcmp(fn, rfa->ri_filename) == 0) return rfa; return NULL;}/*------------------------------------------------------ * sortRfaInfoList - sort RFA list *------------------------------------------------------*/void sortRfaInfoList(rfap) struct RfaInfo **rfap;{ struct RfaInfo *tnext, *tosort, *sorted, **spp; sorted = NULL; for (tosort = *rfap; tosort; tosort = tnext) { tnext = tosort->ri_next; for (spp = &sorted; *spp ; spp = &((*spp)->ri_next)) if (strcmp((*spp)->ri_filename, tosort->ri_filename) > 0) break; tosort->ri_next = *spp; *spp = tosort; } *rfap = sorted;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?