diff --git a/connect.c b/connect.c index c64cef1..f285c8f 100644 --- a/connect.c +++ b/connect.c @@ -72,6 +72,7 @@ static gid_t *act_grouplist=NULL; /* first element is counter !! */ static int connect_is_init = 0; #define MAX_DIRHANDLES 80 +#define EXPIRE_COST 86400 /* Is one day enough? :) */ typedef struct { DIR *f; @@ -629,15 +630,18 @@ static DIR *give_dh_f(DIR_HANDLE *dh) *(dh->kpath) = '\0'; dh->f = opendir(dh->unixname); } + dh->timestamp=time(NULL); /* tnx to Andrew Sapozhnikov */ return(dh->f); } -static void release_dh_f(DIR_HANDLE *dh) +static void release_dh_f(DIR_HANDLE *dh, int expire) { if (dh->f && (dh->vol_options & VOL_OPTION_REMOUNT) ) { closedir(dh->f); dh->f = NULL; } + if (expire) + dh->timestamp-=EXPIRE_COST; /* tnx to Andrew Sapozhnikov */ } static int get_dh_entry(DIR_HANDLE *dh, @@ -667,7 +671,7 @@ static int get_dh_entry(DIR_HANDLE *dh, while (dh->sequence < *sequence) { if (NULL == readdir(f)) { dh->dirpos = telldir(f); - release_dh_f(dh); + release_dh_f(dh, 1); return(0); } dh->sequence++; @@ -709,7 +713,7 @@ static int get_dh_entry(DIR_HANDLE *dh, dh->kpath[0] = '\0'; *sequence = dh->sequence; dh->dirpos = telldir(f); - release_dh_f(dh); + release_dh_f(dh, (dirbuff==NULL)); } /* if */ return(okflag); } @@ -979,6 +983,29 @@ int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle, return(completition); } +int conn_get_full_path(int dirhandle, uint8 *data, int len, + uint8 *fullpath) +/* returns path in form VOLUME:PATH */ +{ + NW_PATH nwpath; + int result = build_path(&nwpath, data, len, 0); + fullpath[0]='\0'; + if (!result) + result = build_verz_name(&nwpath, dirhandle); + if (result > -1) { + uint8 *p=(*nwpath.path=='/') ? nwpath.path+1 : nwpath.path; + int len=sprintf(fullpath, "%s:%s", + nw_volumes[nwpath.volume].sysname, p); + if (nwpath.fn[0]) { + if (*p) fullpath[len++]='/'; + strcpy(fullpath+len, nwpath.fn); + } + result=len+strlen(nwpath.fn); + } + XDPRINTF((1, 0, "conn_get_full_path: result=%d,(0x%x),`%s`", result, result, fullpath)); + return(result); +} + int conn_get_kpl_unxname(char *unixname, int dirhandle, uint8 *data, int len) @@ -1048,7 +1075,7 @@ time_t nw_2_un_time(uint8 *d, uint8 *t) s_tm.tm_hour = hour; s_tm.tm_min = minu; s_tm.tm_sec = sec; - s_tm.tm_isdst = -1; + s_tm.tm_isdst = -1; return(mktime(&s_tm)); } @@ -1223,14 +1250,14 @@ static int do_set_file_info(NW_PATH *nwpath, FUNC_SEARCH *fs) struct stat statb; #if PERSISTENT_SYMLINKS S_STATB stb; -#endif +#endif ut.actime = ut.modtime = nw_2_un_time(f->modify_date, f->modify_time); if ( 0 == (result=s_stat(unname, &statb, &stb)) && 0 == (result=s_utime(unname, &ut, &stb))){ - result = s_chmod(unname, + result = s_chmod(unname, un_nw_attrib(&statb, (int)f->attrib, 1), &stb); } - if (result) + if (result) result= (-0x8c); /* no modify rights */ } XDPRINTF((5,0,"set_file_info result=0x%x, unname:%s:", unname, -result)); @@ -1263,7 +1290,7 @@ int nw_chmod_datei(int dir_handle, uint8 *data, int len, NW_PATH nwpath; #if PERSISTENT_SYMLINKS S_STATB stb; -#endif +#endif build_path(&nwpath, data, len, 0); if (nwpath.fn[0] != '.') { /* Files with . at the beginning are not ok */ completition = build_verz_name(&nwpath, dir_handle); @@ -1271,12 +1298,12 @@ int nw_chmod_datei(int dir_handle, uint8 *data, int len, if (completition < 0) return(completition); strcpy(unname, build_unix_name(&nwpath, 2)); XDPRINTF((5,0,"set file attrib 0x%x, unname:%s:", access, unname)); - + if (!s_stat(unname, &stbuff, &stb)){ int result = s_chmod(unname, un_nw_attrib(&stbuff, access, 1), &stb); return( (result != 0) ? -0x8c : 0); /* no modify rights */ } - + return(-0x9c); /* wrong path */ } @@ -1296,7 +1323,10 @@ int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode) chmod(unname, act_umode_dir); return(0); } - completition = -0x84; /* No Create Priv.*/ /* -0x9f Direktory Aktive */ + if (errno == EEXIST) + completition = -0xff; + else + completition = -0x84; /* No Create Priv.*/ /* -0x9f Direktory Aktive */ } else { /* rmdir */ int j = -1; while (++j < (int)anz_dirhandles){ @@ -1509,13 +1539,13 @@ int nw_init_connect(void) while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))) { if (what == 6) { /* version */ - if (2 != sscanf((char*)buff, "%d %x", + if (2 != sscanf((char*)buff, "%d %x", &tells_server_version, - &server_version_flags)) + &server_version_flags)) server_version_flags=0; } else if (what == 8) { /* entry8_flags */ entry8_flags = hextoi((char*)buff); - } else if (what == 9) { /* GID */ + } else if (what == 9) { /* umode */ int umode_dir, umode_file; if (2 == sscanf((char*)buff, "%o %o", &umode_dir, &umode_file)) { default_umode_dir = umode_dir; diff --git a/connect.h b/connect.h index 8eaad62..a710f1e 100644 --- a/connect.h +++ b/connect.h @@ -213,6 +213,9 @@ extern int act_umode_file; extern int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle, uint8 *data, int len, int only_dir) ; +extern int conn_get_full_path(int dirhandle, uint8 *data, int len, + uint8 *fullpath); + extern int conn_get_kpl_unxname(char *unixname, int dirhandle, uint8 *data, int len); diff --git a/doc/CHANGES b/doc/CHANGES index a617ff5..49bbdba 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -346,17 +346,32 @@ Erste 'oeffentliche' Version - 'Home Volumes' werden nun generell als 'remountable' behandelt. - Bindery Pfad kann nun in section 45 bestimmt werden. - File-sharing abgeaendert. -- Internen Router Code fuer SAP Anfragen des internen Netzes (slist usw.) +- Internen Router Code fuer SAP Anfragen des internen Netzes (slist usw.) korrigiert. <----- ^^^^^^^^^^ pl0 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- namespace routine delete file/dir um wildcardhandling erweitert fuer +- namespace routine delete file/dir um wildcardhandling erweitert fuer client32. (W95) - einfache Semaphore Routinen eingebaut. - Routine 0x16,0x2f eingebaut. (fuer Pete) -- Quota Support wieder zum Laufen gebracht. - Durch Bindery Security Fixes funktionierte Quota Support +- Quota Support wieder zum Laufen gebracht. + Durch Bindery Security Fixes funktionierte Quota Support nicht mehr. -- im MAIL Verzeichnis werden nun im Unterverzeichnis user symbolische Links +- im MAIL Verzeichnis werden nun im Unterverzeichnis user symbolische Links der Login Namen erzeugt. +- Print queue handling stark veraendert. <----- ^^^^^^^^^^ pl1 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- Nested FINDFIRST/FINDNEXT bug korrigiert durch Andrew Sapozhnikov. +- getpwnam/getspnam problem gefixed durch Leslie. +- Neues queue handling funktioniert nun auch mit netx. + Die Queue-job-id wird nun bei den 'neuen' calls, obwohl eigentlich + 4 Byte gross, immer als 2 Byte Zahl behandelt. +- Resultcode in close_queue_job2() (nwqconn.c) korrigiert. Es wurde + immer Fehlercode zurueckgeliefert wodurch der capture aufgehoben + wurde. +- creat directory liefert nun bei EEXIST 0xff zurueck. +- pserver Unterstuetzung erweitert. +- creat queue, destroy queue Calls eingebaut. +- Routine nw_add_obj_to_set traegt nun keine doppelten Eintraege in das Set + ein. +<----- ^^^^^^^^^^ pl2 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/CREDITS b/doc/CREDITS index 0758575..6805ddb 100644 --- a/doc/CREDITS +++ b/doc/CREDITS @@ -46,6 +46,9 @@ Ruedi Kneubuehler Volker Lendecke helps distributing +Leslie + fixed getpwnam/getspnam problem. + Ambrose Li gave hints, patches, docs @@ -67,6 +70,9 @@ Jiri A. Randus Mark Robson fixed bindery security hole and added bindery options +Andrew Sapozhnikov + fixed findfirst/findnext bug + Gregory Steuck testings and errorreports @@ -76,7 +82,7 @@ Morio Taneda Erik Thiele testings and doc -Winfried Truemper : +Winfried Truemper : re-wrote `INSTALL' and added explanations to `nw.ini' diff --git a/doc/NEWS b/doc/NEWS index 62ff597..749d852 100644 --- a/doc/NEWS +++ b/doc/NEWS @@ -1,3 +1,5 @@ +------16-Aug-97--- 0.99.pl2 --------- +- new flag in section '8' for using ncpfs as mars_nwe client. ------16-Aug-97--- 0.99.pl1 --------- - print queue handling changed. (please look into examples/nw.ini) - simple semaphore calls added. diff --git a/doc/mars_nwe.lsm b/doc/mars_nwe.lsm index 080cbbc..e595b64 100644 --- a/doc/mars_nwe.lsm +++ b/doc/mars_nwe.lsm @@ -1,7 +1,7 @@ Begin3 Title: mars_nwe -Version: 0.99.pl1 -Entered-date: 31-Jul-97 +Version: 0.99.pl2 +Entered-date: 08-Oct-97 Description: Full netware-emulator (src), beta. Supports file-services, bindery-services, printing-services, routing-services. @@ -9,7 +9,7 @@ Keywords: novell, netware, server, ipx, ncp, tli Author: mstover@stover.f.eunet.de (Martin Stover) Maintained-by: mstover@stover.f.eunet.de (Martin Stover) Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs - 240kB mars_nwe-0.99.pl1.tgz + 250kB mars_nwe-0.99.pl2.tgz Alternate-site: sunsite.unc.edu:/pub/Linux/system/filesystems/ncpfs Platforms: Linux (1.2.xx, 1.3.xx, 2.xx), UnixWare (2.xx) Copying-policy: GNU diff --git a/examples/nw.ini b/examples/nw.ini index b69ca5e..e4d11d1 100644 --- a/examples/nw.ini +++ b/examples/nw.ini @@ -123,7 +123,7 @@ # # Examples: # 1 SYS /var/local/nwe/SYS k -# 1 CDROM /cdrom kmr +# 1 CDROM /cdrom kmor # 1 HOME ~ k 1 SYS /u3/SYS/ k @@ -384,6 +384,10 @@ # other process. # ( this was standard before mars_nwe-0.99.pl0 ) # +# 0x20 store file base entries for later use. +# Normally only directory base entries are stored. +# necessary if using ncpfs as mars_nwe client. +# # other flags may follow. # value will be interpreted as hex value. @@ -394,6 +398,7 @@ # # mkdir mode (creat mode directories), creat mode files # values are always interpreted as octal values ! +# if 0 is specified then the standard umask will be used. # 9 0755 0664 # 9 0755 0664 diff --git a/examples/xsockrt.c b/examples/xsockrt.c index 4fbfafc..a43169c 100644 --- a/examples/xsockrt.c +++ b/examples/xsockrt.c @@ -25,7 +25,8 @@ static int usage(char *prog) fprintf(stderr, "\tsocknr defaults to 0x869b (doom)\n"); fprintf(stderr, "\tother known sockets are:\n"); fprintf(stderr, "\t-0x8813 virgin games, Red Alert\n"); - fprintf(stderr, "\tdel 0 removes all socknr !!\n"); + fprintf(stderr, "\tadd 0 activates automatic add of socknr !!\n"); + fprintf(stderr, "\tdel 0 removes all socknr and deactivates automatic add !!\n"); return(1); } @@ -60,8 +61,6 @@ int main(int argc, char *argv[]) if (argc > 2 && 1 != sscanf(argv[2],"%i", &socknr)) return(usage(argv[0])); if (!strncasecmp(argv[1], "add", 3)) { - if (!socknr) - return(usage(argv[0])); return(handle_ioctl(1, socknr)); } else if (!strncasecmp(argv[1], "del", 3)) { return(handle_ioctl(0, socknr)); diff --git a/makefile.unx b/makefile.unx index 487d821..bf14934 100644 --- a/makefile.unx +++ b/makefile.unx @@ -1,5 +1,5 @@ #if 0 -#makefile.unx 09-Aug-97 +#makefile.unx 30-Aug-97 #endif VPATH=$(V_VPATH) @@ -9,7 +9,7 @@ C=.c V_H=0 V_L=99 -P_L=1 +P_L=2 #define D_P_L 1 DISTRIB=mars_nwe diff --git a/namspace.c b/namspace.c index 9b8cc57..b9f3f0d 100644 --- a/namspace.c +++ b/namspace.c @@ -400,8 +400,10 @@ static DIR_BASE_ENTRY *allocate_dbe_p(int namespace) } else { while (j && dir_base[--j]->locked) ;; } - if (S_ISDIR(dir_base[j]->nwpath.statb.st_mode)) + if (S_ISDIR(dir_base[j]->nwpath.statb.st_mode) + || (entry8_flags & 0x20) ) { put_dbe_to_disk(dir_base[j]); + } xfree(dir_base[j]); } else anz_dbe++; @@ -715,12 +717,13 @@ static int insert_get_base_entry(N_NW_PATH *nwpath, /* creat dir */ if (mkdir(unname, 0777)) result=-0x84; - else + else if (act_umode_dir) chmod(unname, act_umode_dir); } else { /* creat file */ if ((result = creat(unname, 0777)) > -1) { - chmod(unname, act_umode_file); + if (act_umode_file) + chmod(unname, act_umode_file); close(result); result = 0; } else result=-0x84; diff --git a/nwbind.c b/nwbind.c index f6587a9..854a5c6 100644 --- a/nwbind.c +++ b/nwbind.c @@ -1,5 +1,5 @@ /* nwbind.c */ -#define REVISION_DATE "26-Aug-97" +#define REVISION_DATE "08-Oct-97" /* NCP Bindery SUB-SERVER */ /* authentification and some message handling */ @@ -47,6 +47,14 @@ static void write_to_nwserv(int what, int connection, int mode, char *data, int size) { switch (what) { + case 0x4444 : /* tell the wdog there's no need to look 0 */ + /* activate wdogs to free connection 1 */ + /* the connection ist closed 99 */ + write(FD_NWSERV, &what, sizeof(int)); + write(FD_NWSERV, &connection, sizeof(int)); + write(FD_NWSERV, &mode, sizeof(int)); + break; + case 0x6666 : /* send to client that server holds message */ write(FD_NWSERV, &what, sizeof(int)); write(FD_NWSERV, &connection, sizeof(int)); @@ -61,13 +69,15 @@ static void write_to_nwserv(int what, int connection, int mode, } } +#define nwserv_reset_wdog(connection) \ + write_to_nwserv(0x4444, (connection), 0, NULL, 0) + #define nwserv_handle_msg(connection) \ write_to_nwserv(0x6666, (connection), 0, NULL, 0) #define nwserv_down_server() \ write_to_nwserv(0xffff, 0, 0, NULL, 0) - static int max_nw_vols=MAX_NW_VOLS; static int max_connections=MAX_CONNECTIONS; static CONNECTION *connections=NULL; @@ -715,7 +725,7 @@ static void handle_fxx(int gelen, int func) obj.type = GET_BE16(p); strmaxcpy((char*)obj.name, (char*)(p+3),(int) *(p+2)); upstr(obj.name); - result = scan_for_obj(&obj, last_obj_id); + result = scan_for_obj(&obj, last_obj_id, 0); if (!result){ U32_TO_BE32(obj.id, xdata->object_id); U16_TO_BE16(obj.type, xdata->object_type); @@ -1088,14 +1098,34 @@ static void handle_fxx(int gelen, int func) completition=0xfb; } break; - case 0x64 : { /* Create Queue */ - XDPRINTF((1, 0, "TODO:Create QUEUE ??")); - completition=0xfb; + case 0x64 : { /* Create Queue, prehandled by nwconn */ + int q_typ = GET_BE16(rdata); + int q_name_len = *(rdata+2); + uint8 *q_name = rdata+3; + /* inserted by nwconn !!! */ +#if 0 + int dummy = *(rdata+3+q_name_len); +#endif + int pathlen = *(rdata+3+q_name_len+1); + uint8 *path = rdata+3+q_name_len+2; + uint32 q_id; + int result = nw_creat_queue(q_typ, + q_name, q_name_len, + path, pathlen, &q_id); + if (result > -1) { + U32_TO_BE32(q_id, responsedata); + data_len=4; + } else + completition=(uint8)(-result); } break; - case 0x65 : { /* Delete Queue */ - XDPRINTF((1, 0, "TODO:Delete QUEUE ??")); - completition=0xfb; + case 0x65 : { /* Destroy Queue */ + uint32 q_id = GET_BE32(rdata); + int result=-0xd3; /* no rights */ + if (1 == act_c->object_id) + result=nw_destroy_queue(q_id); + if (result < 0) + completition=(uint8)(-result); } break; case 0x66 : { /* Read Queue Current Status,old */ @@ -1142,7 +1172,7 @@ static void handle_fxx(int gelen, int func) uint32 q_id = GET_BE32(rdata); uint32 job_id = (ufunc == 0x6A) ? GET_BE16(rdata+4) - : GET_BE32(rdata+4); + : GET_BE16(rdata+4); int result=nw_remove_job_from_queue( act_c->object_id, q_id, job_id); @@ -1161,16 +1191,6 @@ static void handle_fxx(int gelen, int func) } break; - case 0x6C : { /* Get Queue Job Entry old */ - uint32 q_id = GET_BE32(rdata); - int job_id = GET_BE16(rdata+4); - int result=nw_get_q_job_entry(q_id, job_id, - responsedata, 1); - if (result > -1) - data_len=result; - else completition=(uint8)-result; - } - break; case 0x68: /* creat queue job and file old */ case 0x79: { /* creat queue job and file new */ @@ -1190,12 +1210,25 @@ static void handle_fxx(int gelen, int func) } break; + case 0x6C : { /* Get Queue Job Entry old */ + uint32 q_id = GET_BE32(rdata); + int job_id = GET_BE16(rdata+4); + /* added by nwconn */ + uint32 fhandle = GET_BE32(rdata+8); + int result=nw_get_q_job_entry(q_id, job_id, fhandle, + responsedata, 1); + if (result > -1) + data_len=result; + else completition=(uint8)-result; + } + break; + case 0x69: /* close file and start queue old ?? */ case 0x7f: { /* close file and start queue */ uint32 q_id = GET_BE32(rdata); uint32 job_id = (ufunc==0x69) ? GET_BE16(rdata+4) - : GET_BE32(rdata+4); + : GET_BE16(rdata+4); int result = nw_close_queue_job(q_id, job_id, responsedata); if (result > -1) @@ -1237,7 +1270,7 @@ static void handle_fxx(int gelen, int func) uint32 q_id = GET_BE32(rdata); uint32 job_id = (ufunc==0x78) ? GET_BE16(rdata+4) - : GET_BE32(rdata+4); + : GET_BE16(rdata+4); int result = nw_get_queue_job_file_size(q_id, job_id); if (result > -1) { uint8 *p=responsedata; @@ -1245,7 +1278,10 @@ static void handle_fxx(int gelen, int func) if (ufunc==0x78) { U16_TO_BE16(job_id, p); p+=2; } else { - U32_TO_BE32(job_id, p); p+=4; + /* U32_TO_BE32(job_id, p); p+=4; */ + U16_TO_BE16(job_id, p); p+=2; + *(p++)=0; + *(p++)=0; } U32_TO_BE32(result, p); p+=4; data_len=(int)(p-responsedata); @@ -1254,13 +1290,15 @@ static void handle_fxx(int gelen, int func) } break; + case 0x71 : /* service queue job old */ case 0x7c : { /* service queue job */ uint32 q_id = GET_BE32(rdata); int type = GET_BE16(rdata+4); int result=nw_service_queue_job( act_c->object_id, act_connection, ncprequest->task, - q_id, type, responsedata, 0); + q_id, type, responsedata, + ufunc==0x71 ); if (result > -1) data_len=result; else @@ -1321,9 +1359,10 @@ static void handle_fxx(int gelen, int func) data_len=sizeof(struct XDATA); }break; + case 0x72: /* finish servicing queue job (old)*/ case 0x83: { /* finish servicing queue job */ uint32 q_id = GET_BE32(rdata); - uint32 job_id = GET_BE32(rdata+4); + uint32 job_id = GET_BE16(rdata+4); #if 0 uint32 chargeinfo = GET_BE32(rdata+8); #endif @@ -1335,9 +1374,10 @@ static void handle_fxx(int gelen, int func) completition=(uint8) -result; }break; + case 0x73: /* abort servicing queue job (old) */ case 0x84: { /* abort servicing queue job */ uint32 q_id = GET_BE32(rdata); - uint32 job_id = GET_BE32(rdata+4); + uint32 job_id = GET_BE16(rdata+4); int result = nw_finish_abort_queue_job(1, act_c->object_id, act_connection, @@ -1676,7 +1716,11 @@ int main(int argc, char *argv[]) internal_act = 0; if (act_c->active && IPXCMPNODE(from_addr.node, my_addr.node) && IPXCMPNET (from_addr.net, my_addr.net)) { - handle_fxx(ud.udata.len, (int)ncprequest->function); + if (!ncprequest->function){ /* wdog reset */ + nwserv_reset_wdog(act_connection); + XDPRINTF((3, 0, "send wdog reset")); + } else + handle_fxx(ud.udata.len, (int)ncprequest->function); } else { XDPRINTF((1, 0, "NWBIND-LOOP addr=%s of connection=%d is wrong", visable_ipx_adr(&from_addr), act_connection)); diff --git a/nwconn.c b/nwconn.c index 94a734b..51fb44a 100644 --- a/nwconn.c +++ b/nwconn.c @@ -1,4 +1,4 @@ -/* nwconn.c 14-Aug-97 */ +/* nwconn.c 08-Oct-97 */ /* one process / connection */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany @@ -64,6 +64,7 @@ static char *prog_title; static int req_printed=0; +#if ENABLE_BURSTMODE typedef struct { BURSTPACKET *sendburst; /* buffer for sending burstpacket * allocated and prefilled by response to @@ -101,6 +102,7 @@ typedef struct { } BURST_W; static BURST_W *burst_w=NULL; +#endif static void set_program_title(char *s) { @@ -135,22 +137,39 @@ static int ncp_response(int sequence, int task, return(0); } -static int call_nwbind(void) +static int call_nwbind(int mode) +/* modes 0: 'standard' call + * 1: activate wdog + */ { ipxAddr_t to_addr; + int result; memcpy(&to_addr, &my_addr, sizeof(ipxAddr_t)); U16_TO_BE16(sock_nwbind, to_addr.sock); - ud.udata.len = ud.udata.maxlen = sizeof(NCPREQUEST) + requestlen; - ud.udata.buf = (char*)&readbuff; ud.addr.buf = (char*)&to_addr; - if (t_sndudata(FD_NCP_OUT, &ud) < 0){ + if (mode==1) { /* reset wdogs */ + NCPREQUEST buf; + buf.type[0] = buf.type[1]=0x22; + buf.sequence = ncprequest->sequence; + buf.connection = ncprequest->connection; + buf.task = ncprequest->task; + buf.high_connection = ncprequest->high_connection; + buf.function = 0; + ud.udata.len = ud.udata.maxlen = sizeof(buf); + ud.udata.buf = (char*)&buf; + XDPRINTF((3, 0, "send wdog reset")); + result=t_sndudata(FD_NCP_OUT, &ud); + } else { + ud.udata.len = ud.udata.maxlen = sizeof(NCPREQUEST) + requestlen; + ud.udata.buf = (char*)&readbuff; + result=t_sndudata(FD_NCP_OUT, &ud); + } + ud.addr.buf = (char*)&from_addr; + ud.udata.buf = (char*)&ipxdata; + if (result< 0){ if (nw_debug) t_error("t_sndudata in NWCONN !OK"); - ud.addr.buf = (char*)&from_addr; - ud.udata.buf = (char*)&ipxdata; return(-1); } - ud.addr.buf = (char*)&from_addr; - ud.udata.buf = (char*)&ipxdata; return(0); } @@ -284,6 +303,12 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', } else completition = (uint8) -result; } break; + case 0x13 : { /* Get connection ?? */ + /* TODO !!!!!!! */ + *responsedata=(uint8) act_connection; + data_len = 1; + } break; + case 0x14 : { /* GET DATE und TIME */ struct SERVER_DATE { uint8 year; @@ -830,12 +855,12 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', } else completition = 0xfb; /* unkwown request */ } break; + case 0x17 : { /* FILE SERVER ENVIRONMENT */ /* uint8 len = *(requestdata+1); */ uint8 ufunc = *(requestdata+2); -#if DO_DEBUG uint8 *rdata = requestdata+3; -#endif + switch (ufunc) { #if FUNC_17_02_IS_DEBUG case 0x02 : { @@ -933,10 +958,46 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', } break; + case 0x64: { /* create queue */ +#if 0 + int q_typ = GET_BE16(rdata); +#endif + int q_name_len = *(rdata+2); +#if 0 + uint8 *q_name = rdata+3; +#endif + uint8 *dirhandle = rdata+3+q_name_len; + int pathlen = *(rdata+3+q_name_len+1); + uint8 *path = rdata+3+q_name_len+2; + uint8 new_path[257]; + int result = conn_get_full_path(*dirhandle, + path, pathlen, new_path); + if (result > -1) { + int diffsize = result - pathlen; + *dirhandle = 0; + memcpy(path, new_path, result); + if (diffsize) + requestlen+=diffsize; /* !!!!!! */ + return(-1); /* nwbind must do the rest */ + } else + completition = (uint8)(-result); + } + break; + case 0x68: /* create queue job and file old */ case 0x79: /* create queue job and file */ return(-2); /* nwbind must do prehandling */ + + case 0x6C: { /* Get Queue Job Entry old */ + uint32 q_id = GET_BE32(rdata); + int job_id = GET_BE16(rdata+4); + uint32 fhandle = get_queue_job_fhandle(q_id, job_id); + U32_TO_BE32(fhandle, rdata+8); + requestlen+=6; /* !!!!!! */ + } + return(-1); /* nwbind must do the rest */ + case 0x69: /* close file and start queue old ?? */ case 0x7f: { /* close file and start queue */ struct INPUT { @@ -949,7 +1010,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', } *input = (struct INPUT *) (ncprequest); uint32 q_id = GET_BE32(input->queue_id); int job_id = (ufunc==0x69) ? GET_BE16(input->job_id) - : GET_BE32(input->job_id); + : GET_BE16(input->job_id); int result = close_queue_job(q_id, job_id); if (result < 0) { completition = (uint8)-result; @@ -959,9 +1020,12 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', } break; + case 0x71 : /* service queue job (old) */ case 0x7c : /* service queue job */ return(-2); /* nwbind must do prehandling */ + case 0x72 : /* finish queue job (old) */ + case 0x73 : /* abort queue job (old) */ case 0x83 : /* finish queue job */ case 0x84 : { /* abort queue job */ struct INPUT { @@ -973,7 +1037,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', /* if 0x69 then only first 2 byte ! */ } *input = (struct INPUT *) (ncprequest); uint32 q_id = GET_BE32(input->queue_id); - int job_id = GET_BE32(input->job_id); + int job_id = GET_BE16(input->job_id); int result = finish_abort_queue_job(q_id, job_id); if (result <0) completition=(uint8) -result; @@ -1859,7 +1923,7 @@ static void handle_after_bind() } *rinput = (struct RINPUT *) (bindresponse); uint32 q_id = GET_BE32(input->queue_id); int job_id = (ufunc==0x69) ? GET_BE16(input->job_id) - : GET_BE32(input->job_id); + : GET_BE16(input->job_id); int result = close_queue_job2(q_id, job_id, rinput->client_area, @@ -1869,18 +1933,20 @@ static void handle_after_bind() } break; + case 0x71 : /* service queue job (old) */ case 0x7c : { /* service queue job */ struct INPUT { uint8 header[7]; /* Requestheader */ uint8 packetlen[2]; /* low high */ - uint8 func; /* 0x7c */ + uint8 func; /* 0x7c,0x71 */ uint8 queue_id[4]; /* Queue ID */ uint8 job_typ[2]; /* service typ */ } *input = (struct INPUT *) (ncprequest); uint32 q_id = GET_BE32(input->queue_id); uint8 *qjob = bindresponse; - int result = service_queue_job(q_id, qjob, - responsedata, 0); + int result = service_queue_job(q_id, qjob, + responsedata, + ufunc==0x71); if (result > -1) data_len=result; else @@ -2089,6 +2155,7 @@ static void set_sig(void) int main(int argc, char **argv) { + time_t last_time=time(NULL); if (argc != 4 || 3!=sscanf(argv[3], "()INIT-:%x,%x,%x-", &father_pid, &sock_nwbind, &sock_echo)) { fprintf(stderr, "usage nwconn connid FROM_ADDR ()INIT-:pid,nwbindsock,echosock-\n"); @@ -2146,6 +2213,7 @@ int main(int argc, char **argv) while (fl_get_int >= 0) { int data_len = read(0, readbuff, sizeof(readbuff)); + /* this read is a pipe or a socket read, * depending on CALL_NWCONN_OVER_SOCKET */ @@ -2180,25 +2248,36 @@ int main(int argc, char **argv) ncprequest->function, data_len); } saved_sequence = -1; -#if ENABLE_BURSTMODE - } else if (ncp_type == 0x7777) { /* BURST-MODE */ - XDPRINTF((16, 0, "GOT BURSTPACKET")); - handle_burst((BURSTPACKET*)readbuff, data_len); -#endif } else { /* this calls I must handle, it is a request */ - int result; - requestlen = data_len - sizeof(NCPREQUEST); - if (0 != (result = handle_ncp_serv()) ) { - if (result == -2) { - /* here the actual call must be saved - * because we need it later, when the request to nwbind - * returns. - */ - memcpy(saved_readbuff, readbuff, data_len); - saved_sequence = (int)(ncprequest->sequence); - } else saved_sequence = -1; - /* this call must go to nwbind */ - call_nwbind(); + time_t act_time=time(NULL); + + if (act_time > last_time+300 && saved_sequence == -1) { + /* ca. 5 min. reset wdogs */ + call_nwbind(1); + last_time=act_time; + } + +#if ENABLE_BURSTMODE + if (ncp_type == 0x7777) { /* BURST-MODE */ + XDPRINTF((16, 0, "GOT BURSTPACKET")); + handle_burst((BURSTPACKET*)readbuff, data_len); + } else +#endif + { + int result; + requestlen = data_len - sizeof(NCPREQUEST); + if (0 != (result = handle_ncp_serv()) ) { + if (result == -2) { + /* here the actual call must be saved + * because we need it later, when the request to nwbind + * returns. + */ + memcpy(saved_readbuff, readbuff, data_len); + saved_sequence = (int)(ncprequest->sequence); + } else saved_sequence = -1; + /* this call must go to nwbind */ + call_nwbind(0); + } } } } diff --git a/nwdbm.c b/nwdbm.c index 79b473d..6677ed1 100644 --- a/nwdbm.c +++ b/nwdbm.c @@ -1,4 +1,4 @@ -/* nwdbm.c 16-Aug-97 data base for mars_nwe */ +/* nwdbm.c 08-Oct-97 data base for mars_nwe */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -56,15 +56,17 @@ #define DBM_REMAINS_OPEN 1 int tells_server_version=1; /* default 1 since 12-Jan-97 */ -int password_scheme=0; +int password_scheme=0; + +uint8 *sys_unixname=NULL; /* Unixname of SYS: ends with '/' */ +int sys_unixnamlen=0; /* len of unixname */ +int sys_downshift=0; /* is SYS downshift */ +uint8 *sys_sysname=NULL; /* Name of first Volume, normally SYS */ + uint32 network_serial_nmbr=(uint32)NETWORK_SERIAL_NMBR; uint16 network_appl_nmbr=(uint16)NETWORK_APPL_NMBR; static int entry8_flags = 0; -static uint8 *sys_unixname=NULL; /* Unixname of SYS: ends with '/' */ -static int sys_unixnamlen=0; /* len of unixname */ -static int sys_downshift=0; /* is SYS downshift */ - static datum key; static datum data; static DBM_FILE my_dbm=NULL; @@ -102,7 +104,7 @@ static int x_dbminit(char *s) #else (void)get_div_pathes(buff, s, 1, NULL); my_dbm = dbm_open(buff, O_RDWR|O_CREAT, 0600); -#endif +#endif return( (my_dbm == NULL) ? -1 : 0); } @@ -124,7 +126,7 @@ static int dbmclose() { if (my_dbm != NULL) { #if !DBM_REMAINS_OPEN -# ifdef USE_GDBM +# ifdef USE_GDBM gdbm_close(my_dbm); # else dbm_close(my_dbm); @@ -141,7 +143,7 @@ void sync_dbm() int k = COUNT_DBM_FILES; while (k--) { if (NULL != my_dbms[k]) { -# ifdef USE_GDBM +# ifdef USE_GDBM gdbm_close(my_dbms[k]); # else dbm_close(my_dbms[k]); @@ -263,12 +265,12 @@ int find_obj_id(NETOBJ *o) XDPRINTF((1,0, "OBJ Index '%s',0x%x, id=0x%x not found in OBJ data", o->name, (int)o->type, o->id)); } - } + } dbmclose(); if (!result) return(0); } - result=scan_for_obj(o, 0); + result=scan_for_obj(o, 0, 1); if (!result) { /* was ok, we will rewrite/creat iobj record */ XDPRINTF((1, 0,"findobj_id OBJ='%s', type=0x%x, id=0x%x not in Index File", o->name,(int)o->type,o->id)); @@ -277,7 +279,7 @@ int find_obj_id(NETOBJ *o) return(result); } -int scan_for_obj(NETOBJ *o, uint32 last_obj_id) +int scan_for_obj(NETOBJ *o, uint32 last_obj_id, int ignore_rights) /* * scans for object, * wildcards in objectname allowed @@ -302,8 +304,9 @@ int scan_for_obj(NETOBJ *o, uint32 last_obj_id) if (data.dptr != NULL){ NETOBJ *obj = (NETOBJ*)data.dptr; if ( ( ((int)obj->type == (int)o->type) || o->type == MAX_U16) && - name_match(obj->name, o->name) && - (b_acc(obj->id, obj->security, 0x00)== 0)) { + name_match(obj->name, o->name) && + ( ignore_rights || + (b_acc(obj->id, obj->security, 0x00)== 0))) { XDPRINTF((2, 0, "found OBJ=%s, id=0x%x", obj->name, (int)obj->id)); result = 0; memcpy((char *)o, (char*)obj, sizeof(NETOBJ)); @@ -399,11 +402,11 @@ static int loc_delete_property(uint32 obj_id, static int prop_delete_member(uint32 obj_id, int prop_id, int prop_security, uint32 member_id) { - int result; + int result; NETVAL val; if (0 != (result=b_acc(obj_id, prop_security, 0x11))) return(result); else result = 0; /* we lie insteed of -0xea; no such member */ - + if (!dbminit(FNVAL)){ key.dsize = NETVAL_KEY_SIZE; key.dptr = (char*)&val; @@ -585,7 +588,7 @@ static int find_prop_id(NETPROP *p, uint32 obj_id, int last_prop_id) else { data = fetch(key); prop = (NETPROP*)data.dptr; - if (data.dptr != NULL && name_match(prop->name, p->name) + if (data.dptr != NULL && name_match(prop->name, p->name) && (b_acc(obj_id, prop->security, 0x00)== 0) ) { XDPRINTF((2,0, "found PROP %s, id=0x%x", prop->name, (int) prop->id)); result = 0; @@ -642,10 +645,10 @@ static int loc_get_prop_val(uint32 obj_id, int prop_id, int prop_security, { int result; NETVAL val; - + if (0 != (result=b_acc(obj_id, prop_security, 0x10))) return(result); else result = -0xec; /* no such Segment */ - + if (!dbminit(FNVAL)){ key.dsize = NETVAL_KEY_SIZE; key.dptr = (char*)&val; @@ -674,10 +677,10 @@ static int prop_find_member(uint32 obj_id, int prop_id, int prop_security, { int result; NETVAL val; - + if (0 != (result=b_acc(obj_id, prop_security, 0x10))) return(result); else result = -0xea; /* no such member */ - + if (!dbminit(FNVAL)){ key.dsize = NETVAL_KEY_SIZE; key.dptr = (char*)&val; @@ -711,7 +714,7 @@ static int prop_add_member(uint32 obj_id, int prop_id, int prop_security, if (0 != (result=b_acc(obj_id, prop_security, 0x11))) return(result); else result = 0; /* OK */ - + if (!dbminit(FNVAL)){ key.dsize = NETVAL_KEY_SIZE; key.dptr = (char*)&val; @@ -910,8 +913,12 @@ int nw_add_obj_to_set(int object_type, result=find_first_prop_id(&prop, obj.id); if (!result) result = find_obj_id(&mobj); - if (!result) - result = prop_add_member(obj.id, (int)prop.id, prop.security, mobj.id); + if (!result) { + if (-0xea == (result=prop_find_member(obj.id, prop.id, prop.security, mobj.id))) + result = prop_add_member(obj.id, (int)prop.id, prop.security, mobj.id); + else if (!result) + result=-0xe9; /* property already exist */ + } } return(result); } @@ -1247,7 +1254,9 @@ static MYPASSWD *nw_getpwnam(uint32 obj_id) static MYPASSWD pwstat; char buff[200]; if (nw_get_prop_val_str(obj_id, pn_unix_user, buff) > 0){ - struct passwd *pw = getpwnam(buff); + struct passwd *pw; + endpwent(); /* tnx to Leslie */ + pw = getpwnam(buff); if (NULL != pw) { if (obj_id != 1 && !pw->pw_uid) return(NULL); /* only supervisor -> root */ @@ -1258,7 +1267,9 @@ static MYPASSWD *nw_getpwnam(uint32 obj_id) xstrcpy(pwstat.pw_dir, pw->pw_dir); #if SHADOW_PWD if (pwstat.pw_passwd[0] == 'x' && pwstat.pw_passwd[1]=='\0') { - struct spwd *spw=getspnam(buff); + struct spwd *spw; + endspent(); /* tnx to Leslie */ + spw=getspnam(buff); if (spw) xstrcpy(pwstat.pw_passwd, spw->sp_pwdp); } #endif @@ -1463,9 +1474,9 @@ int nw_keychange_passwd(uint32 obj_id, uint8 *cryptkey, uint8 *oldpass, } static int nw_test_time_access(uint32 obj_id) -/* - * Routine from Matt Paley - * and code from Mark Robson +/* + * Routine from Matt Paley + * and code from Mark Robson */ { time_t t,expiry; @@ -1482,10 +1493,10 @@ static int nw_test_time_access(uint32 obj_id) buff, &more_segments, &property_flags); if (result < 0) return(0); /* No time limits available */ - + /* Check if account disabled - MR */ - - if (buff[3] != 0) /* Disabled */ + + if (buff[3] != 0) /* Disabled */ { XDPRINTF((1, 0, "No access for user %x - disabled.",obj_id)); return (-0xdc); @@ -1502,10 +1513,10 @@ static int nw_test_time_access(uint32 obj_id) exptm.tm_sec = 59; expiry = mktime(&exptm); } else expiry = 0; - + time(&t); tm = localtime(&t); - + if (expiry>0) /* if expiry is enabled */ { XDPRINTF((1,0,"user has expiry of %d but time is %d",expiry,t)); @@ -1515,7 +1526,7 @@ static int nw_test_time_access(uint32 obj_id) return (-0xdc); } } - + half_hours = tm->tm_wday*48 + tm->tm_hour*2 + ((tm->tm_min>=30)? 1 : 0); if ((buff[14+(half_hours/8)] & (1<<(half_hours % 8))) != 0) return(0); @@ -1576,11 +1587,13 @@ static int nw_new_add_prop_member(uint32 obj_id, char *propname, prop.flags = (uint8) (propflags | P_FL_SET); /* always SET */ prop.security = (uint8) propsecurity; result = nw_create_obj_prop(obj_id, &prop); + if (!result || result == -0xed) { /* created or exists */ if (-0xea == (result=prop_find_member(obj_id, prop.id, prop.security, member_id))) return(prop_add_member(obj_id, prop.id, prop.security, member_id)); else if (!result) result = -0xee; /* already exist */ } + return(result); } @@ -1606,6 +1619,30 @@ int nwdbm_mkdir(char *unixname, int mode, int flags) return(-1); } +int nwdbm_rmdir(char *path) +/* removes full directory */ +{ + DIR *f=opendir(path); + if (f) { + int pathlen=strlen(path); + char *gpath=xmalloc(pathlen+300); + char *p=gpath+pathlen; + struct dirent* dirbuff; + memcpy(gpath, path, pathlen); + *p++ = '/'; + while ((dirbuff = readdir(f)) != (struct dirent*)NULL){ + if (dirbuff->d_ino) { + strmaxcpy(p, dirbuff->d_name, 255); + unlink(gpath); + } + } + xfree(gpath); + closedir(f); + return(rmdir(path)); + } + return(-1); +} + static void create_nw_db(char *fn, int always) { char fname[200]; @@ -1636,10 +1673,10 @@ static void add_pr_queue(uint32 q_id, { uint8 buf[300]; nw_new_obj(&q_id, q_name, 0x3, O_FL_STAT, 0x31); - + if (!q_directory || !*q_directory) { q_directory=buf; - sprintf(q_directory, "SYS:/SYSTEM/%08lX.QDR", q_id); + sprintf(q_directory, "SYS:SYSTEM/%08lX.QDR", q_id); } XDPRINTF((2,0, "ADD Q=%s, V=%s, C=%s", q_name, q_directory, q_command)); nw_new_obj_prop(q_id, NULL, 0, 0, 0, @@ -1660,7 +1697,7 @@ static void add_pr_queue(uint32 q_id, } static void add_pr_server(uint32 ps_id, - char *ps_name, + char *ps_name, char *ps_queue, uint32 su_id, uint32 ge_id) { @@ -1668,12 +1705,12 @@ static void add_pr_server(uint32 ps_id, nw_new_obj(&ps_id, ps_name, 0x7, O_FL_STAT, 0x31); nw_new_add_prop_member(ps_id, "PS_OPERATORS", P_FL_STAT, 0x31, su_id); nw_new_add_prop_member(ps_id, "PS_USERS", P_FL_STAT, 0x31, ge_id); - + if (ps_queue && *ps_queue) { NETOBJ obj; strmaxcpy((char*)obj.name, (char*)ps_queue, 47); obj.type = 0x3; /* QUEUE */ - if (!find_obj_id(&obj)) + if (!find_obj_id(&obj)) nw_new_add_prop_member(obj.id, "Q_SERVERS", P_FL_STAT, 0x31, ps_id); } @@ -1881,7 +1918,7 @@ static void correct_user_dirs(uint32 objid, uint8 *objname, int uid, int gid) } memcpy(p1, "user/", 5); strmaxcpy(p1+5, objname, 47); - if (!sys_downshift) + if (!sys_downshift) upstr(p1); else downstr(p1+5); @@ -1976,7 +2013,7 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) } else if (state==3) { strcpy(command, p-1); break; - } + } } *pp++ = c; } @@ -2000,7 +2037,7 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) int state=0; name[0]='\0'; queue[0]='\0'; - + while (0 != (c = *p++)) { if (c == 32 || c == '\t') { if (!(state & 1)) { @@ -2091,7 +2128,7 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) (char*)adr, sizeof(ipxAddr_t), 1); #endif } - + if (auto_ins_user) { /* here Unix users will be inserted automaticly as mars_nwe users */ struct passwd *pw; @@ -2142,17 +2179,18 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) if (*sysentry) { uint8 unixname[512]; - uint8 sysname[256]; + uint8 sysname[256]; int result = get_sys_unixname(unixname, sysname, sysentry); int downshift = (result & 1); int unlen = strlen(unixname); if (result < 0) return(-1); new_str(sys_unixname, unixname); + new_str(sys_sysname, sysname); sys_downshift = downshift; sys_unixnamlen = unlen; - + if (make_tests) { - uint32 objs[LOC_MAX_OBJS]; + uint32 objs[LOC_MAX_OBJS]; uint8 maildir[512]; int ocount=0; uint8 *pp = unixname+unlen; @@ -2218,7 +2256,10 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) } } } - init_queues(sys_unixname, sys_unixnamlen, sys_downshift, sysname); /* nwqueue.c */ + if (servername && adr) { + /* do only init_queues when starting nwserv */ + init_queues(); /* nwqueue.c */ + } return(0); } return(-1); diff --git a/nwdbm.h b/nwdbm.h index ea189be..ff770f9 100644 --- a/nwdbm.h +++ b/nwdbm.h @@ -1,4 +1,4 @@ -/* nwdbm.h 24-Aug-97 */ +/* nwdbm.h 01-Oct-97 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -70,6 +70,12 @@ typedef struct { extern int tells_server_version; extern int password_scheme; + +extern uint8 *sys_unixname; /* Unixname of SYS: ends with '/' */ +extern int sys_unixnamlen; /* len of unixname */ +extern int sys_downshift; /* is SYS downshift */ +extern uint8 *sys_sysname; /* Name of first Volume, normally SYS */ + extern uint32 network_serial_nmbr; extern uint16 network_appl_nmbr; @@ -93,7 +99,7 @@ extern int nw_get_prop(int object_type, extern int find_obj_id(NETOBJ *o); -extern int scan_for_obj(NETOBJ *o, uint32 last_obj_id); +extern int scan_for_obj(NETOBJ *o, uint32 last_obj_id, int ignore_rights); extern int nw_delete_obj(NETOBJ *obj); extern int nw_rename_obj(NETOBJ *o, uint8 *newname); @@ -199,6 +205,7 @@ extern int nw_test_adr_time_access(uint32 obj_id, ipxAddr_t *client_adr); extern int nwdbm_mkdir(char *unixname, int mode, int flags); +extern int nwdbm_rmdir(char *path); extern void test_ins_unx_user(uint32 id); extern int test_allow_password_change(uint32 id); diff --git a/nwfile.c b/nwfile.c index d759cbb..d7d36bf 100644 --- a/nwfile.c +++ b/nwfile.c @@ -338,7 +338,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, fh->fd = creat(fh->fname, 0777); if (fh->fd < 0) completition = -0x84; /* no create Rights */ - else + else if (act_umode_file) chmod(fh->fname, act_umode_file); } else { XDPRINTF((5,0,"CREAT FILE, ever with attrib:0x%x, access:0x%x, fh->fname:%s: handle:%d", @@ -355,7 +355,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, } if (fh->fd < 0) completition = -0x85; /* no delete /create Rights */ - } else + } else if (act_umode_file) chmod(fh->fname, act_umode_file); } if (fh->fd > -1) { diff --git a/nwqconn.c b/nwqconn.c index 2448eec..b46c2cf 100644 --- a/nwqconn.c +++ b/nwqconn.c @@ -1,4 +1,4 @@ -/* nwqconn.c 26-Aug-97 */ +/* nwqconn.c 24-Sep-97 */ /* (C)opyright (C) 1997 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -130,7 +130,7 @@ int creat_queue_job(uint32 q_id, { uint8 *dirname = (old_call) ? queue_job+sizeof(QUEUE_JOB_OLD) : queue_job+sizeof(QUEUE_JOB); - int job_id; + int job_id=-1; INT_QUEUE_JOB *jo; int result; memcpy(responsedata, queue_job, (old_call) ? sizeof(QUEUE_JOB_OLD) @@ -149,7 +149,7 @@ int creat_queue_job(uint32 q_id, } } else { QUEUE_JOB *job=(QUEUE_JOB*)responsedata; - job_id=GET_BE32(job->job_id); + job_id=GET_BE16(job->job_id); jo = new_queue_job(q_id, job_id); result = open_creat_queue_file(0, job->job_file_name+1, *(job->job_file_name), dirname+1, *dirname); @@ -161,6 +161,9 @@ int creat_queue_job(uint32 q_id, } if (result < 0) free_queue_job(q_id, job_id); + + XDPRINTF((6, 0, "creat_q_job, id=%d, result=%d", jo ? jo->job_id : -1, + result)); return(result); } @@ -240,6 +243,7 @@ int close_queue_job2(uint32 q_id, int job_id, } else XDPRINTF((1,0,"Cannot open queue-file `%s`", unixname)); } } else { + result=0; nw_close_file(jo->fhandle, 1); } free_queue_job(q_id, job_id); @@ -274,7 +278,7 @@ int service_queue_job(uint32 q_id, } } else { QUEUE_JOB *job=(QUEUE_JOB*)responsedata; - job_id=GET_BE32(job->job_id); + job_id = GET_BE16(job->job_id); jo = new_queue_job(q_id, job_id); result = open_creat_queue_file(1, job->job_file_name+1, *(job->job_file_name), @@ -285,8 +289,9 @@ int service_queue_job(uint32 q_id, result = sizeof(QUEUE_JOB) - 202; } } - if (result < 0) + if (result < 0) { free_queue_job(q_id, job_id); + } return(result); } @@ -304,6 +309,14 @@ int finish_abort_queue_job(uint32 q_id, int job_id) return(result); } +uint32 get_queue_job_fhandle(uint32 q_id, int job_id) +{ + INT_QUEUE_JOB *jo=find_queue_job(q_id, job_id); + if (jo) + return(jo->fhandle); + return(0); +} + void free_queue_jobs(void) { INT_QUEUE_JOB *qj=queue_jobs; diff --git a/nwqconn.h b/nwqconn.h index 519e016..679edf3 100644 --- a/nwqconn.h +++ b/nwqconn.h @@ -18,6 +18,7 @@ extern int service_queue_job(uint32 q_id, uint8 old_call); extern int finish_abort_queue_job(uint32 q_id, int job_id); +extern uint32 get_queue_job_fhandle(uint32 q_id, int job_id); extern void free_queue_jobs(void); #endif diff --git a/nwqueue.c b/nwqueue.c index 44da388..507bc5e 100644 --- a/nwqueue.c +++ b/nwqueue.c @@ -1,4 +1,4 @@ -/* nwqueue.c 24-Aug-97 */ +/* nwqueue.c 08-Oct-97 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -250,6 +250,7 @@ static void r_w_queue_jobs(NWE_QUEUE *q, int mode) /* correct some possible wrong values */ qj->server_station=0; qj->server_id=0; + qj->job_control_flags &= ~0x20; add_queue_job(q, qj); qj=(INT_QUEUE_JOB*)xmalloc(sizeof(INT_QUEUE_JOB)); } @@ -380,7 +381,10 @@ static int fill_q_job_entry(INT_QUEUE_JOB *jo, set_time_field(job->target_execute_time, jo->execute_time); set_time_field(job->job_entry_time, jo->entry_time); - U32_TO_BE32(jo->job_id, job->job_id); + U16_TO_BE16(jo->job_id, job->job_id); + *(job->job_id+2) = 0; + *(job->job_id+3) = 0; + U16_TO_BE16(jo->job_typ, job->job_typ); U16_TO_16(jo->job_position, job->job_position); @@ -409,8 +413,9 @@ int nw_creat_queue_job(int connection, int task, uint32 object_id, : responsedata+sizeof(QUEUE_JOB); int result = nw_get_q_dirname(q_id, fulldirname+1); NWE_QUEUE *que=find_queue(q_id); + INT_QUEUE_JOB *jo=NULL; if (result > 0 && que) { - INT_QUEUE_JOB *jo = new_queue_job(que, connection, task, object_id); + jo = new_queue_job(que, connection, task, object_id); *fulldirname=(uint8) result++; if (jo == NULL) return(-0xd4); /* queue full */ if (old_call) { /* before 3.11 */ @@ -439,6 +444,8 @@ int nw_creat_queue_job(int connection, int task, uint32 object_id, } else { result=-0xd3; /* no rights */ } + XDPRINTF((6, 0, "creat_q_job, id=%d, result=%d", jo ? jo->job_id : -1, + result)); return(result); } @@ -486,7 +493,7 @@ int nw_get_queue_status(uint32 q_id, int *status, int *entries, return(-0xff); } -int nw_get_q_job_entry(uint32 q_id, int job_id, +int nw_get_q_job_entry(uint32 q_id, int job_id, uint32 fhandle, uint8 *responsedata, int old_call) { int result=-0xd5; @@ -496,9 +503,12 @@ int nw_get_q_job_entry(uint32 q_id, int job_id, if (old_call) { QUEUE_JOB_OLD *job=(QUEUE_JOB_OLD*)responsedata; result=fill_q_job_entry_old(qj, job, 1); + U16_TO_BE16(0, job->job_file_handle); + U32_TO_32(fhandle, job->job_file_handle+2); } else { QUEUE_JOB *job=(QUEUE_JOB*)responsedata; result=fill_q_job_entry(qj, job, 1); + U32_TO_32(fhandle, job->job_file_handle); } } return(result); @@ -545,8 +555,13 @@ static int remove_queue_job_file(NWE_QUEUE *q, INT_QUEUE_JOB *qj) struct stat stb; uint8 buf[300]; build_unix_queue_file(buf, q, qj); - if (!stat(buf, &stb)) - return(unlink(buf)); + if (!stat(buf, &stb)) { + int result=unlink(buf); + if (result) { + XDPRINTF((1, 0, "remove_queue_job_file, cannot remove `%s`.", buf)); + } + return(result); + } return(0); } @@ -560,7 +575,8 @@ int nw_remove_job_from_queue(uint32 user_id, uint32 q_id, int job_id) result=remove_queue_job_file(q, qj); if (!result) free_queue_job(q, job_id); - else result=-0xd6; + else + result=-0xd6; } else result=-0xd6; /* no queue user rights */ } return(result); @@ -590,6 +606,12 @@ int nw_attach_server_to_queue(uint32 user_id, NWE_QUEUE *q = find_queue(q_id); if (q) { if (!(result=nw_is_member_in_set(q_id, "Q_SERVERS", user_id))){ +#if 1 + if (q->qserver) { + free_qserver(q->qserver); + q->qserver=NULL; + } +#endif if (!q->qserver) { q->qserver=new_qserver(user_id, connection); } else result=-0xdb; /* too max queue servers */ @@ -634,6 +656,7 @@ int nw_service_queue_job(uint32 user_id, int connection, int task, INT_QUEUE_JOB *fqj=NULL; time_t acttime=time(NULL); *fulldirname=(uint8) len++; + *(fulldirname+len)=0; /* for testprints only */ while(qj) { if ( (!qj->server_id) && !(qj->job_control_flags&0x20) /* not actual queued */ @@ -663,6 +686,7 @@ int nw_service_queue_job(uint32 user_id, int connection, int task, result=fill_q_job_entry(fqj, job, 1); } result+=len; + XDPRINTF((3, 0, "nw service queue job dirname=`%s`", fulldirname+1)); } else { XDPRINTF((3, 0, "No queue job found for q_id=0x%x, user_id=0x%x,job_typ=0x%x", q_id, user_id, job_typ)); @@ -718,45 +742,133 @@ void exit_queues(void) free_queue_job(q, job_id); } q=q->next; - free_queue(qid); } nwe_queues=NULL; } } -int build_unix_queue_dir(uint8 *buf, - uint8 *unixname, - int unixname_len, - int downshift, - uint8 *sysname, - uint32 q_id) +static int build_unix_queue_dir(uint8 *buf, uint32 q_id) { int result = -0xff; uint8 buf1[300]; uint8 *p; - memcpy(buf, unixname, unixname_len); + memcpy(buf, sys_unixname, sys_unixnamlen); result=nw_get_q_dirname(q_id, buf1); upstr(buf1); if (result > -1 && NULL != (p=strchr(buf1, ':')) ) { *p++='\0'; result -= (int)(p - buf1); - if (!strcmp(buf1, sysname)) { - memcpy(buf+unixname_len, p, result); - result+=unixname_len; + if (!strcmp(buf1, sys_sysname)) { + memcpy(buf+sys_unixnamlen, p, result); + result+=sys_unixnamlen; if (buf[result-1]=='/') --result; buf[result]='\0'; - if (downshift) - downstr(buf+unixname_len); + if (sys_downshift) + downstr(buf+sys_unixnamlen); } } - XDPRINTF((3,0, "build_unix_queue_dir=`%s`, len=%d", buf, result)); + XDPRINTF((result<0?1:5,0, "build_unix_queue_dir=`%s`, len=%d", buf, result)); return(result); } -void init_queues(uint8 *unixname, int unixname_len, - int downshift, uint8 *sysname) + +int nw_creat_queue(int q_typ, uint8 *q_name, int q_name_len, + uint8 *path, int path_len, uint32 *q_id) +{ + NETOBJ obj; + int result; + if (q_typ != 0x3) return(-0xfb); /* we only support print queues */ + strmaxcpy(obj.name, q_name, min(47, q_name_len)); + obj.type = q_typ; + obj.flags = (uint8) O_FL_STAT; + obj.security = (uint8) 0x31; + obj.id = 0L; + result = nw_create_obj(&obj, 0); + + if (!result) { + uint8 q_directory[300]; + if (path_len && path_len < 230) { + memcpy(q_directory, path, path_len); + path=q_directory+path_len; + *path=0; + upstr(q_directory); + } else { + strcpy(q_directory, "SYS:SYSTEM"); + path_len=10; + path=q_directory+path_len; + } + sprintf(path, "/%08lX.QDR", obj.id); + *q_id = obj.id; + nw_new_obj_prop(obj.id, NULL, 0, 0, 0, + "Q_DIRECTORY", P_FL_ITEM, 0x31, + q_directory, strlen(q_directory), 1); + + nw_new_obj_prop(obj.id , NULL, 0 , 0 , 0, + "Q_USERS", P_FL_SET, 0x31, + NULL, 0, 0); + nw_new_obj_prop(obj.id , NULL, 0 , 0 , 0, + "Q_OPERATORS", P_FL_SET, 0x31, + NULL, 0, 0); + nw_new_obj_prop(obj.id , NULL, 0 , 0 , 0, + "Q_SERVERS", P_FL_SET, 0x31, + NULL, 0, 0); + + nwdbm_mkdir(get_div_pathes(q_directory, NULL, 4, "%x", obj.id), + 0700, 0); + + result=build_unix_queue_dir(q_directory, obj.id); + + if (result > 0) { + NWE_QUEUE *que=new_queue(obj.id); + nwdbm_mkdir(q_directory, 0775, 0); + new_str(que->queuedir, q_directory); + que->queuedir_len=result; + que->queuedir_downshift=sys_downshift; + r_w_queue_jobs(que, 0); + result=0; + } else result=-1; + } + return(result); +} + +int nw_destroy_queue(uint32 q_id) +{ + NETOBJ obj; + int result; + obj.id=q_id; + result=nw_get_obj(&obj); + if (!result) { + if (obj.type == 3) { /* only print queues */ + uint8 buf[300]; + get_div_pathes(buf, NULL, 4, "%x", obj.id); + nwdbm_rmdir(buf); + result=build_unix_queue_dir(buf, obj.id); + if (result > 0) { + NWE_QUEUE *q=find_queue(obj.id); + if (q) { + INT_QUEUE_JOB *qj=q->queue_jobs; + while(qj) { + int job_id=qj->job_id; + qj=qj->next; + free_queue_job(q, job_id); + } + free_queue(obj.id); + } + nwdbm_rmdir(buf); + nw_delete_obj(&obj); + result=0; + } else + result=result=-0xd3; /* no rights */ + } else + result=result=-0xd3; /* no rights */ + } + return(result); +} + + +void init_queues(void) { NETOBJ obj; uint8 buf[300]; @@ -764,11 +876,12 @@ void init_queues(uint8 *unixname, int unixname_len, uint8 *wild="*"; uint32 last_obj_id=MAX_U32; exit_queues(); - strmaxcpy(buf, unixname, unixname_len); + strmaxcpy(buf, sys_unixname, sys_unixnamlen); XDPRINTF((3,0, "init_queues:unixname='%s'", buf)); obj.type = 3; /* queue */ strcpy(obj.name, wild); - result = scan_for_obj(&obj, last_obj_id); + + result = scan_for_obj(&obj, last_obj_id, 1); while (!result) { NWE_QUEUE *que; nwdbm_mkdir(get_div_pathes(buf, NULL, 4, "%x", obj.id), @@ -776,19 +889,17 @@ void init_queues(uint8 *unixname, int unixname_len, strmaxcpy(buf, obj.name, 47); XDPRINTF((3, 0, "init queue, id=0x%x, '%s'", obj.id, buf)); - - result=build_unix_queue_dir(buf, unixname, unixname_len, - downshift, sysname, obj.id); + result=build_unix_queue_dir(buf, obj.id); if (result > 0) { que=new_queue(obj.id); new_str(que->queuedir, buf); que->queuedir_len=result; - que->queuedir_downshift=downshift; + que->queuedir_downshift=sys_downshift; r_w_queue_jobs(que, 0); } last_obj_id=obj.id; strcpy(obj.name, wild); - result = scan_for_obj(&obj, last_obj_id); + result = scan_for_obj(&obj, last_obj_id, 1); } } diff --git a/nwqueue.h b/nwqueue.h index d6082a3..a2d7d10 100644 --- a/nwqueue.h +++ b/nwqueue.h @@ -1,4 +1,4 @@ -/* nwqueue.h 18-Aug-97 */ +/* nwqueue.h 08-Oct-97 */ #ifndef _NWQUEUE_H_ #define _NWQUEUE_H_ #include "queuedef.h" @@ -15,7 +15,7 @@ extern int nw_close_queue_job(uint32 q_id, int job_id, extern int nw_get_queue_status(uint32 q_id, int *status, int *entries, int *servers, int server_ids[], int server_conns[]); -extern int nw_get_q_job_entry(uint32 q_id, int job_id, +extern int nw_get_q_job_entry(uint32 q_id, int job_id, uint32 fhandle, uint8 *responsedata, int old_call); extern int nw_get_queue_job_list_old(uint32 q_id, uint8 *responsedata); extern int nw_get_queue_job_file_size(uint32 q_id, int job_id); @@ -38,7 +38,11 @@ extern int nw_service_queue_job(uint32 user_id, int connection, int task, extern int nw_finish_abort_queue_job(int mode, uint32 user_id, int connection, uint32 q_id, int job_id); +extern int nw_creat_queue(int q_typ, uint8 *q_name, int q_name_len, + uint8 *path, int path_len, uint32 *q_id); + +extern int nw_destroy_queue(uint32 q_id); + extern void exit_queues(void); -extern void init_queues(uint8 *unixname, int unixname_len, - int downshift, uint8 *sysname); +extern void init_queues(void); #endif diff --git a/nwserv.c b/nwserv.c index 8378dcd..1e6a0cb 100644 --- a/nwserv.c +++ b/nwserv.c @@ -1,4 +1,4 @@ -/* nwserv.c 17-Jul-97 */ +/* nwserv.c 08-Oct-97 */ /* MAIN Prog for NWSERV + NWROUTED */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany @@ -1417,20 +1417,24 @@ int main(int argc, char **argv) if (sizeof(int) == read(p->fd, (char*)&conn, sizeof(int)) && sizeof(int) == read(p->fd, - (char*)&what, sizeof(what))) - if (what == 1) { - while (conn++ < hi_conn) { + (char*)&what, sizeof(what))) { + if (what == 1) { + while (conn++ < hi_conn) { + modify_wdog_conn(conn, what); + } + call_wdog++; + } else if (what == 0) { /* reset wdog */ modify_wdog_conn(conn, what); } - call_wdog++; } break; case 0x5555 : /* close connection */ if (sizeof(int) == read(p->fd, - (char*)&conn, sizeof(int))) + (char*)&conn, sizeof(int))) { modify_wdog_conn(conn, 99); write_to_nwbind(what, conn, NULL, 0); + } break; case 0x6666 : /* bcast message */