Rocksolid Light

Welcome to Rocksolid Light

mail  files  register  newsreader  groups  login

Message-ID:  

An engineer is someone who does list processing in FORTRAN.


computers / comp.os.cpm / Re: Another new CP/M utility program: copyq

Re: Another new CP/M utility program: copyq

<05126034-3cda-4193-ba10-8fc6fc5712ban@googlegroups.com>

  copy mid

https://news.novabbs.org/computers/article-flat.php?id=4244&group=comp.os.cpm#4244

  copy link   Newsgroups: comp.os.cpm
X-Received: by 2002:a05:620a:4406:b0:75c:adce:fed8 with SMTP id v6-20020a05620a440600b0075cadcefed8mr3964039qkp.4.1685906001292;
Sun, 04 Jun 2023 12:13:21 -0700 (PDT)
X-Received: by 2002:ac8:7d8e:0:b0:3f4:7d9a:934e with SMTP id
c14-20020ac87d8e000000b003f47d9a934emr1323656qtd.11.1685906000999; Sun, 04
Jun 2023 12:13:20 -0700 (PDT)
Path: i2pn2.org!i2pn.org!usenet.goja.nl.eu.org!3.eu.feeder.erje.net!feeder.erje.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.os.cpm
Date: Sun, 4 Jun 2023 12:13:20 -0700 (PDT)
In-Reply-To: <dc39ed31-d808-4bf1-806d-fb4efa0fd2abn@googlegroups.com>
Injection-Info: google-groups.googlegroups.com; posting-host=2607:f2c0:9577:4a00:af5f:c100:f9d0:c13a;
posting-account=KOfC_woAAAC0YBGf-3r2aV5g2Aifd9jO
NNTP-Posting-Host: 2607:f2c0:9577:4a00:af5f:c100:f9d0:c13a
References: <dc39ed31-d808-4bf1-806d-fb4efa0fd2abn@googlegroups.com>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <05126034-3cda-4193-ba10-8fc6fc5712ban@googlegroups.com>
Subject: Re: Another new CP/M utility program: copyq
From: fridtjof.martin.weigel@gmail.com (fridtjof.ma...@gmail.com)
Injection-Date: Sun, 04 Jun 2023 19:13:21 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
 by: fridtjof.ma...@gmail - Sun, 4 Jun 2023 19:13 UTC

Ladislau

Now, I took an old program called CHDIR, and renamed it to CREDIR (from TOPS-10 CREATE DIRECTORY, that being where most of CP/M command design is from.... like PIP and DIR). This is HiTech C, but is "special" in that it updates itself, in place with the database of Drive/User to Name. It also has the "system password" in it... The directory and/or password could be masked with XOR PASSWORD if you want a bit more security. Have fun with this...

Find attached: <-->snip
/* CREDIR.C
*
* Also the database for directory information, and system password
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <cpm.h>
#include <unixio.h>
#include <sys.h>

#define defname "0:A:CREDIR.COM"
#define dirmax 64
/* #define syspass "password" */
#define syspass "bf109g"
#define sysuser 15
#define tryent 1
#define tryset 3

static char pass[21];

static char spass[21] = syspass;
/*
static char directory[dirmax][9] = { "SYS" };
static char dirdisk[dirmax] = { 'A' };
static char dirun[dirmax] = { 0 };
*/
static char directory[dirmax][9] = {
"SYS", "C", "GAMES", "SYSB",
"BAKSYS", "BAKC", "BAKGAMES", "SBASIC",
"BBCBASIC", "PROFOR", "SSFORT", "BASIC/Z" };
static char dirdisk[dirmax] = {
'A', 'A', 'A', 'B',
'E', 'E', 'E', 'E',
'E', 'E', 'E', 'E' };
static char dirun[dirmax] = {
0, 2, 3, 0,
0, 2, 3, 4,
5, 6, 7, 8 };
static char cend = 0;

static int tou(int c) {
if (islower(c))
return toupper(c);
return c;
}

static void strcap(char *str) {
while (*str) {
*str = tou(*str);
++str;
}
}

#if 0
static int strscan(char *str) {
while (*str)
if (*str++ == '.')
return 1;
return 0;
} #endif

static int tonum(char *str) {
int value, digit;
value = 0;
while (*str) {
digit = *str++ - '0';
if ((digit < 0) || (digit > 9))
return -1; /* Error */
value = value * 10 + digit;
}
return value;
}

static void help(void) {
printf("\nCREDIR\n\n");
printf("CREDIR is a program used to name drive/user areas, logically,\n");
printf("rather than by letter/number. From TOPS-10.\n\n");
printf(" CREDIR dirname select directory\n");
printf(" CREDIR dirname du name directory for disk d user u\n");
printf(" CREDIR /PRINT print name of current disk/user\n");
printf(" CREDIR /DISPLAY display all known names\n");
printf(" CREDIR /SETUP enter interactive setup\n");
printf(" CREDIR /HELP print HELP information\n");
}

static void disp2(void) {
int un, defined, dir;
char disk;
printf("\nCurrent Directory");
un = bdos(32, 0xff);
disk = bdos(25, 0) + 'A';
defined = 0;
printf(" %c%d: ", disk, un);
for (dir = 0; dir < dirmax; ++dir)
if ((dirdisk[dir] == disk) && (dirun[dir] == un)) {
printf("%s", directory[dir]);
defined = 1;
}
if (defined == 0)
printf("Not defined by name");
printf("\n");
}

static void display(int flag) {
/* If flag == 0, only display system files if in system dir */
int count, dir, user;
user = bdos(32, 0xff); /* Get current user number */
printf("\nDefined Directory Names");
count = 0;
for (dir = 0; dir < dirmax; ++dir) {
if ((directory[dir][0]) &&
((user >= sysuser) ||
(flag) ||
(dirun[dir] < sysuser))) {
if (count % 4 == 0)
printf("\n");
printf("%c%2d: %8s ",dirdisk[dir], dirun[dir],
directory[dir]);
}
if (directory[dir][0])
++count;
}
printf("\n%d directory names defined, space left for %d more names\n",
count, dirmax - count);
disp2();
}

static void dots(int num) {
int i;
for (i = 0; i < num; ++i)
putchar('.');
for (i = 0; i < num; ++i)
putchar('\010');
}

static void password(int n) {
int i;
if (bdos(32, 0xff) >= sysuser)
return;
printf("\n\n** System password required for access/permission **");
for (i = 0; i < n; ++i) {
printf("\nSystem Password? ");
dots(20);
scanf("%s", pass);
if (strlen(pass) > 20) {
printf("\n** Violation attempt **");
exit(-1);
}
if (strcmp(spass, pass) == 0) {
printf("** Access granted **");
return;
}
printf("Invalid password given");
}
printf("\n** Access denied **");
exit(-1);
}

static int cdir(char *dirname) {
int dir, index;
unsigned udflag;
unsigned char *p = (unsigned char *)0x004;
index = -1;
for (dir = 0; dir < dirmax; ++dir)
if (strcmp(directory[dir], dirname) == 0)
index = dir;
if (index == -1) {
printf("\nCan't find directory");
display(0);
return -1;
}
if (dirun[index] >= sysuser)
password(tryent);
udflag = dirun[index] << 4;
udflag |= dirdisk[index] - 'A';
*p = udflag;
setuid(dirun[index]); /* for SH.COM */
return 0;
}

static int yn(void) {
char s[20];
printf(" (Y/N)? ");
dots(3);
scanf("%s", s);
return tou(s[0]) == 'Y';
}

static void initdir(void) {
int i;
printf("Verify initialization");
if (!yn()) {
printf("\nInitialization aborted");
return;
}
strcpy(spass, syspass);
for (i = 0; i < dirmax; ++i) {
directory[i][0] = '\0';
dirdisk[i] = '\0';
dirun[i] = 0;
}
printf("\nDirectory cleared");
}

static int finddir(void) {
int dir;
for (dir = 0; dir < dirmax; ++dir)
if (directory[dir][0] == '\0')
return dir;
return -1;
}

static int setdir(void) {
int un, repl, dir;
char disk, name[20];
printf("\n\tDisk and user (Q=Done or A-P 0-15, like A10)? ");
scanf("%s", name);
if (strlen(name) == 0)
return 1;
disk = tou(name[0]);
if (disk == 'Q')
return 1;
if ((disk < 'A') || (disk > 'P')) {
printf("\nInvalid disk");
return 0;
}
if ((un = tonum(name + 1)) == -1)
return 1;
if ((un < 0) || (un > 15)) {
printf("\nInvalid user");
return 0;
}
do {
printf("Directory name (. = Delete old name)? ");
dots(8);
scanf("%s", name);
strcap(name);
if (strlen(name) > 8)
printf("Directory name too long\n");
} while (strlen(name) > 8);
if (name[0] == '.')
name[0] = '\0';
repl = 0;
for (dir = 0; dir < dirmax; ++dir)
if ((dirdisk[dir] == disk) && (dirun[dir] == un)) {
repl = dir;
directory[dir][0] = '\0';
}
if (repl == 0) {
repl = finddir();
if (repl == -1) {
printf("\nDirectory full");
return 1;
}
}
dirdisk[repl] = '\0';
dirun[repl] = 0;
if (strlen(name)) {
dirdisk[repl] = disk;
dirun[repl] = un;
strcat(directory[repl], name);
return 0;
}
printf("\nDirectory name for %c%2d: deleted", disk, un);
return 0;
}

static void swap(int i, int j) {
char disk, name;
int un, k;
disk = dirdisk[i];
dirdisk[i] = dirdisk[j];
dirdisk[j] = disk;
un = dirun[i];
dirun[i] = dirun[j];
dirun[j] = un;
for (k = 0; k < 9; ++k) {
name = directory[i][k];
directory[i][k] = directory[j][k];
directory[j][k] = name;
}
}

static void compare(int i, int j) {
if (dirdisk[i] < dirdisk[j])
return;
if (dirdisk[i] > dirdisk[j]) {
swap(i, j);
return;
}
if (dirun[i] > dirun[j])
swap(i, j);
}

static void sort(void) {
int i, j;
for (i = 0; i < dirmax; ++i)
for (j = i + 1; j < dirmax; ++j)
if (dirdisk[i] && dirdisk[j])
compare(i, j);
}

static void sethlp(void) {
printf("CREDIR Setup subsystem command summary\n");
printf(" D - Display currently-defined directory names\n");
printf(" I - Initialize and clear all directory names\n");
printf(" N - Create a new directory name\n");
printf(" P - Set system password\n");
printf(" Q - Quit without changing program on disk\n");
printf(" S - Sort directory by disk and user number\n");
printf(" X - Exit and update program on disk\n");
}

static int writepgm(char *fname) {
int fd;
unsigned u;
printf("\nSorting directory by disk and user number");
sort();
printf("\nUpdating file %s ...", fname);
fd = open(fname, O_RDWR);
if (fd < 0) {
printf("\nCan't open file %s", fname);
return -1;
}
u = (unsigned)&cend - (unsigned)spass;
lseek(fd, (long)spass - (long)0x100, SEEK_SET);
write(fd, (void *)spass, u);
close(fd);
printf("File %s updated to disk (%d bytes)\n", fname, u);
}

static void readpgm(void) {
int fd;
unsigned u;
fd = open("0:A:CREDIR.COM", O_RDWR);
if (fd < 0)
return;
u = (unsigned)&cend - (unsigned)directory;
lseek(fd, (long)directory - (long)0x100, SEEK_SET);
read(fd, (void *)directory, u);
close(fd);
}

/* Set up Mnemonic Names */

static void setup(void) {
char cmd, fname[40];
printf("\nCREDIR setup");
password(tryset); /* Ask for password */
do {
printf("\nSetup command (? for help)? ");
dots(2);
scanf("%s", fname);
cmd = tou(fname[0]); /* Get Response */
switch (cmd) {
case 'D':
printf("\nSystem password is %s", spass);
printf("\nProgram is %s", defname);
display(1);
break;
case 'I':
initdir();
break;
case 'N':
printf("\nSystem user areas start at %d", sysuser);
while (setdir() == 0)
;
break;
case 'P':
printf("\nNew system password? ");
dots(20);
scanf("%s", spass);
break;
case 'Q':
printf("\tVerify abort");
if (yn())
return;
break;
case 'S':
sort();
printf("\nSort complete"); break;
case 'X':
break;
default:
sethlp();
break;
}
} while (cmd != 'X');
printf("\tUpdate disk");
if (!yn())
return;
/*
printf("\nName of file (. = %s)? ", defname);
dots(12);
scanf("%s", fname);
strcap(fname);
if (fname[0] == '.')
strcpy(fname, defname);
if (strscan(fname) == 0)
strcat(fname, ".COM");
writepgm(fname);
*/
writepgm("0:A:CREDIR.COM");
}

static int scandir(char *name) {
int dir;
for (dir = 0; dir < dirmax; ++dir)
if (strcmp(directory[dir], name) == 0)
return -1;
return 0;
}

static int set(char *dirname, char *duser) {
char disk, *dutemp;
int un, dir;
dutemp = duser;
disk = *duser;
if ((disk < 'A') || (disk > 'P')) {
printf("\nInvalid disk (not A-P)");
return -1;
}
un = tonum(++dutemp);
if ((un < 0) || (un > 31)) {
printf("\nInvalid user (not 0-31)");
return -1;
}
if (scandir(dirname)) {
printf("Duplicate directory name");
return -1;
}
if (un >= sysuser)
password(tryset);
dir = finddir();
if (dir == -1) {
printf("\nDirectory Full");
return -1;
}
strcpy(directory[dir], dirname);
dirdisk[dir] = disk;
dirun[dir] = un;
writepgm(/* defname */ "0:A:CREDIR.COM");
return 0;
}

static void option(char *s) {
++s;
if (*s == 'D' || *s == 'd')
display(0);
else if (*s == 'S' || *s == 's')
setup();
else if (*s == 'P' || *s == 'p')
disp2();
else
help();
}

int main(int argc, char **argv) {
readpgm();
if (argc == 2) {
if (*argv[1] == '/')
option(argv[1]);
else
cdir(argv[1]);
} else if (argc == 3) {
set(argv[1], argv[2]);
} else {
help();
}
return 0;
}

SubjectRepliesAuthor
o Another new CP/M utility program: copyq

By: ladislau szilagyi on Sun, 28 May 2023

4ladislau szilagyi
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor