/* 该函数用于安全的打开文件 2013-12-09 16:15 */ FILE * fileio::safeopen(const char *fname, const char *status) { TYPE_FILENAME cfn = gloab::g_filepoint.getfilename(); TYPE_FILENAME fn = fname; FILE *fp; fp = inopen(fname, status); if(!fp && !isabspath(fname) && cfn != ""){ strprocess::killfbspace(cfn); TYPE_FILENAME pp = getparent(cfn); if(pp != ""){ fn = pp+fname; fp = inopen(fn, status); } } if(fp){ // gloab::g_filepoint.set(fn); return fp; } errorprocess::showerr(ERR_HAVANO_FILE, fname); return NULL; }
inline FILE * inopen(TYPE_FILENAME fn, const char *status) { return inopen(fn.c_str(), status); }
/* **************************************************************** * Substitui um módulo na biblioteca * **************************************************************** */ int mod_replace (MOD *mp, STAT *sp, HEADER *hp, int cmd_nm) { int fd, modif = 0; const char *mod_nm; SYM *sym_tb; MOD *new_mp; SYMTB *zp, *new_zp; SYMTB **link_point; /* * Abre o arquivo (novo), já na biblioteca */ mod_nm = /*** last_nm ***/ mp->m_mod_nm; if ((fd = inopen (sp->st_dev, sp->st_ino)) < 0) { error ("*Não consegui abrir \"%s\"", mod_nm); return (-1); } /* * Aloca memória e le a tabela de símbolos */ sym_tb = alloca (hp->h_ssize); lseek (fd, sizeof (HEADER) + hp->h_tsize + hp->h_dsize, L_SET); if (hp->h_ssize && read (fd, sym_tb, hp->h_ssize) != hp->h_ssize) { error ("*Erro na leitura da tabela de símbolos de \"%s\"", mod_nm); close (fd); return (-1); } close (fd); /* * Processa a tabela de símbolos do novo módulo */ new_mp = alloca (sizeof (MOD)); mk_mod_sym ( mod_nm, new_mp, sym_tb, (SYM *)((int)sym_tb + hp->h_ssize), 0 /* HASHOFF */ ); /* * Confere os tamanhos e símbolos */ if (new_mp->m_n_sym != mp->m_n_sym) { modif++; } else { sort_mod_sym (new_mp); for ( zp = mp->m_sym, new_zp = new_mp->m_sym; zp != NOSYMTB; zp = zp->z_sym_next, new_zp = new_zp->z_sym_next ) { if (strcmp (zp->z_sym_nm, new_zp->z_sym_nm)) { modif++; break; } } } if (vflag) printf ("%c - %s\n", cmd_nm, mod_nm); if (modif == 0) return (0); /* * Atualiza LIBSYM */ for (new_zp = new_mp->m_sym; new_zp != NOSYMTB; new_zp = new_zp->z_sym_next) { if ((zp = hash (new_zp->z_sym_nm, new_zp->z_sym_len, &link_point)) != NOSYMTB) { if (zp->z_mod != mp) { error ( "Símbolo \"%s\" duplicado: \"%s\" :: \"%s\"", zp->z_sym_nm, mod_nm, zp->z_mod->m_mod_nm ); } } else { *link_point = new_zp; new_zp->z_link = NOSYMTB; } } /*** mp->m_mod_nm = ...; ***/ /*** mp->m_ino = ...; ***/ mp->m_sym = new_mp->m_sym; mp->m_n_sym = new_mp->m_n_sym; /*** mp->m_next = ...; ***/ return (1); } /* end mod_replace */
/* **************************************************************** * Programa principal * **************************************************************** */ int main (int argc, const char *argv[]) { XStandardColormap stdcmap, *cmp; Display *dpy = NULL; Window root, win; XGCValues gcv; int depth; FILE *fp; XImage *ximage = NULL; IMAGE *last_image, *ip, *old_ip; int nimages, times; const char *display = NOSTR; int time_interval = 0; int opt, exit_val = 0; int Nflag = 0; Atom map; KeySym key; save_argc = argc; save_argv = argv; /* * Analisa as opções de execução. */ while ((opt = getopt (argc, argv, "d:f:HMNRs:v")) != EOF) { switch (opt) { case 'd': display = optarg; break; case 'f': if (strchr (optarg, '/') != NOSTR) { int num, den; sscanf (optarg, "%d/%d", &num, &den); if (num != 1 || den <= 0 || den > 8) msg ("$Fator redutivo inválido"); default_factor = -den + 1; } else { sscanf (optarg, "%d", &default_factor); if (default_factor <= 0 || default_factor > 8) msg ("$Fator de ampliação inválido"); default_factor--; } break; case 'H': help (0); break; case 'M': return (0); case 'N': Nflag++; break; case 'R': Rflag++; break; case 's': time_interval = atol (optarg); if (time_interval < 1 || time_interval > 60) { msg ("Argumento inválido para opção '-s'"); help (1); } break; case 'v': vflag++; break; default: putc ('\n', stderr); help (2); } /* end switch (opt) */ } /* end while (analisando opções) */ argv += optind; argc -= optind; /* * Consistência final das Opções. */ if (Nflag) { if (argc > 0 || *argv != NOSTR) msg ("$Com a opção '-N' NÃO podem ser dados nomes de arquivos"); argv = read_args_from_stdin (&argc); } if (Rflag && time_interval > 0) msg ("$As opções '-R' e '-s' são incompatíveis"); /* * Constrói a Tabela de Imagens. */ for (/* acima */; *argv != NULL; argv++) { if (ftw (*argv, add_image_to_table) < 0) msg ("$*Erro em \"ftw (%s)\"", *argv); } if ((nimages = next_image - images) <= 0) msg ("$Não foram encontrados arquivos contendo imagens"); last_image = next_image - 1; if (Rflag && nimages > 1) { /* Escolhe aleatoriamente uma imagem */ images += (time (NULL) % nimages); last_image = images; msg ("Imagem a a janela-mãe: \"%s\"", images->i_name); } /* * Abre a conexão com o servidor. */ if ((dpy = XOpenDisplay (display)) == NULL) { msg ( "$Não consegui conectar-me ao servidor \"%s\"", XDisplayName (display) ); } screen = DefaultScreen (dpy); depth = DefaultDepth (dpy, screen); root = RootWindow (dpy, screen); /* * Obtém o mapa de cores de acordo com a profundidade. */ cmp = &stdcmap; map = (depth <= 8) ? XA_RGB_DEFAULT_MAP : XA_RGB_BEST_MAP; if (!XGetStandardColormap (dpy, root, cmp, map)) { cmp = NULL; msg ("Mapa de cores padrão para profundidade %d não disponível", depth); } /* * Decide se cria ou não uma janela para exibir as imagens. */ win = Rflag ? root : create_window (dpy); gcv.foreground = WhitePixel (dpy, screen); gcv.background = BlackPixel (dpy, screen); gc = XCreateGC (dpy, win, GCForeground|GCBackground, &gcv); /* * Mostra as imagens. */ for (times = 0, old_ip = NOIMAGE, ip = images; ip != NOIMAGE; times++) { if (vflag && (times & 15) == 0 && nimages > 0) { printf ("\n NUM FMT LARG x ALT FATOR CORES TAMANHO ARQUIVO\n"); printf ("--------------------------------------------------------------\n"); } if (old_ip != ip) { /* Abre o arquivo que contém a imagem */ if ((fp = fdopen (inopen (ip->i_dev, ip->i_ino), "r")) == NOFILE) { msg ("*Não consegui abrir o arquivo \"%s\"", ip->i_name); exit_val++; break; } /* Lê a imagem para a memória */ if ((ximage = (*ip->i_format->f_load) (fp, 1, dpy, cmp, ip)) == NULL) { msg ("Não consegui ler imagens do arquivo \"%s\"", ip->i_name); fclose (fp); exit_val++; break; } fclose (fp); /* Imprime, se necessário, algumas informações sobre a imagem */ if (vflag) { char factor[8]; if (ip->i_factor >= 0) snprintf (factor, sizeof (factor), "%d", ip->i_factor + 1); else snprintf (factor, sizeof (factor), "1/%d", -ip->i_factor + 1); printf ( "%4d %s %4d x %4d %4s %8d %8d %s\n", ip - images + 1, ip->i_format->f_extension, ip->i_width, ip->i_height, factor, ip->i_ncolors, ip->i_file_sz, ip->i_name ); } /* Mostra a imagem como fundo da janela */ if (draw_window (dpy, win, ximage, ip) < 0) break; } /* end if (nova imagem) */ /* Aguarda eventos e analisa o retorno */ key = wait_for_events (dpy, win, time_interval); old_ip = ip; switch (key) { case 'q': case 'Q': case XK_Escape: ip = NOIMAGE; /* Fim do programa */ break; case XK_Up: case XK_KP_Up: if (ip > images) ip--; /* Retrocede uma imagem */ break; case XK_Down: case XK_KP_Down: if (ip < last_image) ip++; /* Avança uma imagem */ elif (time_interval > 0) ip = images; /* Volta ao início */ break; case XK_Home: case XK_KP_Home: ip = images; /* Volta ao início */ break; case XK_End: case XK_KP_End: ip = last_image; /* Vai para a última imagem */ break; case XK_Right: case XK_KP_Right: ip->i_factor++; /* Aumenta o fator */ old_ip = NOIMAGE; break; case XK_Left: /* Diminui o fator */ case XK_KP_Left: ip->i_factor--; old_ip = NOIMAGE; break; default: break; } /* end switch (tecla retornada) */ if (ip != old_ip) XDestroyImage (ximage); } /* end for (percorrendo imagens) */ XFreeGC (dpy, gc); XCloseDisplay (dpy); return (exit_val); } /* end main */
/* **************************************************************** * Copia um arquivo para o cliente * **************************************************************** */ void copy_to (const char *file_nm) { off_t n; int fd = -1; STAT s; #ifdef LITTLE_ENDIAN STAT big_s; #endif LITTLE_ENDIAN char *rmsg; /* * Obtém o estado do arquivo */ if (lstat (file_nm, &s) < 0) { t_snd_msg (-1, strerror (errno)); return; } if (S_ISREG (s.st_mode) && (fd = inopen (s.st_dev, s.st_ino)) < 0) { t_snd_msg (-1, strerror (errno)); return; } /* * Transmite o nome e estado do arquivo */ t_snd_msg_no_push (0, NOSTR); #ifdef LITTLE_ENDIAN stat_endian_cv (&big_s, &s); if (t_snd (tcp_fd, &big_s, sizeof (STAT), T_PUSH) < 0) error (NOSTR); #else if (t_snd (tcp_fd, &s, sizeof (STAT), T_PUSH) < 0) error (NOSTR); #endif LITTLE_ENDIAN /* * Se for um elo simbólico, envia também o conteúdo */ if (S_ISLNK (s.st_mode)) { char *local_symlink_nm; n = s.st_size + 1; local_symlink_nm = alloca (n); if (readlink (file_nm, local_symlink_nm, n) < 0) error ("$*Não consegui obter o conteúdo do elo \"%s\"", file_nm); if (t_snd (tcp_fd, local_symlink_nm, n, 0) < 0) error (NOSTR); t_push (tcp_fd); } /* * Espera confirmação de criação do arquivo na estação remota */ if (t_rcv_msg (&rmsg) < 0) { if (fd > 0) close (fd); return; } /* * Se não for regular, não precisa de enviar o conteúdo */ if (!S_ISREG (s.st_mode)) return; /* * Transmite os segmentos */ if (Cflag && s.st_size >= MIN_COMPRESS_SZ) { reduce (fd, snd_rcv_buf); } else { for ( /* vazio */; (n = read (fd, snd_rcv_buf, BLSZ)) > 0; /* vazio */ ) { if (t_snd (tcp_fd, snd_rcv_buf, n, 0) < 0) error (NOSTR); } /* loop pelo segmentos */ if (n < 0) error ("$*Erro de leitura do arquivo \"%s\"", file_nm); } t_push (tcp_fd); close (fd); } /* end file_copy */