static void png_cexcept_error (png_structp png_ptr, png_const_charp msg) { if(png_ptr){ rxvt_msg (DBG_ERROR, DBG_IMAGES, "png file read error: %s\n", msg); } }
/* INTPROTO */ static void rxvt_update_lastlog(const char *fname, const char *pty, const char *host) { # ifdef HAVE_STRUCT_LASTLOGX struct lastlogx llx; # endif # ifdef HAVE_STRUCT_LASTLOG int fd; struct lastlog ll; # ifdef LASTLOG_IS_DIR char lastlogfile[256]; # endif struct passwd *pwent; # endif # ifdef HAVE_STRUCT_LASTLOGX MEMSET(&llx, 0, sizeof(llx)); llx.ll_tv.tv_sec = time(NULL); llx.ll_tv.tv_usec = 0; STRNCPY(llx.ll_line, pty, sizeof(llx.ll_line)); STRNCPY(llx.ll_host, host, sizeof(llx.ll_host)); updlastlogx(RXVT_LASTLOGX_FILE, getuid(), &llx); # endif # ifdef HAVE_STRUCT_LASTLOG pwent = getpwuid(getuid()); if (!pwent) { rxvt_msg (DBG_ERROR, DBG_LOGGING, "no entry in password file"); return; } MEMSET(&ll, 0, sizeof(ll)); ll.ll_time = time(NULL); STRNCPY(ll.ll_line, pty, sizeof(ll.ll_line)); STRNCPY(ll.ll_host, host, sizeof(ll.ll_host)); # ifdef LASTLOG_IS_DIR sprintf(lastlogfile, "%.*s/%.*s", sizeof(lastlogfile) - sizeof(pwent->pw_name) - 2, fname, sizeof(pwent->pw_name), (!pwent->pw_name || pwent->pw_name[0] == '\0') ? "unknown" : pwent->pw_name); if ((fd = open(lastlogfile, O_WRONLY | O_CREAT, 0644)) >= 0) { write(fd, &ll, sizeof(ll)); close(fd); } # else if ((fd = open(fname, O_RDWR)) != -1) { if (lseek(fd, (off_t) ((long)pwent->pw_uid * sizeof(ll)), SEEK_SET) != -1) write(fd, &ll, sizeof(ll)); close(fd); } # endif /* LASTLOG_IS_DIR */ # endif /* HAVE_STRUCT_LASTLOG */ }
/* EXTPROTO */ void rxvt_makeutent(rxvt_t *r, const char *pty, const char *hostname) { #ifdef UTEMPTER_SUPPORT utempter_add_record (PVTS(r)->cmd_fd, hostname); #else /* UTEMPTER_SUPPORT */ #ifdef HAVE_STRUCT_UTMP struct utmp *ut = &(PVTS(r)->ut); #endif #if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) struct utmpx *utx = &(PVTS(r)->utx); #endif #ifdef HAVE_UTMP_PID int i; #endif char ut_id[5]; struct passwd *pwent = getpwuid(getuid()); if (!STRNCMP(pty, "/dev/", 5)) pty += 5; /* skip /dev/ prefix */ if (!STRNCMP(pty, "pty", 3) || !STRNCMP(pty, "tty", 3)) { STRNCPY(ut_id, (pty + 3), sizeof(ut_id)); } #ifdef HAVE_UTMP_PID else if (sscanf(pty, "pts/%d", &i) == 1) sprintf(ut_id, "vt%02x", (i & 0xff)); /* sysv naming */ #endif else if (STRNCMP(pty, "pty", 3) && STRNCMP(pty, "tty", 3)) { rxvt_msg (DBG_ERROR, DBG_LOGGING, "can't parse tty name \"%s\"", pty); return; } #ifdef HAVE_STRUCT_UTMP MEMSET(ut, 0, sizeof(struct utmp)); # ifdef HAVE_UTMP_PID setutent(); STRNCPY(ut->ut_id, ut_id, sizeof(ut->ut_id)); ut->ut_type = DEAD_PROCESS; getutid(ut); /* position to entry in utmp file */ STRNCPY(PVTS(r)->ut_id, ut_id, sizeof(PVTS(r)->ut_id)); # endif #endif #if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) MEMSET(utx, 0, sizeof(struct utmpx)); setutxent(); STRNCPY(utx->ut_id, ut_id, sizeof(utx->ut_id)); utx->ut_type = DEAD_PROCESS; getutxid(utx); /* position to entry in utmp file */ STRNCPY(PVTS(r)->ut_id, ut_id, sizeof(PVTS(r)->ut_id)); #endif #ifdef HAVE_STRUCT_UTMP STRNCPY(ut->ut_line, pty, sizeof(ut->ut_line)); ut->ut_time = time(NULL); # ifdef HAVE_UTMP_PID STRNCPY(ut->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?", sizeof(ut->ut_user)); STRNCPY(ut->ut_id, ut_id, sizeof(ut->ut_id)); ut->ut_time = time(NULL); ut->ut_pid = PVTS(r)->cmd_pid; # ifdef HAVE_UTMP_HOST STRNCPY(ut->ut_host, hostname, sizeof(ut->ut_host)); # endif ut->ut_type = USER_PROCESS; pututline(ut); endutent(); /* close the file */ PVTS(r)->utmp_pos = 0; # else STRNCPY(ut->ut_name, (pwent && pwent->pw_name) ? pwent->pw_name : "?", sizeof(ut->ut_name)); # ifdef HAVE_UTMP_HOST STRNCPY(ut->ut_host, hostname, sizeof(ut->ut_host)); # endif # endif #endif #if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) STRNCPY(utx->ut_line, pty, sizeof(utx->ut_line)); STRNCPY(utx->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?", sizeof(utx->ut_user)); STRNCPY(utx->ut_id, ut_id, sizeof(utx->ut_id)); # ifdef HAVE_UTMPX_SESSION utx->ut_session = getsid(0); # endif utx->ut_tv.tv_sec = time(NULL); utx->ut_tv.tv_usec = 0; utx->ut_pid = PVTS(r)->cmd_pid; # ifdef HAVE_UTMPX_HOST STRNCPY(utx->ut_host, hostname, sizeof(utx->ut_host)); # endif utx->ut_type = USER_PROCESS; pututxline(utx); endutxent(); /* close the file */ PVTS(r)->utmp_pos = 0; #endif #if defined(HAVE_STRUCT_UTMP) && !defined(HAVE_UTMP_PID) { int i; # ifdef HAVE_TTYSLOT i = ttyslot(); if (rxvt_write_bsd_utmp(i, ut)) PVTS(r)->utmp_pos = i; # else FILE *fd0; if (NOT_NULL(fd0 = fopen(TTYTAB_FILENAME, "r"))) { char buf[256], name[256]; buf[sizeof(buf) - 1] = '\0'; for (i = 1; NOT_NULL(fgets(buf, sizeof(buf) - 1, fd0)); ) { if (*buf == '#' || sscanf(buf, "%s", name) != 1) continue; if (!STRCMP(ut->ut_line, name)) { if (!rxvt_write_bsd_utmp(i, ut)) i = 0; PVTS(r)->utmp_pos = i; fclose(fd0); break; } i++; } fclose(fd0); } # endif } #endif #ifdef WTMP_SUPPORT # ifdef WTMP_ONLY_ON_LOGIN if (ISSET_OPTION(r, Opt_loginShell)) # endif { # ifdef HAVE_STRUCT_UTMP # ifdef HAVE_UPDWTMP updwtmp(RXVT_WTMP_FILE, ut); # else rxvt_update_wtmp(RXVT_WTMP_FILE, ut); # endif # endif # if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) # ifdef HAVE_UPDWTMPX updwtmpx(RXVT_WTMPX_FILE, utx); # else pututxline (utx); # endif # endif } #endif #endif /* UTEMPTER_SUPPORT */ #if defined(LASTLOG_SUPPORT) && defined(RXVT_LASTLOG_FILE) if (ISSET_OPTION(r, Opt_loginShell)) rxvt_update_lastlog(RXVT_LASTLOG_FILE, pty, hostname); #endif }
/* EXTPROTO */ Pixmap rxvt_load_pixmap(rxvt_t *r, const char *file, long* pwidth, long* pheight) { char* f; int flen; #if defined(USE_JPEG) || defined(USE_PNG) long w = 0, h = 0; #endif XpmAttributes xpm_attr; Pixmap pixmap; UNSET_PIXMAP(pixmap); assert(file != NULL); if ((char) 0 == *file) { /* No file to load */ return None; } xpm_attr.closeness = 30000; xpm_attr.colormap = XCMAP; xpm_attr.visual = XVISUAL; xpm_attr.depth = XDEPTH; xpm_attr.valuemask = (XpmCloseness | XpmColormap | XpmVisual | XpmDepth | XpmSize | XpmReturnPixels); /* search environment variables here too */ if (NULL == (f = (char*) rxvt_File_find (file, ".xpm", r->h->rs[Rs_path])) #ifdef USE_JPEG && NULL == (f = (char*) rxvt_File_find (file, ".jpg", r->h->rs[Rs_path])) && NULL == (f = (char*) rxvt_File_find (file, ".jpeg", r->h->rs[Rs_path])) #endif #ifdef USE_PNG && NULL == (f = (char*) rxvt_File_find (file, ".png", r->h->rs[Rs_path])) #endif ) { char *p; /* semi-colon delimited */ if (NULL == (p = STRCHR(file, ';'))) p = STRCHR(file, '\0'); rxvt_msg (DBG_ERROR, DBG_PIXMAP, "couldn't load image file \"%.*s\"", (p - file), file); return None; } flen = STRLEN (f); #ifdef USE_JPEG if ((flen >= 4 && !STRNCASECMP (f+flen-4, ".jpg", 4)) || (flen >= 5 && !STRNCASECMP (f+flen-5, ".jpeg",5))) { GC gc = DefaultGC (r->Xdisplay, XSCREEN); if (!JpegReadFileToPixmap (r->Xdisplay, XROOT, gc, f, &pixmap, &w, &h)) { *pwidth = w; *pheight = h; } } else #endif #ifdef USE_PNG if (flen >= 4 && !STRNCASECMP (f+flen-4, ".png", 4)) { GC gc = DefaultGC (r->Xdisplay, XSCREEN); if (!PngReadFileToPixmap (r->Xdisplay, XROOT, gc, f, &pixmap, &w, &h)) { *pwidth = w; *pheight = h; } } else #endif #ifdef HAVE_LIBXPM if (!XpmReadFileToPixmap(r->Xdisplay, XROOT, f, &pixmap, NULL, &xpm_attr)) { *pwidth = xpm_attr.width; *pheight = xpm_attr.height; } #endif { /* empty to suppress compile error */ } rxvt_free(f); if (NOT_PIXMAP(pixmap)) { char *p; /* semi-colon delimited */ if ((p = STRCHR(file, ';')) == NULL) p = STRCHR(file, '\0'); rxvt_msg (DBG_ERROR, DBG_PIXMAP, "couldn't load image file \"%.*s\"", (p - file), file); } return (pixmap); }
long PngReadFileToPixmap (Display* display, Window window, GC gc, char* filename, Pixmap* pixmap, long* w, long* h) { int red_mask, green_mask, blue_mask; int red_shift, green_shift, blue_shift; int start_shift, msb_flag; unsigned int start_mask, udat; XWindowAttributes win_attr; FILE* ifile; long display_depth; png_byte sig[8]; png_infop info_ptr; png_structp png_ptr; png_uint_32 png_width; png_uint_32 png_height; int png_depth; int png_color_type; png_uint_32 png_row_bytes; png_uint_32 png_channels; long rwidth; long rheight; long components; unsigned char* buf; png_byte** png_row_ptrs; long vwidth; long vheight; long stretched; XImage* image; Visual* visual; Pixmap pix; int i; char* data1; unsigned char r,g,b; long ptr = 0; long ptr2 = 0; long j; red_mask = green_mask = blue_mask = 0; red_shift = green_shift = blue_shift = 0; ifile = fopen(filename,"r"); if (ifile == NULL){ return -1; } display_depth = XDefaultDepth(display,XDefaultScreen(display)); fread(sig, 1, 8, ifile); if (png_sig_cmp(sig, 0, 8)){ fclose(ifile); return -1; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL); if (png_ptr == NULL){ fclose(ifile); return -1; } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL){ png_destroy_read_struct(&png_ptr, NULL, NULL); fclose(ifile); return -1; } png_init_io(png_ptr, ifile); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &png_width, &png_height, &png_depth, &png_color_type, NULL, NULL, NULL); if (png_depth == 16){ png_set_strip_16(png_ptr); } png_row_bytes = png_get_rowbytes(png_ptr, info_ptr); png_channels = png_get_channels(png_ptr, info_ptr); if (png_depth < 8){ if (png_color_type == PNG_COLOR_TYPE_GRAY ){ png_set_expand_gray_1_2_4_to_8(png_ptr); png_row_bytes = png_width; }else{ png_set_expand(png_ptr); png_row_bytes = png_width; png_row_bytes = png_width * 3; png_channels = 3; } } if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)){ png_set_expand(png_ptr); png_row_bytes = png_width; } if (png_color_type == PNG_COLOR_TYPE_GRAY || png_color_type == PNG_COLOR_TYPE_GRAY_ALPHA){ png_set_gray_to_rgb(png_ptr); png_row_bytes = png_width; } if (png_color_type == PNG_COLOR_TYPE_PALETTE){ png_set_palette_to_rgb(png_ptr); png_row_bytes = png_width * 3; png_channels = 3; } rwidth = png_width; rheight = png_height; components = png_channels; /* possible integer overflow? */ assert ((int) png_row_bytes > 0); assert ((int) png_height > 0); assert (((int)png_row_bytes) * ((int)png_height) * sizeof(png_byte) > 0); buf = rxvt_malloc(png_row_bytes * png_height * sizeof(png_byte)); if (buf == NULL){ rxvt_msg (DBG_ERROR, DBG_IMAGES, "png read error: out of memory..\n"); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(ifile); return -1; } /* possible integer overflow? */ assert ((int) png_height > 0); assert (sizeof(png_bytep) * ((int)png_height) > 0); png_row_ptrs = rxvt_malloc (sizeof(png_bytep)*png_height); if (png_row_ptrs == NULL){ rxvt_msg (DBG_ERROR, DBG_IMAGES, "png read error: out of memory..\n"); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(ifile); return -1; } for(i = 0; i < (int)png_height; i++){ png_row_ptrs[i] = (png_byte*)(buf + i * png_row_bytes); } png_read_image(png_ptr, png_row_ptrs); png_read_end(png_ptr,NULL); rxvt_free(png_row_ptrs); vwidth = *w; vheight = *h; stretched =0; if (*w == 0 || *h == 0){ *w = rwidth; *h = rheight; }else{ if ((long)((double)rwidth * vheight/vwidth) < rheight){ *w = (long)((double)vheight * rwidth/rheight); }else{ *h = (long)((double)vwidth * rheight/rwidth); } stretched = 1; } vwidth = *w; vheight = *h; image = 0; visual = XDefaultVisual(display,XDefaultScreen(display)); if (display_depth >16){ image = XCreateImage(display,visual, display_depth, ZPixmap,0,0,vwidth,vheight,32,0); }else if (display_depth >8){ image = XCreateImage(display,visual, display_depth, ZPixmap,0,0,vwidth,vheight,16,0); }else{ image = XCreateImage(display,visual, display_depth, ZPixmap,0,0,vwidth,vheight,8,0); } msb_flag = (ImageByteOrder(display) == MSBFirst)?1:0; if (XGetWindowAttributes(display, RootWindow(display, DefaultScreen(display)), &win_attr) == 0) { fclose(ifile); return -1; } if ((win_attr.depth == 24) || (win_attr.depth == 16)) { unsigned int n; if (win_attr.depth == 24) { start_shift = 24; start_mask = 0x80000000; }else{ start_shift = 8; start_mask = 0x8000; } red_mask = win_attr.visual->red_mask; red_shift = start_shift; n = start_mask; while (!(n & red_mask)) { n >>= 1; red_shift--; } green_mask = win_attr.visual->green_mask; green_shift = start_shift; n = start_mask; while (!(n & green_mask)) { n >>= 1; green_shift--; } blue_mask = win_attr.visual->blue_mask; blue_shift = start_shift; n = start_mask; while (!(n & blue_mask)) { n >>= 1; blue_shift--; } }