int compose_compound(F_compound *c) { c->ellipses = NULL; c->lines = NULL; c->texts = NULL; c->splines = NULL; c->arcs = NULL; c->comments = NULL; c->compounds = NULL; /* defer updating of layer buttons until we've composed the entire compound */ defer_update_layers = True; get_ellipse(&c->ellipses); get_line(&c->lines); get_spline(&c->splines); get_text(&c->texts); get_arc(&c->arcs); get_compound(&c->compounds); /* now update the layer buttons */ defer_update_layers = False; update_layers(); if (c->ellipses != NULL) return (1); if (c->splines != NULL) return (1); if (c->lines != NULL) return (1); if (c->texts != NULL) return (1); if (c->arcs != NULL) return (1); if (c->compounds != NULL) return (1); return (0); }
int Graph::get_arc_length(int from, int to) { /* Renvoie la longueur d'un arc donné */ Arc a = get_arc(from, to); return a.length; }
void Graph::invert_arc(int from, int to) { /* inverser. */ int length = get_arc(from, to).length; delete_arc(from, to); add_arc(to, from, length); }
vector<int> Graph::max_distances(int source) { /* *Renvoie la distance maximale de la source à chaque sommet. *L'algorithme est une version modifiée de la procédure de recherche de la distance minimale dans un graph acyclique * Bellman Ford *graphe orienté - modification consiste à transformer les +INF à 0 et min au max. */ int n = vertices_number; vector<int> distance; distance.resize(n); deque<int> topo = topological_sort(); distance[topo[0]] = 0; for (int j=1; j<n; j++) distance[topo[j]] = 0; for (int j=1; j<n; j++) { for (int i=0; i<incoming_arcs[topo[j]].size(); i++) { int a = distance[topo[j]]; int b = distance[incoming_arcs[topo[j]][i].vertex_id]; Arc arc = get_arc(incoming_arcs[topo[j]][i].vertex_id, topo[j]); int c = arc.length; distance[topo[j]] = max(a, b + c); } } debug("max distances from %d to 0..%d respectively:\n", source, n-1); for (int i=0; i<n; i++) debug("%d ", distance[i]); debug("\n"); return distance; }
void list() #endif { register ARCHD *arcn; register int res; ARCHD archd; time_t now; arcn = &archd; /* * figure out archive type; pass any format specific options to the * archive option processing routine; call the format init routine. We * also save current time for ls_list() so we do not make a system * call for each file we need to print. If verbose (vflag) start up * the name and group caches. */ if ((get_arc() < 0) || ((*frmt->options)() < 0) || ((*frmt->st_rd)() < 0)) return; if (vflag && ((uidtb_start() < 0) || (gidtb_start() < 0))) return; now = time((time_t *)NULL); /* * step through the archive until the format says it is done */ while (next_head(arcn) == 0) { /* * check for pattern, and user specified options match. * When all patterns are matched we are done. */ if ((res = pat_match(arcn)) < 0) break; if ((res == 0) && (sel_chk(arcn) == 0)) { /* * pattern resulted in a selected file */ if (pat_sel(arcn) < 0) break; /* * modify the name as requested by the user if name * survives modification, do a listing of the file */ if ((res = mod_name(arcn)) < 0) break; if (res == 0) ls_list(arcn, now); } /* * skip to next archive format header using values calculated * by the format header read routine */ if (rd_skip(arcn->skip + arcn->pad) == 1) break; } /* * all done, let format have a chance to cleanup, and make sure that * the patterns supplied by the user were all matched */ (void)(*frmt->end_rd)(); (void)sigprocmask(SIG_BLOCK, &s_mask, (sigset_t *)NULL); ar_close(); pat_chk(); }
void extract() #endif { register ARCHD *arcn; register int res; off_t cnt; ARCHD archd; struct stat sb; int fd; arcn = &archd; /* * figure out archive type; pass any format specific options to the * archive option processing routine; call the format init routine; * start up the directory modification time and access mode database */ if ((get_arc() < 0) || ((*frmt->options)() < 0) || ((*frmt->st_rd)() < 0) || (dir_start() < 0)) return; /* * When we are doing interactive rename, we store the mapping of names * so we can fix up hard links files later in the archive. */ if (iflag && (name_start() < 0)) return; /* * step through each entry on the archive until the format read routine * says it is done */ while (next_head(arcn) == 0) { /* * check for pattern, and user specified options match. When * all the patterns are matched we are done */ if ((res = pat_match(arcn)) < 0) break; if ((res > 0) || (sel_chk(arcn) != 0)) { /* * file is not selected. skip past any file data and * padding and go back for the next archive member */ (void)rd_skip(arcn->skip + arcn->pad); continue; } /* * with -u or -D only extract when the archive member is newer * than the file with the same name in the file system (nos * test of being the same type is required). * NOTE: this test is done BEFORE name modifications as * specified by pax. this operation can be confusing to the * user who might expect the test to be done on an existing * file AFTER the name mod. In honesty the pax spec is probably * flawed in this respect. */ if ((uflag || Dflag) && ((lstat(arcn->name, &sb) == 0))) { if (uflag && Dflag) { if ((arcn->sb.st_mtime <= sb.st_mtime) && (arcn->sb.st_ctime <= sb.st_ctime)) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } else if (Dflag) { if (arcn->sb.st_ctime <= sb.st_ctime) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } else if (arcn->sb.st_mtime <= sb.st_mtime) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } /* * this archive member is now been selected. modify the name. */ if ((pat_sel(arcn) < 0) || ((res = mod_name(arcn)) < 0)) break; if (res > 0) { /* * a bad name mod, skip and purge name from link table */ purg_lnk(arcn); (void)rd_skip(arcn->skip + arcn->pad); continue; } /* * Non standard -Y and -Z flag. When the exisiting file is * same age or newer skip */ if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0))) { if (Yflag && Zflag) { if ((arcn->sb.st_mtime <= sb.st_mtime) && (arcn->sb.st_ctime <= sb.st_ctime)) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } else if (Yflag) { if (arcn->sb.st_ctime <= sb.st_ctime) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } else if (arcn->sb.st_mtime <= sb.st_mtime) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } if (vflag) { (void)fputs(arcn->name, stderr); vfpart = 1; } /* * all ok, extract this member based on type */ if ((arcn->type != PAX_REG) && (arcn->type != PAX_CTG)) { /* * process archive members that are not regular files. * throw out padding and any data that might follow the * header (as determined by the format). */ if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG)) res = lnk_creat(arcn); else res = node_creat(arcn); (void)rd_skip(arcn->skip + arcn->pad); if (res < 0) purg_lnk(arcn); if (vflag && vfpart) { (void)putc('\n', stderr); vfpart = 0; } continue; } /* * we have a file with data here. If we can not create it, skip * over the data and purge the name from hard link table */ if ((fd = file_creat(arcn)) < 0) { (void)rd_skip(arcn->skip + arcn->pad); purg_lnk(arcn); continue; } /* * extract the file from the archive and skip over padding and * any unprocessed data */ res = (*frmt->rd_data)(arcn, fd, &cnt); file_close(arcn, fd); if (vflag && vfpart) { (void)putc('\n', stderr); vfpart = 0; } if (!res) (void)rd_skip(cnt + arcn->pad); } /* * all done, restore directory modes and times as required; make sure * all patterns supplied by the user were matched; block off signals * to avoid chance for multiple entry into the cleanup code. */ (void)(*frmt->end_rd)(); (void)sigprocmask(SIG_BLOCK, &s_mask, (sigset_t *)NULL); ar_close(); proc_dir(); pat_chk(); }
void list(void) { ARCHD *arcn; int res; ARCHD archd; arcn = &archd; /* * figure out archive type; pass any format specific options to the * archive option processing routine; call the format init routine. We * also save current time for ls_list() so we do not make a system * call for each file we need to print. If verbose (vflag) start up * the name and group caches. */ if ((get_arc() < 0) || ((*frmt->options)() < 0) || ((*frmt->st_rd)() < 0)) return; #if !HAVE_UG_FROM_UGID if (vflag && ((uidtb_start() < 0) || (gidtb_start() < 0))) return; #endif /* * step through the archive until the format says it is done */ while (next_head(arcn) == 0) { if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) { /* * we need to read, to get the real filename */ off_t cnt; if (!(*frmt->rd_data)(arcn, arcn->type == PAX_GLF ? -1 : -2, &cnt)) (void)rd_skip(cnt + arcn->pad); continue; } /* * check for pattern, and user specified options match. * When all patterns are matched we are done. */ if ((res = pat_match(arcn)) < 0) break; if ((res == 0) && (sel_chk(arcn) == 0)) { /* * pattern resulted in a selected file */ if (pat_sel(arcn) < 0) break; /* * modify the name as requested by the user if name * survives modification, do a listing of the file */ if ((res = mod_name(arcn)) < 0) break; if (res == 0) ls_list(arcn, stdout); } /* * skip to next archive format header using values calculated * by the format header read routine */ if (rd_skip(arcn->skip + arcn->pad) == 1) break; } /* * all done, let format have a chance to cleanup, and make sure that * the patterns supplied by the user were all matched */ (void)(*frmt->end_rd)(); (void)sigprocmask(SIG_BLOCK, &s_mask, NULL); ar_close(0); pat_chk(); }
int append(void) { ARCHD *arcn; int res; FSUB *orgfrmt; int udev; off_t tlen; arcn = &archd; orgfrmt = frmt; /* * Do not allow an append operation if the actual archive is of a * different format than the user specified format. */ if (get_arc() < 0) return 1; if ((orgfrmt != NULL) && (orgfrmt != frmt)) { tty_warn(1, "Cannot mix current archive format %s with %s", frmt->name, orgfrmt->name); return 1; } /* * pass the format any options and start up format */ if (((*frmt->options)() < 0) || ((*frmt->st_rd)() < 0)) return 1; /* * if we only are adding members that are newer, we need to save the * mod times for all files we see. */ if (uflag && (ftime_start() < 0)) return 1; /* * some archive formats encode hard links by recording the device and * file serial number (inode) but copy the file anyway (multiple times) * to the archive. When we append, we run the risk that newly added * files may have the same device and inode numbers as those recorded * on the archive but during a previous run. If this happens, when the * archive is extracted we get INCORRECT hard links. We avoid this by * remapping the device numbers so that newly added files will never * use the same device number as one found on the archive. remapping * allows new members to safely have links among themselves. remapping * also avoids problems with file inode (serial number) truncations * when the inode number is larger than storage space in the archive * header. See the remap routines for more details. */ if ((udev = frmt->udev) && (dev_start() < 0)) return 1; /* * reading the archive may take a long time. If verbose tell the user */ if (vflag || Vflag) { (void)fprintf(listf, "%s: Reading archive to position at the end...", argv0); vfpart = 1; } /* * step through the archive until the format says it is done */ while (next_head(arcn) == 0) { /* * check if this file meets user specified options. */ if (sel_chk(arcn) != 0) { if (rd_skip(arcn->skip + arcn->pad) == 1) break; continue; } if (uflag) { /* * see if this is the newest version of this file has * already been seen, if so skip. */ if ((res = chk_ftime(arcn)) < 0) break; if (res > 0) { if (rd_skip(arcn->skip + arcn->pad) == 1) break; continue; } } /* * Store this device number. Device numbers seen during the * read phase of append will cause newly appended files with a * device number seen in the old part of the archive to be * remapped to an unused device number. */ if ((udev && (add_dev(arcn) < 0)) || (rd_skip(arcn->skip + arcn->pad) == 1)) break; } /* * done, finish up read and get the number of bytes to back up so we * can add new members. The format might have used the hard link table, * purge it. */ tlen = (*frmt->end_rd)(); lnk_end(); /* * try to position for write, if this fails quit. if any error occurs, * we will refuse to write */ if (appnd_start(tlen) < 0) return 1; /* * tell the user we are done reading. */ if ((vflag || Vflag) && vfpart) { (void)safe_print("done.\n", listf); vfpart = 0; } /* * go to the writing phase to add the new members */ res = wr_archive(arcn, 1); if (res == 1) { /* * wr_archive failed in some way, but before any files were * added. These are the only steps needed to cleanup (and * not truncate the archive). */ wr_fin(); (void)sigprocmask(SIG_BLOCK, &s_mask, (sigset_t *)NULL); ar_close(); } return res; }
int extract(void) { ARCHD *arcn; int res; off_t cnt; struct stat sb; int fd; time_t now; arcn = &archd; /* * figure out archive type; pass any format specific options to the * archive option processing routine; call the format init routine; * start up the directory modification time and access mode database */ if ((get_arc() < 0) || ((*frmt->options)() < 0) || ((*frmt->st_rd)() < 0) || (dir_start() < 0)) return 1; now = time((time_t *)NULL); #if !HAVE_NBTOOL_CONFIG_H if (do_chroot) (void)fdochroot(cwdfd); #endif /* * When we are doing interactive rename, we store the mapping of names * so we can fix up hard links files later in the archive. */ if (iflag && (name_start() < 0)) return 1; /* * step through each entry on the archive until the format read routine * says it is done */ while (next_head(arcn) == 0) { int write_to_hard_link = 0; if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) { /* * we need to read, to get the real filename */ if (!(*frmt->rd_data)(arcn, -arcn->type, &cnt)) (void)rd_skip(cnt + arcn->pad); continue; } /* * check for pattern, and user specified options match. When * all the patterns are matched we are done */ if ((res = pat_match(arcn)) < 0) break; if ((res > 0) || (sel_chk(arcn) != 0)) { /* * file is not selected. skip past any file * data and padding and go back for the next * archive member */ (void)rd_skip(arcn->skip + arcn->pad); continue; } if (kflag && (lstat(arcn->name, &sb) == 0)) { (void)rd_skip(arcn->skip + arcn->pad); continue; } /* * with -u or -D only extract when the archive member is newer * than the file with the same name in the file system (no * test of being the same type is required). * NOTE: this test is done BEFORE name modifications as * specified by pax. this operation can be confusing to the * user who might expect the test to be done on an existing * file AFTER the name mod. In honesty the pax spec is probably * flawed in this respect. ignore this for GNU long links. */ if ((uflag || Dflag) && ((lstat(arcn->name, &sb) == 0))) { if (uflag && Dflag) { if ((arcn->sb.st_mtime <= sb.st_mtime) && (arcn->sb.st_ctime <= sb.st_ctime)) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } else if (Dflag) { if (arcn->sb.st_ctime <= sb.st_ctime) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } else if (arcn->sb.st_mtime <= sb.st_mtime) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } /* * this archive member is now been selected. modify the name. */ if ((pat_sel(arcn) < 0) || ((res = mod_name(arcn, RENM)) < 0)) break; if (res > 0) { /* * a bad name mod, skip and purge name from link table */ purg_lnk(arcn); (void)rd_skip(arcn->skip + arcn->pad); continue; } if (arcn->name[0] == '/' && !check_Aflag()) { memmove(arcn->name, arcn->name + 1, strlen(arcn->name)); } /* * Non standard -Y and -Z flag. When the existing file is * same age or newer skip; ignore this for GNU long links. */ if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0))) { if (Yflag && Zflag) { if ((arcn->sb.st_mtime <= sb.st_mtime) && (arcn->sb.st_ctime <= sb.st_ctime)) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } else if (Yflag) { if (arcn->sb.st_ctime <= sb.st_ctime) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } else if (arcn->sb.st_mtime <= sb.st_mtime) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } if (vflag) { if (vflag > 1) ls_list(arcn, now, listf); else { (void)safe_print(arcn->name, listf); vfpart = 1; } } /* * if required, chdir around. */ if ((arcn->pat != NULL) && (arcn->pat->chdname != NULL) && !to_stdout) dochdir(arcn->pat->chdname); if (secure && path_check(arcn, 0) != 0) { (void)rd_skip(arcn->skip + arcn->pad); continue; } /* * all ok, extract this member based on type */ if ((arcn->type != PAX_REG) && (arcn->type != PAX_CTG)) { /* * process archive members that are not regular files. * throw out padding and any data that might follow the * header (as determined by the format). */ if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG)) res = lnk_creat(arcn, &write_to_hard_link); else res = node_creat(arcn); if (!write_to_hard_link) { (void)rd_skip(arcn->skip + arcn->pad); if (res < 0) purg_lnk(arcn); if (vflag && vfpart) { (void)putc('\n', listf); vfpart = 0; } continue; } } if (to_stdout) fd = STDOUT_FILENO; else { /* * We have a file with data here. If we cannot create * it, skip over the data and purge the name from hard * link table. */ if ((fd = file_creat(arcn, write_to_hard_link)) < 0) { (void)fflush(listf); (void)rd_skip(arcn->skip + arcn->pad); purg_lnk(arcn); continue; } } /* * extract the file from the archive and skip over padding and * any unprocessed data */ res = (*frmt->rd_data)(arcn, fd, &cnt); if (!to_stdout) file_close(arcn, fd); if (vflag && vfpart) { (void)putc('\n', listf); vfpart = 0; } if (!res) (void)rd_skip(cnt + arcn->pad); /* * if required, chdir around. */ if ((arcn->pat != NULL) && (arcn->pat->chdname != NULL)) fdochdir(cwdfd); } /* * all done, restore directory modes and times as required; make sure * all patterns supplied by the user were matched; block off signals * to avoid chance for multiple entry into the cleanup code. */ (void)(*frmt->end_rd)(); (void)sigprocmask(SIG_BLOCK, &s_mask, (sigset_t *)NULL); ar_close(); proc_dir(); pat_chk(); return 0; }
int list(void) { ARCHD *arcn; int res; time_t now; arcn = &archd; /* * figure out archive type; pass any format specific options to the * archive option processing routine; call the format init routine. We * also save current time for ls_list() so we do not make a system * call for each file we need to print. If verbose (vflag) start up * the name and group caches. */ if ((get_arc() < 0) || ((*frmt->options)() < 0) || ((*frmt->st_rd)() < 0)) return 1; now = time((time_t *)NULL); /* * step through the archive until the format says it is done */ while (next_head(arcn) == 0) { if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) { /* * we need to read, to get the real filename */ off_t cnt; if (!(*frmt->rd_data)(arcn, -arcn->type, &cnt)) (void)rd_skip(cnt + arcn->pad); continue; } /* * check for pattern, and user specified options match. * When all patterns are matched we are done. */ if ((res = pat_match(arcn)) < 0) break; if ((res == 0) && (sel_chk(arcn) == 0)) { /* * pattern resulted in a selected file */ if (pat_sel(arcn) < 0) break; /* * modify the name as requested by the user if name * survives modification, do a listing of the file */ if ((res = mod_name(arcn, RENM)) < 0) break; if (res == 0) { if (arcn->name[0] == '/' && !check_Aflag()) { memmove(arcn->name, arcn->name + 1, strlen(arcn->name)); } ls_list(arcn, now, stdout); } /* * if there's an error writing to stdout then we must * stop now -- we're probably writing to a pipe that * has been closed by the reader. */ if (ferror(stdout)) { syswarn(1, errno, "Listing incomplete."); break; } } /* * skip to next archive format header using values calculated * by the format header read routine */ if (rd_skip(arcn->skip + arcn->pad) == 1) break; } /* * all done, let format have a chance to cleanup, and make sure that * the patterns supplied by the user were all matched */ (void)(*frmt->end_rd)(); (void)sigprocmask(SIG_BLOCK, &s_mask, (sigset_t *)NULL); ar_close(); pat_chk(); return 0; }