void rfs4_set_deleg_response(rfs4_deleg_state_t *dsp, open_delegation4 *dp, nfsace4 *ace, int recall) { open_write_delegation4 *wp; open_read_delegation4 *rp; nfs_space_limit4 *spl; nfsace4 nace; /* * We need to allocate a new copy of the who string. * this string will be freed by the rfs4_op_open dis_resfree * routine. We need to do this allocation since replays will * be allocated and rfs4_compound can't tell the difference from * a replay and an inital open. N.B. if an ace is passed in, it * the caller's responsibility to free it. */ if (ace == NULL) { /* * Default is to deny all access, the client will have * to contact the server. XXX Do we want to actually * set a deny for every one, or do we simply want to * construct an entity that will match no one? */ nace.type = ACE4_ACCESS_DENIED_ACE_TYPE; nace.flag = 0; nace.access_mask = ACE4_VALID_MASK_BITS; (void) str_to_utf8(ACE4_WHO_EVERYONE, &nace.who); } else { nace.type = ace->type; nace.flag = ace->flag; nace.access_mask = ace->access_mask; (void) utf8_copy(&ace->who, &nace.who); } dp->delegation_type = dsp->rds_dtype; switch (dsp->rds_dtype) { case OPEN_DELEGATE_NONE: break; case OPEN_DELEGATE_READ: rp = &dp->open_delegation4_u.read; rp->stateid = dsp->rds_delegid.stateid; rp->recall = (bool_t)recall; rp->permissions = nace; break; case OPEN_DELEGATE_WRITE: wp = &dp->open_delegation4_u.write; wp->stateid = dsp->rds_delegid.stateid; wp->recall = (bool_t)recall; spl = &wp->space_limit; spl->limitby = NFS_LIMIT_SIZE; spl->nfs_space_limit4_u.filesize = 0; wp->permissions = nace; break; } }
void screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen, struct grid_cell *gc, const char *fmt, va_list ap) { char *msg; struct utf8_data ud; u_char *ptr; size_t left, size = 0; enum utf8_state more; xvasprintf(&msg, fmt, ap); ptr = msg; while (*ptr != '\0') { if (*ptr > 0x7f && utf8_open(&ud, *ptr) == UTF8_MORE) { ptr++; left = strlen(ptr); if (left < (size_t)ud.size - 1) break; while ((more = utf8_append(&ud, *ptr)) == UTF8_MORE) ptr++; ptr++; if (more == UTF8_DONE) { if (maxlen > 0 && size + ud.width > (size_t) maxlen) { while (size < (size_t) maxlen) { screen_write_putc(ctx, gc, ' '); size++; } break; } size += ud.width; utf8_copy(&gc->data, &ud); screen_write_cell(ctx, gc); } } else { if (maxlen > 0 && size + 1 > (size_t) maxlen) break; if (*ptr == '\001') gc->attr ^= GRID_ATTR_CHARSET; else if (*ptr > 0x1f && *ptr < 0x7f) { size++; screen_write_putc(ctx, gc, *ptr); } ptr++; } } free(msg); }
/* Get selected grid cell. */ void screen_select_cell(struct screen *s, struct grid_cell *dst, const struct grid_cell *src) { if (!s->sel.flag || s->sel.hidden) return; memcpy(dst, &s->sel.cell, sizeof *dst); utf8_copy(&dst->data, &src->data); dst->attr = dst->attr & ~GRID_ATTR_CHARSET; dst->attr |= src->attr & GRID_ATTR_CHARSET; dst->flags = src->flags; }
/* Write cell data. */ void screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) { struct screen *s = ctx->s; struct grid *gd = s->grid; struct tty_ctx ttyctx; u_int width, xx, last; struct grid_cell tmp_gc, now_gc; int insert, skip, selected; /* Ignore padding. */ if (gc->flags & GRID_FLAG_PADDING) return; width = gc->data.width; /* * If this is a wide character and there is no room on the screen, for * the entire character, don't print it. */ if (!(s->mode & MODE_WRAP) && (width > 1 && (width > screen_size_x(s) || (s->cx != screen_size_x(s) && s->cx > screen_size_x(s) - width)))) return; /* * If the width is zero, combine onto the previous character, if * there is space. */ if (width == 0) { if (screen_write_combine(ctx, &gc->data) == 0) { screen_write_initctx(ctx, &ttyctx); tty_write(tty_cmd_utf8character, &ttyctx); } return; } /* Initialise the redraw context. */ screen_write_initctx(ctx, &ttyctx); /* If in insert mode, make space for the cells. */ if ((s->mode & MODE_INSERT) && s->cx <= screen_size_x(s) - width) { xx = screen_size_x(s) - s->cx - width; grid_move_cells(s->grid, s->cx + width, s->cx, s->cy, xx); insert = 1; } else insert = 0; skip = !insert; /* Check this will fit on the current line and wrap if not. */ if ((s->mode & MODE_WRAP) && s->cx > screen_size_x(s) - width) { screen_write_linefeed(ctx, 1); s->cx = 0; /* carriage return */ skip = 0; } /* Sanity check cursor position. */ if (s->cx > screen_size_x(s) - width || s->cy > screen_size_y(s) - 1) return; /* Handle overwriting of UTF-8 characters. */ grid_view_get_cell(gd, s->cx, s->cy, &now_gc); if (screen_write_overwrite(ctx, &now_gc, width)) skip = 0; /* * If the new character is UTF-8 wide, fill in padding cells. Have * already ensured there is enough room. */ for (xx = s->cx + 1; xx < s->cx + width; xx++) { grid_view_set_cell(gd, xx, s->cy, &screen_write_pad_cell); skip = 0; } /* If no change, do not draw. */ if (skip) skip = (memcmp(&now_gc, gc, sizeof now_gc) == 0); /* Update the selection the flag and set the cell. */ selected = screen_check_selection(s, s->cx, s->cy); if (selected && ~gc->flags & GRID_FLAG_SELECTED) { skip = 0; memcpy(&tmp_gc, gc, sizeof tmp_gc); tmp_gc.flags |= GRID_FLAG_SELECTED; grid_view_set_cell(gd, s->cx, s->cy, &tmp_gc); } else if (!selected && gc->flags & GRID_FLAG_SELECTED) { skip = 0; memcpy(&tmp_gc, gc, sizeof tmp_gc); tmp_gc.flags &= ~GRID_FLAG_SELECTED; grid_view_set_cell(gd, s->cx, s->cy, &tmp_gc); } else if (!skip) grid_view_set_cell(gd, s->cx, s->cy, gc); /* * Move the cursor. If not wrapping, stick at the last character and * replace it. */ last = !(s->mode & MODE_WRAP); if (s->cx <= screen_size_x(s) - last - width) s->cx += width; else s->cx = screen_size_x(s) - last; /* Create space for character in insert mode. */ if (insert) { ttyctx.num = width; tty_write(tty_cmd_insertcharacter, &ttyctx); } /* Save last cell if it will be needed. */ if (!skip && ctx->wp != NULL && ttyctx.ocx > ctx->wp->sx - width) screen_write_save_last(ctx, &ttyctx); /* Write to the screen. */ if (selected) { memcpy(&tmp_gc, &s->sel.cell, sizeof tmp_gc); utf8_copy(&tmp_gc.data, &gc->data); tmp_gc.attr = tmp_gc.attr & ~GRID_ATTR_CHARSET; tmp_gc.attr |= gc->attr & GRID_ATTR_CHARSET; tmp_gc.flags = gc->flags; tmp_gc.flags &= ~(GRID_FLAG_FGRGB|GRID_FLAG_BGRGB); tmp_gc.flags &= ~(GRID_FLAG_FG256|GRID_FLAG_BG256); tmp_gc.flags |= s->sel.cell.flags & (GRID_FLAG_FG256|GRID_FLAG_BG256); ttyctx.cell = &tmp_gc; tty_write(tty_cmd_cell, &ttyctx); } else if (!skip) { ttyctx.cell = gc; tty_write(tty_cmd_cell, &ttyctx); } }
/* Write cell data. */ void screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) { struct screen *s = ctx->s; struct grid *gd = s->grid; struct tty_ctx ttyctx; u_int width, xx, last; u_int sx = screen_size_x(s), sy = screen_size_y(s); struct grid_line *gl; struct grid_cell tmp_gc, now_gc; struct grid_cell_entry *gce; int insert, skip, selected, wrapped = 0; ctx->cells++; /* Ignore padding. */ if (gc->flags & GRID_FLAG_PADDING) return; width = gc->data.width; /* * If this is a wide character and there is no room on the screen, for * the entire character, don't print it. */ if (!(s->mode & MODE_WRAP) && (width > 1 && (width > sx || (s->cx != sx && s->cx > sx - width)))) return; /* * If the width is zero, combine onto the previous character, if * there is space. */ if (width == 0) { if (screen_write_combine(ctx, &gc->data) == 0) { screen_write_initctx(ctx, &ttyctx); tty_write(tty_cmd_utf8character, &ttyctx); } return; } /* Initialise the redraw context. */ screen_write_initctx(ctx, &ttyctx); /* If in insert mode, make space for the cells. */ if ((s->mode & MODE_INSERT) && s->cx <= sx - width) { xx = sx - s->cx - width; grid_move_cells(s->grid, s->cx + width, s->cx, s->cy, xx); insert = 1; } else insert = 0; skip = !insert; /* Check this will fit on the current line and wrap if not. */ if ((s->mode & MODE_WRAP) && s->cx > sx - width) { screen_write_flush(ctx); screen_write_save_last(ctx, &ttyctx); screen_write_linefeed(ctx, 1); s->cx = 0; /* carriage return */ skip = 0; wrapped = 1; } /* Sanity check cursor position. */ if (s->cx > sx - width || s->cy > sy - 1) return; /* Handle overwriting of UTF-8 characters. */ gl = &s->grid->linedata[s->grid->hsize + s->cy]; if (gl->flags & GRID_LINE_EXTENDED) { grid_view_get_cell(gd, s->cx, s->cy, &now_gc); if (screen_write_overwrite(ctx, &now_gc, width)) skip = 0; } /* * If the new character is UTF-8 wide, fill in padding cells. Have * already ensured there is enough room. */ for (xx = s->cx + 1; xx < s->cx + width; xx++) { grid_view_set_cell(gd, xx, s->cy, &screen_write_pad_cell); skip = 0; } /* If no change, do not draw. */ if (skip) { if (s->cx >= gl->cellsize) skip = grid_cells_equal(gc, &grid_default_cell); else { gce = &gl->celldata[s->cx]; if (gce->flags & GRID_FLAG_EXTENDED) skip = 0; else if (gc->flags != (gce->flags & ~GRID_FLAG_EXTENDED)) skip = 0; else if (gc->attr != gce->data.attr) skip = 0; else if (gc->fg != gce->data.fg) skip = 0; else if (gc->bg != gce->data.bg) skip = 0; else if (gc->data.width != 1 || gce->data.data != gc->data.data[0]) skip = 0; } } /* Update the selection the flag and set the cell. */ selected = screen_check_selection(s, s->cx, s->cy); if (selected && ~gc->flags & GRID_FLAG_SELECTED) { skip = 0; memcpy(&tmp_gc, gc, sizeof tmp_gc); tmp_gc.flags |= GRID_FLAG_SELECTED; grid_view_set_cell(gd, s->cx, s->cy, &tmp_gc); } else if (!selected && gc->flags & GRID_FLAG_SELECTED) { skip = 0; memcpy(&tmp_gc, gc, sizeof tmp_gc); tmp_gc.flags &= ~GRID_FLAG_SELECTED; grid_view_set_cell(gd, s->cx, s->cy, &tmp_gc); } else if (!skip) grid_view_set_cell(gd, s->cx, s->cy, gc); /* * Move the cursor. If not wrapping, stick at the last character and * replace it. */ last = !(s->mode & MODE_WRAP); if (s->cx <= sx - last - width) s->cx += width; else s->cx = sx - last; /* Create space for character in insert mode. */ if (insert) { if (!wrapped) screen_write_flush(ctx); ttyctx.num = width; tty_write(tty_cmd_insertcharacter, &ttyctx); } /* Write to the screen. */ if (selected) { memcpy(&tmp_gc, &s->sel.cell, sizeof tmp_gc); utf8_copy(&tmp_gc.data, &gc->data); tmp_gc.attr = tmp_gc.attr & ~GRID_ATTR_CHARSET; tmp_gc.attr |= gc->attr & GRID_ATTR_CHARSET; tmp_gc.flags = gc->flags; screen_write_flush(ctx); ttyctx.cell = &tmp_gc; tty_write(tty_cmd_cell, &ttyctx); ctx->written++; } else if (!skip) { if (wrapped) { ttyctx.cell = gc; tty_write(tty_cmd_cell, &ttyctx); ctx->written++; } else { /* * If wp is NULL, we are not updating the terminal and * don't care about actually writing the cells * (tty_write will just return). So don't even bother * allocating the dirty array. */ if (ctx->wp != NULL && s->dirty == NULL) { log_debug("%s: allocating %u bits", __func__, s->dirtysize); s->dirty = bit_alloc(s->dirtysize); } if (s->dirty != NULL) { bit_set(s->dirty, screen_dirty_bit(s, ttyctx.ocx, ttyctx.ocy)); ctx->dirty++; } } } else ctx->skipped++; }
/* Write cell data. */ void screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) { struct screen *s = ctx->s; struct grid *gd = s->grid; struct tty_ctx ttyctx; u_int width, xx, last; struct grid_cell tmp_gc; int insert; /* Ignore padding. */ if (gc->flags & GRID_FLAG_PADDING) return; width = gc->data.width; /* * If this is a wide character and there is no room on the screen, for * the entire character, don't print it. */ if (!(s->mode & MODE_WRAP) && (width > 1 && (width > screen_size_x(s) || (s->cx != screen_size_x(s) && s->cx > screen_size_x(s) - width)))) return; /* * If the width is zero, combine onto the previous character, if * there is space. */ if (width == 0) { if (screen_write_combine(ctx, &gc->data) == 0) { screen_write_initctx(ctx, &ttyctx, 0); tty_write(tty_cmd_utf8character, &ttyctx); } return; } /* Initialise the redraw context, saving the last cell. */ screen_write_initctx(ctx, &ttyctx, 1); /* If in insert mode, make space for the cells. */ if ((s->mode & MODE_INSERT) && s->cx <= screen_size_x(s) - width) { xx = screen_size_x(s) - s->cx - width; grid_move_cells(s->grid, s->cx + width, s->cx, s->cy, xx); insert = 1; } else insert = 0; /* Check this will fit on the current line and wrap if not. */ if ((s->mode & MODE_WRAP) && s->cx > screen_size_x(s) - width) { screen_write_linefeed(ctx, 1); s->cx = 0; /* carriage return */ } /* Sanity check cursor position. */ if (s->cx > screen_size_x(s) - width || s->cy > screen_size_y(s) - 1) return; /* Handle overwriting of UTF-8 characters. */ screen_write_overwrite(ctx, width); /* * If the new character is UTF-8 wide, fill in padding cells. Have * already ensured there is enough room. */ memcpy(&tmp_gc, &grid_default_cell, sizeof tmp_gc); tmp_gc.flags |= GRID_FLAG_PADDING; tmp_gc.data.width = 0; for (xx = s->cx + 1; xx < s->cx + width; xx++) grid_view_set_cell(gd, xx, s->cy, &tmp_gc); /* Set the cell. */ grid_view_set_cell(gd, s->cx, s->cy, gc); /* * Move the cursor. If not wrapping, stick at the last character and * replace it. */ last = !(s->mode & MODE_WRAP); if (s->cx <= screen_size_x(s) - last - width) s->cx += width; else s->cx = screen_size_x(s) - last; /* Draw to the screen if necessary. */ if (insert) { ttyctx.num = width; tty_write(tty_cmd_insertcharacter, &ttyctx); } if (screen_check_selection(s, s->cx - width, s->cy)) { memcpy(&tmp_gc, &s->sel.cell, sizeof tmp_gc); utf8_copy(&tmp_gc.data, &gc->data); tmp_gc.attr = tmp_gc.attr & ~GRID_ATTR_CHARSET; tmp_gc.attr |= gc->attr & GRID_ATTR_CHARSET; tmp_gc.flags = gc->flags & ~(GRID_FLAG_FG256|GRID_FLAG_BG256); tmp_gc.flags |= s->sel.cell.flags & (GRID_FLAG_FG256|GRID_FLAG_BG256); ttyctx.cell = &tmp_gc; tty_write(tty_cmd_cell, &ttyctx); } else { ttyctx.cell = gc; tty_write(tty_cmd_cell, &ttyctx); } }
/* Write string, similar to nputs, but with embedded formatting (#[]). */ void screen_write_cnputs(struct screen_write_ctx *ctx, ssize_t maxlen, struct grid_cell *gc, const char *fmt, ...) { struct grid_cell lgc; struct utf8_data ud; va_list ap; char *msg; u_char *ptr, *last; size_t left, size = 0; enum utf8_state more; va_start(ap, fmt); xvasprintf(&msg, fmt, ap); va_end(ap); memcpy(&lgc, gc, sizeof lgc); ptr = msg; while (*ptr != '\0') { if (ptr[0] == '#' && ptr[1] == '[') { ptr += 2; last = ptr + strcspn(ptr, "]"); if (*last == '\0') { /* No ]. Not much point in doing anything. */ break; } *last = '\0'; style_parse(gc, &lgc, ptr); ptr = last + 1; continue; } if (*ptr > 0x7f && utf8_open(&ud, *ptr) == UTF8_MORE) { ptr++; left = strlen(ptr); if (left < (size_t)ud.size - 1) break; while ((more = utf8_append(&ud, *ptr)) == UTF8_MORE) ptr++; ptr++; if (more == UTF8_DONE) { if (maxlen > 0 && size + ud.width > (size_t) maxlen) { while (size < (size_t) maxlen) { screen_write_putc(ctx, gc, ' '); size++; } break; } size += ud.width; utf8_copy(&lgc.data, &ud); screen_write_cell(ctx, &lgc); } } else { if (maxlen > 0 && size + 1 > (size_t) maxlen) break; if (*ptr > 0x1f && *ptr < 0x7f) { size++; screen_write_putc(ctx, &lgc, *ptr); } ptr++; } } free(msg); }