[comp.sources.misc] uupc.mac.8.4

Stuart.Lynne@van-bc.UUCP (Stuart Lynne) (08/17/87)

>From uucp Wed Aug 12 02:43 PDT 1987
>From slynne  Wed Aug 12 02:42:15 1987 remote from slmac
Received: by van-bc.uucp (smail2.3)
	id AA17598; 12 Aug 87 02:42:15 PDT (Wed)
Received: by slmac.vnet.van-bc.uucp (pcmail) Wed Aug 12 02:37:52 1987
Date: Wed Aug 12 02:37:52 1987
From: Stuart Lynne - test a mac <slynne@slmac.vnet.van-bc.uucp>
Message-ID: <149@slmac.vnet.van-bc.uucp>
To: sl@van-bc
Subject: shar/uupc.mac.8.4

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	mac/README.MAC
#	mac/Makefile.mac
#	mac/host.c
#	mac/host.h
#	mac/mlib.c
#	mac/ulib.c
#	mac/profile
#	mac/ndir.h
# This archive created: Wed Aug 12 02:02:50 1987
# By:	Stuart Lynne - test a mac ()
export PATH; PATH=/bin:$PATH
if test -f 'mac/README.MAC'
then
       echo shar: will not over-write existing file "'mac/README.MAC'"
else
cat << \SHAR_EOF > 'mac/README.MAC'
mac 			June 8, 1987		Stuart Lynne

For Beta implementors only.

uupc incorporates a streamlined version of dcp to implement a uucp mail
and news delivery system. 

See README.DCP for dcp info.
See README.UU for overview of this version.

This directory implements the macintosh version of host support routines. 
It runs under the Aztec Shell environment.

By moving the host dependant code into one file the other four dcp files can 
hopefully be maintained easily. It should be possible to maintain one version
of them which compiles and runs on all machines without conditional compilation
flags.

To simplify things for other systems (Atari) use of -D in the cc command is
not used. Instead various small files are used to set flags and then include
a common file.

host.h 			- include <host/host.h>
mailhost.c		- define MAIN mailmain; include <host/host.h>
mlib.c			- include <host/mlib.c>
ulib.c			- include <host/ulib.c>
uuhost.c		- define MAIN mailmain; include <host/host.h>

mac/host.c 		- generic macintosh host, calls MAIN
mac/host.h 		- macintosh host header file
mac/mlib.c 		- mail library
mac/ulib.c 		- uupc library

mac/profile		- a sample aztec profile file to set environment varialbes

There is actually fairly little code here. I have a separate set of library 
routines for doing the standard things like directory support. See 
the shar file for the Macintosh library (maclib.shar).

A separate uux command is included in uupc for the Macintosh (not finished yet).
Called macbin it copies a MacBinary image from stdin to a Macintosh file.
This allows macintosh files, including both forks and the finder info to be
stored in a single file on the remote system. It can then be retrieved by:

	uux macfile > remotemac!macbin

A standalone macbin will be available to convert a Macintosh file into a
flat file with the MacBinary image.

For more information, bug fixes, more commands etc:

		Stuart.Lynne@van-bc.uucp
		604-937-7532



PS. July 29/87

See the Amiga version for a genv.c that gets environment var's from
a profile file directly. I havn't had time to try on mac yet. 

I have made a VERY PRELIMINARY start at a standalone version, but have
not completed it yet. I hope to get more time to work on this early
in the fall. In the meantime anyone who could get this running as a Mac
application.... please feel free. And send me the changes.

sl

SHAR_EOF
chmod +x 'mac/README.MAC'
fi # end of overwriting check
if test -f 'mac/Makefile.mac'
then
       echo shar: will not over-write existing file "'mac/Makefile.mac'"
else
cat << \SHAR_EOF > 'mac/Makefile.mac'
#		Makefile for uupc/dcp with Macintosh Aztec C
#
#		Stuart Lynne
#		May/87
#


.c.o:
	cc $(CFLAGS) $*.c

#LFLAGS= -M -lx /usr/lib/mixcroot.o -lc
#CFLAGS= -E200 -DSTANDALONE
LFLAGS= -lx -lc
CFLAGS= -E200 -Y200
LIBS=

OFILES= dcp.o dcpsys.o dcpxfer.o dcpgpkt.o rmail.o \
		  lib.o


all:	 uupc mail
	echo uupc & mail done

#
# .o dependicies
#
dcp.o: dcp.c dcp.h local/host.h
dcpsys.o: dcpsys.c dcp.h local/host.h
dcpxfer.o: dcpxfer.c dcp.h local/host.h
dcpgpkt.o: dcpgpkt.c dcp.h local/host.h
lib.o: lib.c local/host.h
lmail.o: pcmail.c lmail.c local/host.h
mailhost.o: local/host.c local/host.h
mail.o: local/host.h
mlib.o: local/mlib.c local/host.h
ulib.o: local/ulib.c local/host.h
uuhost.o: local/host.c local/host.h

#
# mail
#
mail: lmail.o mailhost.o mail.o mlib.o lib.o Makefile
	ln mailhost.o mail.o lmail.o mlib.o lib.o $(LIBS) $(LFLAGS) -o mail

#
# uupc
#
uupc:	uuhost.o $(OFILES) ulib.o lib.o Makefile
	ln uuhost.o ulib.o $(OFILES) $(LIBS) $(LFLAGS) -o uupc

#
# simple shar constructing
#
SDCP 	=  dcp.c dcp.h dcpgpkt.c dcpsys.c dcpxfer.c

SUU		= host.h lib.c lmail.c mail.c mailhost.c mlib.c \
		ndir.h pcmail.c rmail.c ulib.c uuhost.c systems

SREAD	= README.DCP README.UUPC README.PORT README.INFO  

SMAC	= mac/README.MAC mac/Makefile.mac\
		mac/host.c mac/host.h mac/mlib.c mac/ulib.c mac/profile \
		mac/ndir.h

SST		= st/README.ST \
		st/host.c st/host.h  \
		st/c.mm st/cu.mm st/dirsubs.c st/dmymath.c st/env.mm \
		st/fgets.c st/genv.c st/getargs.c st/getenv.c \
		st/getone.c st/host.c st/host.h \
		st/inoutpth.c st/ldcp.mm \
		st/l.mm st/l1.mm st/ldcp.mm st/lmail.mm \
		st/ndir.c st/ndir.h st/printmsg.c st/readme.st st/shell.c \
		st/startup.mm st/time.c st/utar.mm st/uu.mm st/uuar.mm \
		st/uusup.c  st/zdcp.h st/zgenv.h st/zzgenv.h \
		st/zhost.h st/zzhost.h st/zmailhos.c st/zzmailhost.c \
		st/zndir.h st/zzndir.h st/zztime.h st/zuuhost.c 


SAMI	= amiga/README.Amiga amiga/Makefile.ami amiga/Makefile \
		amiga/chdir.c amiga/genv.c amiga/genv.dyna \
		amiga/genv.h amiga/getcwd.c amiga/host.c amiga/host.h \
		amiga/mkdir.c amiga/mlib.c \
		amiga/ndir.c amiga/ndir.h \
		amiga/SerialIO.c amiga/sio.c \
		amiga/sleep.c amiga/Timer.c amiga/ulib.c

SDOS	= dos/README.DOS dos/Makefile.dos \
		dos/comm.asm dos/comm.h \
		dos/host.c dos/host.h \
		dos/mlib.c dos/ndir.c dos/ndir.h \
		dos/setup.bat dos/ulib.c

shar: shar/uupc.dcp.8.3 shar/uupc.uu.8.2 shar/uupc.read.8.1 \
		shar/uupc.mac.8.4 shar/uupc.st.8.5 shar/uupc.ami.8.6 \
		shar/uupc.dos.8.7

shar/uupc.read.8.1: $(SUU)
	shar $(SREAD) > shar/uupc.read.8.1
shar/uupc.uu.8.2: $(SUU)
	shar $(SUU) > shar/uupc.uu.8.2
shar/uupc.dcp.8.3: $(SDCP)
	shar  $(SDCP) > shar/uupc.dcp.8.3
shar/uupc.mac.8.4: $(SMAC)
	cp Makefile mac/Makefile.mac
	shar $(SMAC) > shar/uupc.mac.8.4
shar/uupc.st.8.5: $(SST)
	shar $(SST) > shar/uupc.st.8.5
shar/uupc.ami.8.6: $(SAMI)
	shar $(SAMI) > shar/uupc.ami.8.6
shar/uupc.dos.8.7: $(SDOS)
	shar $(SDOS) > shar/uupc.dos.8.7

clean:
	rm *.o *.bak CC.TMP


SHAR_EOF
chmod +x 'mac/Makefile.mac'
fi # end of overwriting check
if test -f 'mac/host.c'
then
       echo shar: will not over-write existing file "'mac/host.c'"
else
cat << \SHAR_EOF > 'mac/host.c'
/*		mac.c

		macintosh host 

*/

#include <stdio.h>
#include "host.h"

#include <ctype.h>
#include <setjmp.h>
#include <errno.h>

char *curdir;
char * getcwd();
FILE * FOPEN();

int CHDIR();
int	debuglevel;		/* debugging level */

#ifdef STANDALONE
char *flds[10];
char line[128];

#define DMAILBOX	"mailbox"
#define	DNAME		""
#define DHOME		"/usr/guest"
#define	DDOMAIN		"pc.uucp"
#define	DMAILDIR	"/usr/mail"
#define	DCONFDIR	"/usr/lib/uucp"
#define	DSPOOLDIR	"/usr/spool/uucp"
#define DPUBDIR		"/usr/spool/uucppublic"
#define	DMAILSERVICE	"host"
#define	DNODENAME	""
#define	DDEVICE		".a"
#define	DSPEED		"1200"
#define	DTEMPDIR	"/tmp"

FILE *fe;

void sgenv(thename, envname, dflt)
char **thename;
char *envname;
char *dflt;
{
	char line[BUFSIZ];

	fprintf( stderr, "genv: %s %s\n", envname, dflt ); /**/
	
	if (fgets( line, BUFSIZ, fe ) == NULL) {
		fprintf( stderr, "genv: %s not found, using %s\n", envname, dflt ); /* */
		strcpy( *thename, dflt);
	}
	else {
		strcpy( *thename, line);
		fprintf( stderr, "genv: %s %s\n", envname, *thename ); /**/
	}
}

void sloadenv()
{
	fprintf( stderr, "sloadenv\n" );
	if ( (fe = FOPEN( "/usr/lib/uucp/defaults", "r" )) == (FILE *) NULL ) {
		fprintf( stderr, "can't open /usr/lib/uucp/defaults  %d\n", errno );
		exit( -1 );
	}
	fprintf( stderr, "sloadenv - fopened\n" );
	/* get environment var's */
	sgenv( &name, NAME, DNAME );
	sgenv( &mailbox, MAILBOX, DMAILBOX );
	sgenv( &nodename, NODENAME, DNODENAME );
	sgenv( &home, HOME, DHOME );
	sgenv( &domain, DOMAIN, DDOMAIN );
	sgenv( &maildir, MAILDIR, DMAILDIR );
	sgenv( &confdir, CONFDIR, DCONFDIR );
	sgenv( &spooldir, SPOOLDIR, DSPOOLDIR );
	sgenv( &pubdir, PUBDIR, DPUBDIR );
	sgenv( &mailserv, MAILSERVICE, DMAILSERVICE );
	sgenv( &device, DEVICE, DDEVICE );
	sgenv( &speed, SPEED, DSPEED );
	sgenv( &tempdir, TEMPDIR, DTEMPDIR );
}
#endif

jmp_buf	dcpexit;

char *gets();

main( argc, argv )
int	argc;
char *argv[];
{

	macinit();

#ifdef STANDALONE
	fprintf( stderr, "Please enter parameters: " );
	if ( gets( line ) == (char *) NULL )
		exit( -1 );
	getargs( line, flds );
	argv = flds;
	/* mac specific prolog */
	sloadenv();
#else
	/* mac specific prolog */
	loadenv();
#endif
	
	
	curdir = getcwd( NULL, 0 );

#ifdef CWDSPOOL
	CHDIR( spooldir );
#endif

	/* setup longjmp for error exit's */
	if ( setjmp( dcpexit ) == 0 ) {

		MAIN( argc, argv );

	}
	

	/* mac specific epilog */
	chdir( curdir );

}


/* canonical name conversio routines

	importpath	canonical -> host
	exportpath	host -> canonical

	host		your local pathname format
	canonical	unix style
*/

importpath( host, canon )
char * host;
char * canon;
{
	sprintf( host, "%s", canon );
}

exportpath( canon, host )
char * host;
char * canon;
{


}



SHAR_EOF
chmod +x 'mac/host.c'
fi # end of overwriting check
if test -f 'mac/host.h'
then
       echo shar: will not over-write existing file "'mac/host.h'"
else
cat << \SHAR_EOF > 'mac/host.h'
 /*		mac.h

		Macintosh version

*/

/*#include <local/genv.h>*/
#include <genv.h>
#include <time.h>
#include <errno.h>
#include <ctype.h>

#define SAME 	0
#define	FALSE	0
#define	TRUE	1

#define	TFILENAME	"tmpfile.%.7d"
#define	SFILENAME	"SEQF"

#define SEPCHAR		'/'	/* path separater character		*/
#define SIGFILE		".signature"	/* file containing signature	*/
#define COPYFILE	"Mail/mail.sent"	/* copy of sent mail	*/
#define NEWSDIR		"/usr/spool/rnews/%02d%02d%02d%02d%02d%02d.%03d"

#define HOSTINIT	macinit()	/* name of function used to initialize	*/

#define FILEMODE(f)

#define	CALLFILE	"C."
#define	XQTFILE		"X."

#include <local/genv.h>
extern	char * fgets();
extern	char * index();

extern 	int	debuglevel;                  /* debuglevelging level */


SHAR_EOF
chmod +x 'mac/host.h'
fi # end of overwriting check
if test -f 'mac/mlib.c'
then
       echo shar: will not over-write existing file "'mac/mlib.c'"
else
cat << \SHAR_EOF > 'mac/mlib.c'
/*		lib.c


		macintosh library
		

	Things to do in uu host

		serial I/O
		
		directory stuff
			opendir, readdir, closedir

		prolog and epilog

		system call

*/

#include <stdio.h>
#include "host.h"
#include <sgtty.h>

int get_one()
{
	char c;
	
	struct sgttyb stty, sttyo;
	ioctl( 0, TIOCGETP, &stty );
	sttyo = stty;
	stty.sg_flags |= CBREAK;
	stty.sg_flags &= ~ ECHO;
	ioctl( 0, TIOCSETP, &stty );
	c = fgetc( stdin );
	ioctl( 0, TIOCSETP, &sttyo );
	return( c );
}



SHAR_EOF
chmod +x 'mac/mlib.c'
fi # end of overwriting check
if test -f 'mac/ulib.c'
then
       echo shar: will not over-write existing file "'mac/ulib.c'"
else
cat << \SHAR_EOF > 'mac/ulib.c'
/*		ulib.c


		macintosh library
		

	Things to do in uu host

		serial I/O
		
		directory stuff
			opendir, readdir, closedir

		prolog and epilog

		system call

*/

#include <stdio.h>
#include "host.h"
#include <sgtty.h>



/**/
/*
 *
 *      login (for slave in PC mode)
 * Real dumb login handshake
*/
login()
{
	char	logmsg[132];
#ifdef PC
lretry:
	msgtime = 9999;
	rmsg(logmsg, 0); /* wait for a <CR> or <NL> */
	msgtime = 2 * MSGTIME;
	wmsg("Username:", 0);
	rmsg(logmsg, 0);
	printmsg( 0, "Username = %s", logmsg );
	wmsg("Password:", 0);
	rmsg(logmsg, 0);
	printmsg( 14, "Password = %s", logmsg );
	if (strcmp(logmsg, "uucp") != 0) 
		goto lretry;
#endif
	return('I');
}


char inbuf[BUFSIZ];
char outbuf[BUFSIZ];

swrite(data, num)
int	num;
char	*data;
{

	int test;
	unsigned char * cp;

	if (debuglevel > 14)
		fputc( '{', stderr );
	if (debuglevel > 14) {
		test = num;
		cp = data;
		while (test--)
			fprintf( stderr, isprint(*cp)? "{%c}":"{%02x}", *cp++ );
	}
	test = SIOWrite( data, num );
	if (debuglevel > 14)
		fputc( '}', stderr );
	return( test );

}

/* non-blocking read essential to "g" protocol */
/* see "dcpgpkt.c" for description */
/* This all changes in a mtask systems. Requests for */
/* I/O should get qued and an event flag given. Then the */
/* requesting process (e.g.gmachine()) waits for the event */
/* flag to fire processing either a read or a write. */
/* Could be implemented on VAX/VMS or DG but not MS-DOS */
sread(buf, num, timeout)
char	*buf;
int	num, timeout;
{
/*
	return( SIORead( buf, num, num, timeout*10 ) );
*/
	int count;
	int test;
	unsigned char * cp;

	if (debuglevel > 13)
		fputc( '[', stderr );
	printmsg( 15, "sread: num: %d  timeout: %d", num, timeout );
		
	count = SIORead( buf, num, num, timeout*10 );
	printmsg( 15, "sread: read: %d ", count );

	if (debuglevel > 13 && count > 0) {
		test = count;
		cp = buf;
		while (test--)
			fprintf( stderr, isprint(*cp)? "[%c]":"[%02x]", *cp++ );
	}
		
	if (debuglevel > 13)
		fputc( ']', stderr );
	return( count );	
	
}



openline(name, baud)
char	*name, *baud;
{

	printmsg( 3, "openline: name: \"%s\"  baud: \"%s\"", name, baud );
	SIOInit( name, baud );
	SIOInBuffer( inbuf, BUFSIZ );
	SIOOutBuffer( outbuf, BUFSIZ );
	return( 0 );
}


closeline()
{
	SIOClose( 1 );
}


nodot(string)
{
}



notimp( argc, argv )
char *argv[];
{
	/*debuglevelMsg("\Pcheck argc (08) and argv (0a) ");*/
	fprintf( stderr, "shell: %s not implemented\n", *argv );
}

/* 		shell


*/

char * getcwd();

shell( command, inname, outname, errname )
char * command;
char * inname;
char * outname;
{

	char	* argvec[50];

	int rmail();
	int rnews();
	int macbin();
	
	int 	argcp;

	char **argvp;
	char args;
	

	int	(*proto)();
	
	argcp = 0;

	argcp = getargs( command, argvec );

	argvp = argvec;
	args = argcp;

	if ( debuglevel > 5 ) {
		while ( args ) 
			fprintf( stderr, "arg: %d  %s\n", args--, *argvp++ );
		argvp = argvec;
		args = argcp;
	}
	/* */
	
	proto = notimp;

	if ( strcmp( *argvp, "rmail" ) == SAME )
		proto = rmail;

	else if ( strcmp( *argvp, "rnews" ) == SAME ) 
		proto = rnews;
	
	else if ( strcmp( *argvp, "macbin" ) == SAME ) 
		proto = macbin;
	
		
	if ( *inname != '\0' ) {
		/* fprintf( stderr, "reopening stdin as %s\n", inname );
		fprintf( stderr, "curdir: %s\n", getcwd(NULL, 0)); /* */
		if ( freopen( inname, "r", stdin ) == NULL ) 
			fprintf( stderr, "Couldn't open %s, %d\n", inname, errno );
	}
	(proto)( argcp, argvp );

	freopen( ".console", "r", stdin );

}


/*
	macbin

	copy a macbinary image from stdin into a macintosh file

		128 bytes of header information
		(n+128)/128*128 bytes of data fork data
		(n+128)/128*128 bytes of resource fork data

	The name is derived from the header information

	The directory is given as an arguement


	on remote system use:

		uux macfile.mb > remotemac!macbin /usr/sl


*/

#undef TRUE

#include <types.h>
#include <pb.h>

/* #include <stdio.h> */

typedef struct {
	/*
	char				blknum;
	char				mblknum;
	*/
	char				dummy;

	char				version;

	char				fName[64];
	FInfo				finderInfo;			/* check - starts on odd byte boundary */
	char				protected;
	char				ckZero1;
	long				dfLength;
	long				rfLength;
	long				crDat;
	long				mdDat;
	char				fill1[27];
	char				computer;
	char				os;
	} MacBinHeader;



int macbin( argc, argv )
int argc;
char *argv[];
{
#ifdef TESTETEST
	char	filename[132];
	char	buf[BUFSIZ];
	MacBinHeader mbh;
	long	count, size;
	int		i;

	HPrmBlkRec	pbr;

	/* get the header */
	fread( &mbh.version, 1, 128, stdin );


	/* create and open the file */
	strncpy( pbr.ioNamePtr, mbh.fName, 64 );
	pbr.ioVRefNum = 0;
	pbr.u.hfp.ioFVersNum = 0;
	PBCreate( &pbr, FALSE );


	/* get finder info */
	pbr.u.hfp.ioFDirIndex = 0;
	pbr.u.hfp.ioDirID = 0L;
	PBGetInfo( &pbr, FALSE );
	
	/* set finder info */
	pbr.u.hfp.ioFlFndrInfo.fdFldr = 0;
	pbr.u.hfp.ioFlCrDat = mbh.crDat;
	pbr.u.hfp.ioFlMdDat = mbh.mdDat;
	pbr.u.hfp.ioFlFndrInfo = mbh.finderInfo;
	PBSetInfo( &pbr, FALSE );

	/* get and write out the fork */
	pbr.u.iop.ioPermssn = 0;
	pbr.u.iop.ioMisc = 0L;
	for ( i = 1; i > 0 ; i-- ) {
		if (i == 1 ) {
			PBOpen( &pbr, FALSE );
			size = (mbh.dfLength + 127) & 0xffffff80;
		}
		else {
			PBROpen( &pbr, FALSE );
			size = (mbh.rfLength + 127) & 0xffffff80;
		}
		while ( size > 0 )
			if ( (count = fread( buf, 1, BUFSIZ, stdin )) != 0 ) {
				size -= count;
				pbr.u.iop.ioBuffer = buf;
				pbr.u.iop.ioReqCount = count;
				PBWrite ( &pbr, FALSE);
			}
		PBClose( &pbr, FALSE );
	}
#endif
}



SHAR_EOF
chmod +x 'mac/ulib.c'
fi # end of overwriting check
if test -f 'mac/profile'
then
       echo shar: will not over-write existing file "'mac/profile'"
else
cat << \SHAR_EOF > 'mac/profile'

set NAME="Stuart Lynne - test a mac"
set MAILBOX=slynne
set HOME=/usr/sl

set DOMAIN="slmac.vcr.bc.can"
set MAILSERVICE="van-bc"
set NODENAME=slmac


SHAR_EOF
chmod +x 'mac/profile'
fi # end of overwriting check
if test -f 'mac/ndir.h'
then
       echo shar: will not over-write existing file "'mac/ndir.h'"
else
cat << \SHAR_EOF > 'mac/ndir.h'
/* @(#)ndir.h	1.4	4/16/85 */
#ifndef DEV_BSIZE
#define	DEV_BSIZE	512
#endif
#define DIRBLKSIZ	DEV_BSIZE
#define	MAXNAMLEN	255

struct	direct {
	long	d_ino;			/* inode number of entry */
	short	d_reclen;		/* length of this record */ 
	short	d_namlen;		/* length of string in d_name */
	char	d_name[MAXNAMLEN + 1];	/* name must be no longer than this */
};

/*
 * The DIRSIZ macro gives the minimum record length which will hold
 * the directory entry.  This requires the amount of space in struct direct
 * without the d_name field, plus enough space for the name with a terminating
 * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
 */

#ifdef DIRSIZ
#undef DIRSIZ
#endif /* DIRSIZ */
#define DIRSIZ(dp) \
    ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))

/*
 * Definitions for library routines operating on directories.
 */
/*
typedef struct _dirdesc {
	int	dd_fd;
	long	dd_loc;
	long	dd_size;
	char	dd_buf[DIRBLKSIZ];
} DIR;
*/
typedef struct _dirdesc {
	int 	ioVRefNum;
	long	ioDrDirID;
	int		ioFDirIndex;
} DIR;
#ifndef NULL
#define NULL 0L
#endif
extern	DIR *opendir();
extern	struct direct *readdir();
extern	void closedir();
extern char * getcwd();

SHAR_EOF
chmod +x 'mac/ndir.h'
fi # end of overwriting check
#	End of shell archive
exit 0

--
{ubc-vision,uunet}!van-bc!sl				Stuart.Lynne@van-bc.uucp