diff options
author | Samba Release Account <samba-bugs@samba.org> | 1997-07-01 01:19:13 +0000 |
---|---|---|
committer | Samba Release Account <samba-bugs@samba.org> | 1997-07-01 01:19:13 +0000 |
commit | 1c6e433caa22813a699c9766847886eb59755f8b (patch) | |
tree | 7ebc25637926ed22a740029767851621f5775278 /source | |
parent | 199fe63b1524833840b44ac708c2540272386d31 (diff) | |
download | samba-1c6e433caa22813a699c9766847886eb59755f8b.tar.gz |
client.c: New print queue query code from Jeff C. Foster " <jfoste@wgc.woodward.com>
ipc.c: Added code for returning restricted lists of servers.
loadparm.c: Changed default for force create mode to 000.
Changed default maxmux to 50 to comply with NT.
locking.c: Fixed silly crash bug with slow share mode code.
nameannounce.c: Added code for returning restricted lists of servers.
namedbserver.c: Added code for returning restricted lists of servers.
nameelect.c: Added code for returning restricted lists of servers.
namework.c: Added code for returning restricted lists of servers.
nmbsync.c: Added code for returning restricted lists of servers.
server.c: Added quota fix Albrecht Gebhardt <albrecht.gebhardt@uni-klu.ac.at>
smb.h: Added define for COPYBUF_SIZE.
system.c: Rename across filesystems Patch from Warren Birnbaum
<warrenb@hpcvscdp.cv.hp.com>
util.c: Minor fix for warning.
Diffstat (limited to 'source')
-rw-r--r-- | source/client/client.c | 119 | ||||
-rw-r--r-- | source/include/smb.h | 3 | ||||
-rw-r--r-- | source/lib/system.c | 117 | ||||
-rw-r--r-- | source/lib/util.c | 2 | ||||
-rw-r--r-- | source/locking/locking.c | 12 | ||||
-rw-r--r-- | source/nameannounce.c | 2 | ||||
-rw-r--r-- | source/namedbserver.c | 10 | ||||
-rw-r--r-- | source/nameelect.c | 17 | ||||
-rw-r--r-- | source/namework.c | 2 | ||||
-rw-r--r-- | source/nmbsync.c | 4 | ||||
-rw-r--r-- | source/param/loadparm.c | 4 | ||||
-rw-r--r-- | source/smbd/ipc.c | 17 | ||||
-rw-r--r-- | source/smbd/server.c | 83 |
13 files changed, 338 insertions, 54 deletions
diff --git a/source/client/client.c b/source/client/client.c index 873c88e88c4..c7e00c45150 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -1651,7 +1651,7 @@ static void cmd_more(void) strcpy(rname,cur_dir); strcat(rname,"\\"); - sprintf(tmpname,"%s/smbmore.%d",tmpdir(),getpid()); + sprintf(tmpname,"%s/smbmore.%d",tmpdir(),(int)getpid()); strcpy(lname,tmpname); if (!next_token(NULL,rname+strlen(rname),NULL)) { @@ -2452,7 +2452,8 @@ static void cmd_print(char *inbuf,char *outbuf ) } /**************************************************************************** -show a print queue +show a print queue - this is deprecated as it uses the old smb that +has limited support - the correct call is the cmd_p_queue_4() after this. ****************************************************************************/ static void cmd_queue(char *inbuf,char *outbuf ) { @@ -2516,6 +2517,119 @@ static void cmd_queue(char *inbuf,char *outbuf ) /**************************************************************************** show information about a print queue ****************************************************************************/ +static void cmd_p_queue_4(char *inbuf,char *outbuf ) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt, rprcnt; + pstring param; + int result_code=0; + + if (!connect_as_printer) + { + DEBUG(0,("WARNING: You didn't use the -P option to smbclient.\n")); + DEBUG(0,("Trying to print without -P may fail\n")); + } + + bzero(param,sizeof(param)); + + p = param; + SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */ + p += 2; + strcpy(p,"zWrLeh"); /* parameter description? */ + p = skip_string(p,1); + strcpy(p,"WWzWWDDzz"); /* returned data format */ + p = skip_string(p,1); + strcpy(p,strrchr(service,'\\')+1); /* name of queue */ + p = skip_string(p,1); + SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */ + SSVAL(p,2,1000); /* size of bytes of returned data buffer */ + p += 4; + strcpy(p,""); /* subformat */ + p = skip_string(p,1); + + DEBUG(1,("Calling DosPrintJobEnum()...\n")); + if( call_api(PTR_DIFF(p,param), 0, + 10, 4096, + &rprcnt, &rdrcnt, + param, NULL, + &rparam, &rdata) ) + { + int converter; + result_code = SVAL(rparam,0); + converter = SVAL(rparam,2); /* conversion factor */ + + DEBUG(2,("returned %d bytes of parameters, %d bytes of data, %d records\n", rprcnt, rdrcnt, SVAL(rparam,4) )); + + if (result_code == 0) /* if no error, */ + { + int i; + uint16 JobId; + uint16 Priority; + uint32 Size; + char *UserName; + char *JobName; + char *JobTimeStr; + time_t JobTime; + char PrinterName[20]; + + strcpy(PrinterName,strrchr(service,'\\')+1); /* name of queue */ + strlower(PrinterName); /* in lower case */ + + p = rdata; /* received data */ + for( i = 0; i < SVAL(rparam,4); ++i) + { + JobId = SVAL(p,0); + Priority = SVAL(p,2); + UserName = fix_char_ptr(SVAL(p,4), converter, rdata, rdrcnt); + strlower(UserName); + Priority = SVAL(p,2); + JobTime = make_unix_date3( p + 12); + JobTimeStr = asctime(LocalTime( &JobTime)); + Size = IVAL(p,16); + JobName = fix_char_ptr(SVAL(p,24), converter, rdata, rdrcnt); + + + printf("%s-%u %s priority %u %s %s %u bytes\n", + PrinterName, JobId, UserName, + Priority, JobTimeStr, JobName, Size); + +#if 0 /* DEBUG code */ + printf("Job Id: \"%u\"\n", SVAL(p,0)); + printf("Priority: \"%u\"\n", SVAL(p,2)); + + printf("User Name: \"%s\"\n", fix_char_ptr(SVAL(p,4), converter, rdata, rdrcnt) ); + printf("Position: \"%u\"\n", SVAL(p,8)); + printf("Status: \"%u\"\n", SVAL(p,10)); + + JobTime = make_unix_date3( p + 12); + printf("Submitted: \"%s\"\n", asctime(LocalTime(&JobTime))); + printf("date: \"%u\"\n", SVAL(p,12)); + + printf("Size: \"%u\"\n", SVAL(p,16)); + printf("Comment: \"%s\"\n", fix_char_ptr(SVAL(p,20), converter, rdata, rdrcnt) ); + printf("Document: \"%s\"\n", fix_char_ptr(SVAL(p,24), converter, rdata, rdrcnt) ); +#endif /* DEBUG CODE */ + p += 28; + } + } + } + else /* call_api() failed */ + { + printf("Failed, error = %d\n", result_code); + } + + /* If any parameters or data were returned, free the storage. */ + if(rparam) free(rparam); + if(rdata) free(rdata); + + return; +} + +/**************************************************************************** +show information about a print queue +****************************************************************************/ static void cmd_qinfo(char *inbuf,char *outbuf ) { char *rparam = NULL; @@ -3870,6 +3984,7 @@ struct {"md",cmd_mkdir,"<directory> make a directory"}, {"rmdir",cmd_rmdir,"<directory> remove a directory"}, {"rd",cmd_rmdir,"<directory> remove a directory"}, + {"pq",cmd_p_queue_4,"enumerate the print queue"}, {"prompt",cmd_prompt,"toggle prompting for filenames for mget and mput"}, {"recurse",cmd_recurse,"toggle directory recursion for mget and mput"}, {"translate",cmd_translate,"toggle text translation for printing"}, diff --git a/source/include/smb.h b/source/include/smb.h index 2dc2624566f..ddbd05792df 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -912,4 +912,7 @@ enum case_handling {CASE_LOWER,CASE_UPPER}; /* Default client code page - 850 - Western European */ #define DEFAULT_CLIENT_CODE_PAGE 850 +/* Size of buffer to use when moving files across filesystems. */ +#define COPYBUF_SIZE (8*1024) + /* _SMB_H */ diff --git a/source/lib/system.c b/source/lib/system.c index 521f5e304ce..ea86e9ccaab 100644 --- a/source/lib/system.c +++ b/source/lib/system.c @@ -197,15 +197,130 @@ int sys_utime(char *fname,struct utimbuf *times) return(utime(dos_to_unix(fname,False),times)); } +/********************************************************* +for rename across filesystems Patch from Warren Birnbaum +<warrenb@hpcvscdp.cv.hp.com> +**********************************************************/ + +static int +copy_reg (const char *source, const char *dest) +{ + struct stat source_stats; + int ifd; + int full_write(); + int safe_read(); + int ofd; + char *buf; + int len; /* Number of bytes read into `buf'. */ + + lstat (source, &source_stats); + if (!S_ISREG (source_stats.st_mode)) + { + return 1; + } + + if (unlink (dest) && errno != ENOENT) + { + return 1; + } + + if((ifd = open (source, O_RDONLY, 0)) < 0) + { + return 1; + } + if((ofd = open (dest, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0 ) + { + close (ifd); + return 1; + } + + if((buf = malloc( COPYBUF_SIZE )) == NULL) + { + close (ifd); + close (ofd); + unlink (dest); + return 1; + } + + while ((len = read(ifd, buf, COPYBUF_SIZE)) > 0) + { + if (write_data(ofd, buf, len) < 0) + { + close (ifd); + close (ofd); + unlink (dest); + free(buf); + return 1; + } + } + free(buf); + if (len < 0) + { + close (ifd); + close (ofd); + unlink (dest); + return 1; + } + + if (close (ifd) < 0) + { + close (ofd); + return 1; + } + if (close (ofd) < 0) + { + return 1; + } + + /* chown turns off set[ug]id bits for non-root, + so do the chmod last. */ + + /* Try to copy the old file's modtime and access time. */ + { + struct utimbuf tv; + + tv.actime = source_stats.st_atime; + tv.modtime = source_stats.st_mtime; + if (utime (dest, &tv)) + { + return 1; + } + } + + /* Try to preserve ownership. For non-root it might fail, but that's ok. + But root probably wants to know, e.g. if NFS disallows it. */ + if (chown (dest, source_stats.st_uid, source_stats.st_gid) + && (errno != EPERM)) + { + return 1; + } + + if (chmod (dest, source_stats.st_mode & 07777)) + { + return 1; + } + unlink (source); + return 0; +} + /******************************************************************* for rename() ********************************************************************/ int sys_rename(char *from, char *to) { + int rcode; pstring zfrom, zto; + strcpy (zfrom, dos_to_unix (from, False)); strcpy (zto, dos_to_unix (to, False)); - return rename (zfrom, zto); + rcode = rename (zfrom, zto); + + if (errno == EXDEV) + { + /* Rename across filesystems needed. */ + rcode = copy_reg (zfrom, zto); + } + return rcode; } /******************************************************************* diff --git a/source/lib/util.c b/source/lib/util.c index def84bf5ae0..9ebfdca88ea 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -3306,7 +3306,7 @@ BOOL process_exists(int pid) fstring s; if (!tested) { tested = True; - sprintf(s,"/proc/%05d",getpid()); + sprintf(s,"/proc/%05d",(int)getpid()); ok = file_exist(s,NULL); } if (ok) { diff --git a/source/locking/locking.c b/source/locking/locking.c index 2c392e924d2..64dc207cb7d 100644 --- a/source/locking/locking.c +++ b/source/locking/locking.c @@ -893,7 +893,8 @@ it left a share mode entry with mode 0x%X in share file %s\n", DEBUG(0,("get_share_modes: share file %s had no valid entries - deleting it !\n", fname)); if(*old_shares) - free((char *)old_shares); + free((char *)*old_shares); + *old_shares = 0; if(buf) free(buf); delete_share_file(cnum, fname); @@ -910,7 +911,8 @@ it left a share mode entry with mode 0x%X in share file %s\n", DEBUG(0,("ERROR: get_share_modes: lseek failed to reset to \ position 0 for share mode file %s (%s)\n", fname, strerror(errno))); if(*old_shares) - free((char *)old_shares); + free((char *)*old_shares); + *old_shares = 0; if(buf) free(buf); return 0; @@ -933,7 +935,8 @@ position 0 for share mode file %s (%s)\n", fname, strerror(errno))); DEBUG(0,("ERROR: get_share_modes: failed to re-write share \ mode file %s (%s)\n", fname, strerror(errno))); if(*old_shares) - free((char *)old_shares); + free((char *)*old_shares); + *old_shares = 0; if(buf) free(buf); return 0; @@ -944,7 +947,8 @@ mode file %s (%s)\n", fname, strerror(errno))); DEBUG(0,("ERROR: get_share_modes: failed to ftruncate share \ mode file %s to size %d (%s)\n", fname, newsize, strerror(errno))); if(*old_shares) - free((char *)old_shares); + free((char *)*old_shares); + *old_shares = 0; if(buf) free(buf); return 0; diff --git a/source/nameannounce.c b/source/nameannounce.c index 899fcd7e3b5..6e7e445e4b1 100644 --- a/source/nameannounce.c +++ b/source/nameannounce.c @@ -165,7 +165,7 @@ void do_announce_host(int command, CVAL(p,21) = MAJOR_VERSION; /* major version */ CVAL(p,22) = MINOR_VERSION; /* minor version */ - SIVAL(p,23,server_type); + SIVAL(p,23,server_type & ~SV_TYPE_LOCAL_LIST_ONLY); /* browse version: got from NT/AS 4.00 - Value defined in smb.h (JHT)*/ SSVAL(p,27,BROWSER_ELECTION_VERSION); SSVAL(p,29,BROWSER_CONSTANT); /* browse signature */ diff --git a/source/namedbserver.c b/source/namedbserver.c index 8cad8a3a112..9223cb6ce6a 100644 --- a/source/namedbserver.c +++ b/source/namedbserver.c @@ -162,16 +162,6 @@ struct server_record *add_server_entry(struct subnet_record *d, } - if (strequal(myworkgroup,work->work_group)) - { - if (servertype) - servertype |= SV_TYPE_LOCAL_LIST_ONLY; - } - else - { - servertype &= ~SV_TYPE_LOCAL_LIST_ONLY; - } - /* update the entry */ StrnCpy(s->serv.name,name,sizeof(s->serv.name)-1); StrnCpy(s->serv.comment,comment,sizeof(s->serv.comment)-1); diff --git a/source/nameelect.c b/source/nameelect.c index cc1c2bc002e..2b4ebf091cc 100644 --- a/source/nameelect.c +++ b/source/nameelect.c @@ -345,7 +345,8 @@ void become_local_master(struct subnet_record *d, struct work_record *work) /* update our server status */ work->ServerType &= ~SV_TYPE_POTENTIAL_BROWSER; - add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True); + add_server_entry(d,work,myname,work->ServerType|SV_TYPE_LOCAL_LIST_ONLY, + 0,lp_serverstring(),True); /* add special browser name */ add_my_name_entry(d,MSBROWSE,0x01,nb_type|NB_ACTIVE|NB_GROUP,False); @@ -360,7 +361,8 @@ void become_local_master(struct subnet_record *d, struct work_record *work) work->mst_state = MST_MSB; /* registering MSBROWSE was successful */ /* add server entry on successful registration of MSBROWSE */ - add_server_entry(d,work,work->work_group,domain_type,0,myname,True); + add_server_entry(d,work,work->work_group,domain_type|SV_TYPE_LOCAL_LIST_ONLY, + 0,myname,True); /* add master name */ add_my_name_entry(d,work->work_group,0x1d,nb_type|NB_ACTIVE,False); @@ -384,7 +386,8 @@ on subnet %s\n", work->work_group, inet_ntoa(d->bcast_ip))); DEBUG(3,("become_local_master: updating our server %s to type %x\n", myname, work->ServerType)); - add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True); + add_server_entry(d,work,myname,work->ServerType|SV_TYPE_LOCAL_LIST_ONLY, + 0,lp_serverstring(),True); /* Count the number of servers we have on our list. If it's less than 10 (just a heuristic) request the servers @@ -493,8 +496,8 @@ void become_domain_master(struct subnet_record *d, struct work_record *work) /* update our server status */ work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MASTER; - add_server_entry(d,work,myname,work->ServerType,0, - lp_serverstring(),True); + add_server_entry(d,work,myname,work->ServerType|SV_TYPE_LOCAL_LIST_ONLY, + 0, lp_serverstring(),True); DEBUG(0,("Samba is now a domain master browser for workgroup %s on subnet %s\n", work->work_group, inet_ntoa(d->bcast_ip))); @@ -549,8 +552,8 @@ void become_logon_server(struct subnet_record *d, struct work_record *work) /* update our server status */ work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MEMBER; - add_server_entry(d,work,myname,work->ServerType,0, - lp_serverstring(),True); + add_server_entry(d,work,myname,work->ServerType|SV_TYPE_LOCAL_LIST_ONLY + ,0, lp_serverstring(),True); /* DON'T do anything else after calling add_my_name_entry() */ break; diff --git a/source/namework.c b/source/namework.c index 23d48d9ced7..ff623e69dbf 100644 --- a/source/namework.c +++ b/source/namework.c @@ -255,7 +255,7 @@ static void process_localnet_announce(struct packet_struct *p,uint16 command,cha ttl = GET_TTL(ttl); /* add them to our browse list, and update the browse.dat file */ - add_server_entry(d,work,name,servertype,ttl,comment,True); + add_server_entry(d,work,name,servertype|SV_TYPE_LOCAL_LIST_ONLY,ttl,comment,True); updatedlists = True; #if 0 diff --git a/source/nmbsync.c b/source/nmbsync.c index 7f5d608998a..97e7e02b2b9 100644 --- a/source/nmbsync.c +++ b/source/nmbsync.c @@ -99,7 +99,7 @@ static BOOL add_info(struct subnet_record *d, struct work_record *work, int serv for (i = 0;i < count;i++, p += 26) { char *sname = p; - uint32 stype = IVAL(p,18); + uint32 stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; int comment_offset = IVAL(p,22) & 0xFFFF; char *cmnt = comment_offset?(rdata+comment_offset-converter):""; @@ -157,7 +157,7 @@ void sync_browse_lists(struct subnet_record *d, struct work_record *work, got_pass = True; DEBUG(0,("sync_browse_lists: Sync browse lists with %s for %s %s\n", - work->work_group, name, inet_ntoa(ip))); + name, work->work_group, inet_ntoa(ip))); strcpy(workgroup,work->work_group); strcpy(desthost,name); diff --git a/source/param/loadparm.c b/source/param/loadparm.c index 8c2dd2776cc..9d3850b2428 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -298,7 +298,7 @@ static service sDefault = NULL, /* volume */ 0, /* iMinPrintSpace */ 0644, /* iCreate_mode */ - 0700, /* iCreate_force_mode */ + 0000, /* iCreate_force_mode */ 0755, /* iDir_mode */ 0000, /* iDir_force_mode */ 0, /* iMaxConnections */ @@ -598,7 +598,7 @@ static void init_globals(void) Globals.max_packet = 65535; Globals.mangled_stack = 50; Globals.max_xmit = 65535; - Globals.max_mux = 2; + Globals.max_mux = 50; /* This is *needed* for profile support. */ Globals.lpqcachetime = 10; Globals.pwordlevel = 0; Globals.deadtime = 0; diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c index 6b3953e6c86..7922e416236 100644 --- a/source/smbd/ipc.c +++ b/source/smbd/ipc.c @@ -770,6 +770,7 @@ static int get_server_info(uint32 servertype, int count=0; int alloced=0; pstring line; + BOOL local_list_only; strcpy(fname,lp_lockdir()); trim_string(fname,NULL,"/"); @@ -784,7 +785,10 @@ static int get_server_info(uint32 servertype, } /* request for everything is code for request all servers */ - if (servertype == SV_TYPE_ALL) servertype &= ~SV_TYPE_DOMAIN_ENUM; + if (servertype == SV_TYPE_ALL) + servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY); + + local_list_only = (servertype & SV_TYPE_LOCAL_LIST_ONLY); DEBUG(4,("Servertype search: %8x\n",servertype)); @@ -821,6 +825,14 @@ static int get_server_info(uint32 servertype, ok = False; } + /* Filter the servers/domains we return based on what was asked for. */ + + /* Check to see if we are being asked for a local list only. */ + if(local_list_only && ((s->type & SV_TYPE_LOCAL_LIST_ONLY) == 0)) { + DEBUG(4,("r: local list only")); + ok = False; + } + /* doesn't match up: don't want it */ if (!(servertype & s->type)) { DEBUG(4,("r:serv type ")); @@ -839,6 +851,9 @@ static int get_server_info(uint32 servertype, ok = False; } + /* We should never return a server type with a SV_TYPE_LOCAL_LIST_ONLY set. */ + s->type &= ~SV_TYPE_LOCAL_LIST_ONLY; + if (ok) { DEBUG(4,("**SV** %20s %8x %25s %15s\n", diff --git a/source/smbd/server.c b/source/smbd/server.c index 203bdb8da89..8c40734ce42 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -603,6 +603,14 @@ static void disk_norm(int *bsize,int *dfree,int *dsize) int disk_free(char *path,int *bsize,int *dfree,int *dsize) { char *df_command = lp_dfree_command(); + int dfree_retval; +#ifdef QUOTAS + int dfreeq_retval; + int dfreeq = 0; + int bsizeq = *bsize; + int dsizeq = *dsize; +#endif + #ifndef NO_STATFS #ifdef USE_STATVFS struct statvfs fs; @@ -615,15 +623,6 @@ int disk_free(char *path,int *bsize,int *dfree,int *dsize) #endif #endif -#ifdef QUOTAS - if (disk_quotas(path, bsize, dfree, dsize)) - { - disk_norm(bsize,dfree,dsize); - return(((*bsize)/1024)*(*dfree)); - } -#endif - - /* possibly use system() to get the result */ if (df_command && *df_command) { @@ -639,22 +638,42 @@ int disk_free(char *path,int *bsize,int *dfree,int *dsize) DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); { - FILE *f = fopen(outfile,"r"); - *dsize = 0; - *dfree = 0; - *bsize = 1024; - if (f) - { - fscanf(f,"%d %d %d",dsize,dfree,bsize); - fclose(f); - } - else - DEBUG(0,("Can't open %s\n",outfile)); + FILE *f = fopen(outfile,"r"); + *dsize = 0; + *dfree = 0; + *bsize = 1024; + if (f) + { + fscanf(f,"%d %d %d",dsize,dfree,bsize); + fclose(f); + } + else + DEBUG(0,("Can't open %s\n",outfile)); } unlink(outfile); disk_norm(bsize,dfree,dsize); - return(((*bsize)/1024)*(*dfree)); + dfree_retval = ((*bsize)/1024)*(*dfree); +#ifdef QUOTAS + /* Ensure we return the min value between the users quota and + what's free on the disk. Thanks to Albrecht Gebhardt + <albrecht.gebhardt@uni-klu.ac.at> for this fix. + */ + if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq)) + { + disk_norm(&bsizeq, &dfreeq, &dsizeq); + dfreeq_retval = ((bsizeq)/1024)*(dfreeq); + dfree_retval = ( dfree_retval < dfreeq_retval ) ? + dfree_retval : dfreeq_retval ; + /* maybe dfree and dfreeq are calculated using different bsizes + so convert dfree from bsize into bsizeq */ + *dfree = ((*dfree) * (*bsize)) / (bsizeq); + *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ; + *bsize = bsizeq; + *dsize = dsizeq; + } +#endif + return(dfree_retval); } #ifdef NO_STATFS @@ -724,7 +743,27 @@ if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024; *dsize = 20*1024*1024/(*bsize); *dfree = MAX(1,*dfree); } - return(((*bsize)/1024)*(*dfree)); + dfree_retval = ((*bsize)/1024)*(*dfree); +#ifdef QUOTAS + /* Ensure we return the min value between the users quota and + what's free on the disk. Thanks to Albrecht Gebhardt + <albrecht.gebhardt@uni-klu.ac.at> for this fix. + */ + if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq)) + { + disk_norm(&bsizeq, &dfreeq, &dsizeq); + dfreeq_retval = ((bsizeq)/1024)*(dfreeq); + dfree_retval = ( dfree_retval < dfreeq_retval ) ? + dfree_retval : dfreeq_retval ; + /* maybe dfree and dfreeq are calculated using different bsizes + so convert dfree from bsize into bsizeq */ + *dfree = ((*dfree) * (*bsize)) / (bsizeq); + *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ; + *bsize = bsizeq; + *dsize = dsizeq; + } +#endif + return(dfree_retval); #endif } |