static int found_other(struct asfd *asfd, FF_PKT *ff_pkt, struct conf *conf, char *fname, bool top_level) { #ifdef HAVE_FREEBSD_OS /* * On FreeBSD, all block devices are character devices, so * to be able to read a raw disk, we need the check for * a character device. * crw-r----- 1 root operator - 116, 0x00040002 Jun 9 19:32 /dev/ad0s3 * crw-r----- 1 root operator - 116, 0x00040002 Jun 9 19:32 /dev/rad0s3 */ if((S_ISBLK(ff_pkt->statp.st_mode) || S_ISCHR(ff_pkt->statp.st_mode)) && need_to_read_blockdev(conf, ff_pkt->fname)) { #else if(S_ISBLK(ff_pkt->statp.st_mode) && need_to_read_blockdev(conf, ff_pkt->fname)) { #endif ff_pkt->type = FT_RAW; /* raw partition */ } else if(S_ISFIFO(ff_pkt->statp.st_mode) && need_to_read_fifo(conf, ff_pkt->fname)) { ff_pkt->type=FT_FIFO; } else { /* The only remaining are special (character, ...) files */ ff_pkt->type=FT_SPEC; } return send_file(asfd, ff_pkt, top_level, conf); } /* * Find a single file. * p is the filename * parent_device is the device we are currently on * top_level is 1 when not recursing or 0 when * descending into a directory. */ static int find_files(struct asfd *asfd, FF_PKT *ff_pkt, struct conf *conf, char *fname, dev_t parent_device, bool top_level) { ff_pkt->fname=fname; ff_pkt->link=fname; #ifdef HAVE_WIN32 if(win32_lstat(fname, &ff_pkt->statp, &ff_pkt->winattr)) #else if(lstat(fname, &ff_pkt->statp)) #endif { ff_pkt->type=FT_NOSTAT; return send_file(asfd, ff_pkt, top_level, conf); } /* * Handle hard linked files * Maintain a list of hard linked files already backed up. This * allows us to ensure that the data of each file gets backed * up only once. */ if(ff_pkt->statp.st_nlink > 1 && (S_ISREG(ff_pkt->statp.st_mode) || S_ISCHR(ff_pkt->statp.st_mode) || S_ISBLK(ff_pkt->statp.st_mode) || S_ISFIFO(ff_pkt->statp.st_mode) || S_ISSOCK(ff_pkt->statp.st_mode))) { struct f_link *lp; const int linkhash_ind=LINKHASH(ff_pkt->statp); /* Search link list of hard linked files */ for(lp=linkhash[linkhash_ind]; lp; lp=lp->next) { if(lp->ino==(ino_t)ff_pkt->statp.st_ino && lp->dev==(dev_t)ff_pkt->statp.st_dev) { if(!strcmp(lp->name, fname)) return 0; ff_pkt->link=lp->name; /* Handle link, file already saved */ ff_pkt->type=FT_LNK_H; return send_file(asfd, ff_pkt, top_level, conf); } } // File not previously dumped. Chain it into our list. if(!(lp=(struct f_link *) malloc_w(sizeof(struct f_link), __func__)) || !(lp->name=strdup_w(fname, __func__))) return -1; lp->ino=ff_pkt->statp.st_ino; lp->dev=ff_pkt->statp.st_dev; lp->next=linkhash[linkhash_ind]; linkhash[linkhash_ind]=lp; } /* This is not a link to a previously dumped file, so dump it. */ if(S_ISREG(ff_pkt->statp.st_mode)) return found_regular_file(asfd, ff_pkt, conf, fname, top_level); else if(S_ISLNK(ff_pkt->statp.st_mode)) { #ifdef S_IFLNK /* A symlink. If they have specified the symlink in a read_blockdev argument, treat it as a block device. */ struct strlist *l; for(l=conf->blockdevs; l; l=l->next) { if(!strcmp(l->path, fname)) { ff_pkt->statp.st_mode ^= S_IFLNK; ff_pkt->statp.st_mode |= S_IFBLK; return found_other(asfd, ff_pkt, conf, fname, top_level); } } #endif return found_soft_link(asfd, ff_pkt, conf, fname, top_level); } else if(S_ISDIR(ff_pkt->statp.st_mode)) return found_directory(asfd, ff_pkt, conf, fname, parent_device, top_level); else return found_other(asfd, ff_pkt, conf, fname, top_level); }
static int found_other(struct asfd *asfd, FF_PKT *ff_pkt, struct conf **confs, char *fname, bool top_level) { #ifdef HAVE_FREEBSD_OS /* * On FreeBSD, all block devices are character devices, so * to be able to read a raw disk, we need the check for * a character device. * crw-r----- 1 root operator - 116, 0x00040002 Jun 9 19:32 /dev/ad0s3 * crw-r----- 1 root operator - 116, 0x00040002 Jun 9 19:32 /dev/rad0s3 */ if((S_ISBLK(ff_pkt->statp.st_mode) || S_ISCHR(ff_pkt->statp.st_mode)) && need_to_read_blockdev(confs, ff_pkt->fname)) { #else if(S_ISBLK(ff_pkt->statp.st_mode) && need_to_read_blockdev(confs, ff_pkt->fname)) { #endif /* raw partition */ ff_pkt->type=FT_RAW; } else if(S_ISFIFO(ff_pkt->statp.st_mode) && need_to_read_fifo(confs, ff_pkt->fname)) { ff_pkt->type=FT_FIFO; } else { /* The only remaining are special (character, ...) files */ ff_pkt->type=FT_SPEC; } return send_file_w(asfd, ff_pkt, top_level, confs); } static int find_files(struct asfd *asfd, FF_PKT *ff_pkt, struct conf **confs, char *fname, dev_t parent_device, bool top_level) { ff_pkt->fname=fname; ff_pkt->link=fname; #ifdef HAVE_WIN32 if(win32_lstat(fname, &ff_pkt->statp, &ff_pkt->winattr)) #else if(lstat(fname, &ff_pkt->statp)) #endif { ff_pkt->type=FT_NOSTAT; return send_file_w(asfd, ff_pkt, top_level, confs); } if(S_ISREG(ff_pkt->statp.st_mode)) return found_regular_file(asfd, ff_pkt, confs, fname, top_level); else if(S_ISLNK(ff_pkt->statp.st_mode)) { #ifdef S_IFLNK /* A symlink. If they have specified the symlink in a read_blockdev argument, treat it as a block device. */ struct strlist *l; for(l=get_strlist(confs[OPT_BLOCKDEVS]); l; l=l->next) { if(!strcmp(l->path, fname)) { ff_pkt->statp.st_mode ^= S_IFLNK; ff_pkt->statp.st_mode |= S_IFBLK; return found_other(asfd, ff_pkt, confs, fname, top_level); } } #endif return found_soft_link(asfd, ff_pkt, confs, fname, top_level); } else if(S_ISDIR(ff_pkt->statp.st_mode)) return found_directory(asfd, ff_pkt, confs, fname, parent_device, top_level); else return found_other(asfd, ff_pkt, confs, fname, top_level); }