File:  [Coherent Logic Development] / freem / src / ssvn_device.c
Revision 1.4: download - view: text, annotated - select for diffs
Sun Mar 9 19:50:47 2025 UTC (3 weeks, 2 days ago) by snw
Branches: MAIN
CVS tags: v0-62-3, v0-62-2, v0-62-1, v0-62-0, HEAD
Second phase of REUSE compliance and header reformat

/*
 *   $Id: ssvn_device.c,v 1.4 2025/03/09 19:50:47 snw Exp $
 *    ^$DEVICE ssvn
 *
 *  
 *   Author: Serena Willis <snw@coherent-logic.com>
 *    Copyright (C) 1998 MUG Deutschland
 *    Copyright (C) 2020, 2025 Coherent Logic Development LLC
 *
 *
 *   This file is part of FreeM.
 *
 *   FreeM is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   FreeM is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero Public License for more details.
 *
 *   You should have received a copy of the GNU Affero Public License
 *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
 *
 **/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "mref.h"
#include "mpsdef.h"

void set_dsw_bit(int bit);
void clear_dsw_bit(int bit);

void ssvn_device(short action, char *key, char *data)
{
    int channel;
    int fd;
    int i;
    FILE *fp;
    freem_ref_t *r;
    char *dbuf;
    char *envbuf;
    
    r = (freem_ref_t *) malloc (sizeof (freem_ref_t));
    NULLPTRCHK(r,"ssvn_device");
    
    dbuf = (char *) malloc (100 * sizeof (char));
    NULLPTRCHK(dbuf,"ssvn_device");
    
    mref_init (r, MREF_RT_SSV, "^$DEVICE");
    internal_to_mref (r, key);

    if (!isdigit (r->subscripts[0][0])) {
        merr_raise (NODEVICE);
        goto done;
    }

    strcpy (dbuf, r->subscripts[0]);
    stcnv_c2m (dbuf);
    
    channel = intexpr (dbuf);

    if (channel < 0 || channel >= MAXDEV) {
        merr_raise (NODEVICE);
        goto done;
    }

    
    for (i = 0; i < strlen (r->subscripts[1]); i++) r->subscripts[1][i] = toupper (r->subscripts[1][i]);

    
    fp = opnfile[channel];

    if (channel != 0 && (fp == NULL || (fd = fileno (fp)) == -1) && channel < FIRSTSCK && strcmp (r->subscripts[1], "$DEVICE") != 0) {
        merr_raise (NOPEN);
        goto done;
    }


    key = mref_to_internal (r);

    switch (action) {

        case get_sym:

            if (r->subscript_count == 1) {
                stcpy (data, dev[channel]);
                break;
            }

            
            
            if (r->subscript_count == 2) {
                if (strcmp (r->subscripts[1], "$DEVICE") == 0) {

                    if (devstat[channel].mdc_err == 0) {
                        snprintf (data, 3, "0\201\0");
                    }
                    else {
                        snprintf (data, 120, "%d,%d,%s\201\0", devstat[channel].mdc_err, devstat[channel].frm_err, devstat[channel].err_txt);
                    }

                    break;
                    
                }
                if (strcmp (r->subscripts[1], "EOF") == 0 && channel != 0) {
                    
                    if (feof (fp)) {
                        sprintf (data, "1\201");
                    }
                    else {
                        sprintf (data, "0\201");
                    }
                    
                    break;
		
                }
                else if (strcmp (r->subscripts[1], "INPUT_BUFFER") == 0) {
                    stcpy (data, ug_buf[channel]);
                    break;
                }
                else if ((strcmp (r->subscripts[1], "$X") == 0)) {
                    sprintf (data, "%d\201", xpos[channel]);
                    break;
                }
                else if ((strcmp (r->subscripts[1], "$Y") == 0)) {
                    sprintf (data, "%d\201", ypos[channel]);
                    break;
                }
                else if ((strcmp (r->subscripts[1], "ROWS") == 0) && (channel == 0)) {
                    sprintf (data, "%d\201", n_lines);
                    break;
                }
                else if ((strcmp (r->subscripts[1], "COLUMNS") == 0) && (channel == 0)) {
                    sprintf (data, "%d\201", n_columns);
                    break;
                }
                else if (strcmp (r->subscripts[1], "FD") == 0) {
                    sprintf (data, "%d\201", fileno (fp));
                    break;
                }
                else if (strcmp (r->subscripts[1], "MODE") == 0) {

                    switch (sq_modes[channel]) {

                        case 'r':

                            sprintf (data, "READ\201");
                            break;

                        case 'w':

                            sprintf (data, "WRITE\201");
                            break;

                        case 'a':

                            sprintf (data, "APPEND\201");
                            break;

                        case '+':

                            sprintf (data, "READWRITE\201");
                            break;


                        default:

                            sprintf (data, "\201");
                            break;
                            
                    }
                    
                }
                else if (strcmp (r->subscripts[1], "CHARACTER") == 0) {
                    sprintf (data, "M\201");
                    break;
                }
                else if (strcmp (r->subscripts[1], "NAME") == 0) {
                    sprintf (data, "%s", dev[channel]);
                    break;
                }
                else if (strcmp (r->subscripts[1], "TYPE") == 0) {

                    if (channel == 0) {
                        sprintf (data, "4,TERMINAL\201");
                    }
                    else if (channel > 0 && channel < FIRSTSCK) {
                        sprintf (data, "1,FILE\201");
                    }
                    else {
                        sprintf (data, "2,SOCKET\201");
                    }

                    break;
                    
                }
                else if (strcmp (r->subscripts[1], "LENGTH") == 0 && channel != 0) {
                    
                    struct stat s;
                    off_t siz;
                    
                    fstat (fd, &s);
                    siz = s.st_size;
                    
                    sprintf (data, "%ld\201", (long) siz);  

                    break;  

                }    
                else if (strcmp (r->subscripts[1], "NAMESPACE") == 0) {
                
                    switch (channel) {
                        
                        case 0:
                            sprintf (data, "X364\201");
                            break;
                            
                        default:
                            sprintf (data, "\201");
                            break;
                    }
                        
                    break;
                }
                else {
                    merr_raise (M38);
                    goto done;
                }

                goto done;
            }


            
            if ((r->subscript_count == 3) && (strcmp (r->subscripts[1], "OPTIONS") == 0)) {
            
                if (strcmp (r->subscripts[2], "DSW") == 0 && channel == 0) {
                    
                    sprintf (data, "%ld\201", DSW);
                    
                    merr_raise (OK);
                    goto done;
                    
                }     
                else if (strcmp (r->subscripts[2], "TERMINATOR") == 0) {
                    symtab (get_sym, key, data);
                    goto done;
                }
                else if (strcmp (r->subscripts[2], "TERMID") == 0 && channel == 0) {
                    envbuf = getenv ("TERM");
                    strcpy (data, envbuf);
                    stcnv_c2m (data);
                    goto done;
                }
                else if (strcmp (r->subscripts[2], "ECHO") == 0 && channel == 0) {
                    
                    if (ECHOON) {
                        sprintf (data, "1\201");
                    }
                    else {
                        sprintf (data, "0\201");
                    }                    
                    
                }
                else if (strcmp (r->subscripts[2], "DELMODE") == 0 && channel == 0) {
                    
                    if (DELMODE) {
                        sprintf (data, "1\201");
                    }
                    else {
                        sprintf (data, "0\201");
                    }
                    
                }
                else if (strcmp (r->subscripts[2], "ESCAPE") == 0 && channel == 0) {
                    
                    if (ESCSEQPROC) {
                        sprintf (data, "1\201");
                    }
                    else {
                        sprintf (data, "0\201");
                    }
                    
                }
                else if (strcmp (r->subscripts[2], "CONVUPPER") == 0 && channel == 0) {
                    
                    if (CONVUPPER) {
                        sprintf (data, "1\201");
                    }
                    else {
                        sprintf (data, "0\201");
                    }
                    
                }
                else if (strcmp (r->subscripts[2], "DELEMPTY") == 0 && channel == 0) {
                    
                    if (DELEMPTY) {
                        sprintf (data, "1\201");
                    }
                    else {
                        sprintf (data, "0\201");
                    }
                    
                }
                else if (strcmp (r->subscripts[2], "NOCTRLS") == 0 && channel == 0) {
                    
                    if (NOCTRLS) {
                        sprintf (data, "1\201");
                    }
                    else {
                        sprintf (data, "0\201");
                    }
                    
                }
                else if (strcmp (r->subscripts[2], "CTRLOPROC") == 0 && channel == 0) {

                    if (CTRLOPROC) {
                        sprintf (data, "1\201");
                    }
                    else {
                        sprintf (data, "0\201");
                    }
                    
                }
                else if (strcmp (r->subscripts[2], "NOTYPEAHEAD") == 0 && channel == 0) {
                    
                    if (NOTYPEAHEAD) {
                        sprintf (data, "1\201");
                    }
                    else {
                        sprintf (data, "0\201");
                    }
                    
                }            
                else {
                    merr_raise (M38);
                    goto done;
                }

                break;
            }
            else {
                merr_raise (M38);
                goto done;
            }

        case set_sym:


            if (r->subscript_count == 2) {                

                if (strcmp (r->subscripts[1], "DSW") == 0 && channel == 0) {

                    stcpy (dbuf, data);
                    stcnv_m2c (dbuf);

                    DSW = atol (dbuf);

                    merr_raise (OK);
                    goto done;

                }
                else if (strcmp (r->subscripts[1], "INPUT_BUFFER") == 0) {
                    stcpy (ug_buf[channel], data);

                    merr_raise (OK);
                    goto done;
                }
                else {

                    merr_raise (M29);
                    goto done;

                }

            }
            
            if ((r->subscript_count == 3) && (strcmp (r->subscripts[1], "OPTIONS") == 0)) {            

                if (strcmp (r->subscripts[2], "ECHO") == 0 && channel == 0) {

                    if (tvexpr (data)) {
                        clear_dsw_bit (0);
                    }
                    else {
                        set_dsw_bit (0);
                    }
                
                }
                else if (strcmp (r->subscripts[2], "TERMINATOR") == 0) {
                    symtab (set_sym, key, data);

                    merr_raise (OK);
                    goto done;
                }
                else if (strcmp (r->subscripts[2], "DELMODE") == 0 && channel == 0) {

                    if (tvexpr (data)) {
                        set_dsw_bit (2);
                    }
                    else {
                        clear_dsw_bit (2);
                    }
                
                }
                else if (strcmp (r->subscripts[2], "ESCAPE") == 0 && channel == 0) {

                    if (tvexpr (data)) {
                        set_dsw_bit (6);
                    }
                    else {
                        clear_dsw_bit (6);
                    }
                
                }
                else if (strcmp (r->subscripts[2], "CONVUPPER") == 0 && channel == 0) {

                    if (tvexpr (data)) {
                        set_dsw_bit (14);
                    }
                    else {
                        clear_dsw_bit (14);
                    }
                
                }
                else if (strcmp (r->subscripts[2], "DELEMPTY") == 0 && channel == 0) {

                    if (tvexpr (data)) {
                        set_dsw_bit (19);
                    }
                    else {
                        clear_dsw_bit (19);
                    }
                
                }
                else if (strcmp (r->subscripts[2], "NOCTRLS") == 0 && channel == 0) {

                    if (tvexpr (data)) {
                        set_dsw_bit (20);
                    }
                    else {
                        clear_dsw_bit (20);
                    }
                
                }
                else if (strcmp (r->subscripts[2], "CTRLOPROC") == 0 && channel == 0) {

                    if (tvexpr (data)) {
                        set_dsw_bit (21);
                    }
                    else {
                        clear_dsw_bit (21);
                    }
                
                }
                else if (strcmp (r->subscripts[2], "NOTYPEAHEAD") == 0 && channel == 0) {

                    if (tvexpr (data)) {
                        set_dsw_bit (25);
                    }
                    else {
                        clear_dsw_bit (25);
                    }
                
                }            
                else {
                    merr_raise (M29);
                    goto done;
                }

                break;

            }


        default:
            merr_raise (INVREF);
            break;
    }

done:

    free (key);
    free (r);
    free (dbuf);

    return;
}

void set_dsw_bit(int bit)
{
    DSW = ((1 << bit) | DSW);
}

void clear_dsw_bit(int bit)
{
    DSW &= ~(1 << bit);
}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>